www.eprace.edu.pl » rejestrowanie-multimediow » Program komputerowy obsługujący rejestrator » Implementacja zasadniczych funkcji programu

Implementacja zasadniczych funkcji programu

Organizacja programu – dwa wątki

Podstawowym zadaniem programu jest odbieranie ramek sterujących i głosowych, oraz tworzenie w reakcji na nie plików dźwiękowych z zapisem rozmów. Aby czynności te wykonywane były cały czas, nie blokując funkcjonowania okna dialogowego, program wykonywany jest w dwóch wątkach. Wątek główny, rozpoczynany w pierwszej kolejności, odpowiedzialny jest za interfejs użytkownika, za przygotowanie ramek z parametrami AGC po zmianie tych parametrów przez użytkownika i za ładowanie programu dla procesora sygnałowego. Wątek ten wywołuje funkcje klasy CRejRozmow2Dlg. Drugi wątek, obsługiwany przez funkcję globalną writeWave, odbiera i interpretuje ramki sterujące i głosowe, wysyła potwierdzenia i zapisuje rozmowy w plikach WAV. Wątek ten jest uruchamiany w funkcji OnInitDialog klasy CRejRozmow2Dlg.

Obsługa sieci

Do obsługi transmisji w sieci z protokołem UDP została wykorzystana klasa CAsyncSocket z biblioteki MFC. W programie tworzony jest jeden globalny obiekt tej klasy o nazwie socket1, który obsługuje wszelką komunikację sieciową z rejestra­torem.

Czynności inicjalizujące wymagane przed korzystaniem z klasy CAsyncSocket zostały zawarte w funkcji CRejRozmow2Dlg::OnInitDialog. Najważniejszą z nich jest otwarcie gniazda socket1 w trybie UDP, przy czym system operacyjny sam wybiera wolny port po stronie komputera.

Do nadawania i odbioru danych przez sieć wykorzystywane są odpowiednio funkcje SendTo i ReceiveFrom, wywoływane dla obiektu socket1.

Ładowanie programu dla procesora DSP

Za przesłanie programu dsp.asm do rejestratora odpowiedzialna jest funkcja CRejRozmow2Dlg::OnBnClickedBootBtn, wywoływana po wciśnięciu przycisku „Boot”. Funkcja ta korzysta z pliku bootdata.bin, zawierającego program, który ma być przesłany, wraz z 6-bajtowym nagłówkiem omówionym w podrozdziale 7.5.

Pierwszą czynnością wykonywaną przez funkcję OnBnClickedBootBtn jest odebranie wszystkich datagramów, które zostały wcześniej wysłane do komputera na port używany do komunikacji z rejestratorem. Datagramy te są ignorowane. Zapobiega to potraktowaniu pozostałości z ewentualnych wcześniejszych transmisji jako odpowiedź rejestratora na wysyłanie programu.

Następnie program wysyła dane z pliku bootdata.bin w pakietach po 256 bajtów, po każdym oczekując na 1-bajtowe potwierdzenie. Jeżeli któreś potwierdzenie nie przyjdzie w ciągu przewidzianego czasu, procedura jest przerywana i wyświetlany jest komunikat o błędzie. Jeżeli wszystkie pakiety danych zostaną potwierdzone, ustawiany jest znacznik booted, dzięki czemu wątek rejestracji rozmów zostanie uaktywniony. Numer sekwencyjny ostatnio odebranej ramki sterującej (zmienna seqCtl) ustawiany jest na wartość 255, co spowoduje zaakceptowanie przychodzącej ramki o numerze 0, zgodnie z regułami opisanymi w podrozdziale 7.4.2. Ustawiany jest również znacznik chnsCloseReq, co spowoduje, że wątek rejestracji zamknie wszystkie kanały, które były otwarte. Ma to znaczenie tylko w sytuacji, gdy program wcześniej współpracował z rejestratorem i nie został zamknięty przed ponownym użyciem przycisku „Boot”.

Po załadowaniu programu następuje przesłanie do rejestratora parametrów algorytmu AGC dla wszystkich kanałów za pomocą wielokrotnego wywołania funkcji setAGCPar. Na koniec funkcji obsługującej przycisk „Boot” wyświetlone zostaje okienko z informacją o poprawnym załadowaniu programu do rejestratora.

Wątek obsługujący rejestrację rozmów

Wątek rejestrujący rozmowy obsługiwany jest przez funkcję globalną writeWave. Funkcja ta pracuje przez cały czas aktywności programu, jednak wykonuje ona istotne czynności tylko wtedy, gdy ustawiony jest znacznik booted (zmienna globalna). Zapobiega to kolizji tego wątku z procedurą ładowania programu do procesora.


Rys. 8.3. Schemat blokowy czynności wykonywanych w wątku rejestracji


Działania wykonywane w wątku rejestracji zostały zobrazowane ogólnie na rysunku 8.3, a bardziej złożone procedury pokazane są szczegółowo na rysunkach 8.4, 8.5 i 8.6.

Rys. 8.4. Schemat blokowy procedury przetwarzania odebranej ramki


Rys. 8.5. Schemat blokowy procedury obsługi ramki sterującej

Rys. 8.6. Schemat blokowy procedury wysyłania ramki parametrów AGC

Występujące wielokrotnie na diagramach zamknięcie kanału polega na wykonaniu następujących czynności:

Pierwsze trzy z powyższych czynności wykonywane są przez wywołanie funkcji CloseChn.

Ustawianie parametrów AGC polega na wysłaniu ramki z bufora agcParBuffer, którego zawartość przygotowuje funkcja setAGCPar. Funkcja ta tworzy w buforze ramkę AGC korzystając z parametrów zapisanych w zmiennych tablicowych agcOn, vadOn, htOn, minGain, maxGain, startGain, attThr, attTC, decTC, holdTime. Zmienne te ustawiane są na wartości początkowe przez funkcję InitializeAGCParams, a w trakcie działania programu modyfikowane przez funkcje obsługujące suwaki w oknie interfejsu użytkownika. Licznik powtórzeń agcParRptCnt wraz z licznikiem czasu oczekiwania agcParTimer pozwalają zapobiec wysyłaniu parametrów AGC kilkakrotnie podczas poruszania suwakiem oraz zrealizować powtórzenie ramki w celu zapewnienia niezawodności transmisji.

Aby zamknięcie programu przez użytkownika powodowało nie tylko zakończenie wątku głównego, ale także wątku rejestracji, wprowadzono znacznik finishReq. Gdy użytkownik wciśnie ikonę zamykania programu, znacznik ten jest ustawiany przez wątek główny na wartość true. W reakcji na to wątek rejestracji zamyka wszystkie kanały, odpowiada ustawieniem znacznika finishOK i kończy się.



komentarze

Copyright © 2008-2010 EPrace oraz autorzy prac.