Generator funkcyjny z karty dźwiękowej

Generator funkcyjny z karty dźwiękowej
Pobierz PDF Download icon
Generator funkcji jest podstawowym narzędziem elektronika konstruktora. Jednak fabryczne generatory są drogie i nie każdy może sobie pozwolić na taki luksus. Alternatywnym rozwiązaniem jest generator software\'owy, czyli program komputerowy sterujący kartą dźwiękową. Koszt tego rozwiązania żaden, a program może być w wielu przypadkach użyteczny.
64 ELEKTRONIKA PRAKTYCZNA 7/2010 Notatnik konstruktora Podstawowe informacje: ? Zakres częstotliwości wyjściowej: 1  Hz...20  kHz (sinus). ? Rozdzielczość ustawiania częstotliwości: 0,1  Hz. ? Maksymalna amplituda napięcia wyjściowego: zależna od karty dźwiękowej. ? Generowanie przebiegów o  kształtach: sinusoidalnym, trójkątnym, prostokątnym. W opisanym generatorze wykorzystuje się przetworniki C/A  na karcie dźwiękowej z częstotliwością próbkowania 96  kHz lub 44,2 kHz na kartach starszego typu. Sygnał jest pobierany z  wyjść karty dźwiękowej, które są najczęściej typu jack. Oczywiście, jak widać z samej zasady działania, genera- tor taki ma gorsze parametry niż generator sprzętowy. Generatory pozwalają uzyskać częstotliwości sygnału wyjściowego powy- żej 1 MHz, a ten jedynie kilkadziesiąt kilo- herców i to tylko dla sinusoidy. Do badania urządzeń akustycznych to jednak w  zupeł- ności wystarczy, a  z  powodu niskiej ceny nasz generator może być konkurencyjny w stosunku do firmowych. Inną zaletą jest to, że przy niskich częstotliwościach możemy uzyskać bardzo małe zniekształcenia. Sygnał odwzorowany jest z rodzielczością 16 bitów, czyli 65536 poziomów napięć. Dodatkowym mankamentem kart dźwiękowych jest to, że na sygnał wyjściowy nakładają się zakłóce- nia elektromagnetyczne wytwarzane przez płytę główną komputera oraz to, że wyjście jest separowane kondensatorem sprzęgają- cym o niewielkiej pojemności, co ogranicza pasmo od dołu. Zasada działania Do bufora o odpowiedniej długości wpi- sywane są kolejne wartości chwilowe am- Generator funkcyjny z karty dźwiękowej Generator funkcji jest podstawowym narzędziem elektronika konstruktora. Jednak fabryczne generatory są drogie i  nie każdy może sobie pozwolić na taki luksus. Alternatywnym rozwiązaniem jest generator software?owy, czyli program komputerowy sterujący kartą dźwiękową. Koszt tego rozwiązania żaden, a  program może być w  wielu przypadkach użyteczny. plitudy sygnału generowanego. Następnie bufor jest cyklicznie odczytywany przez pro- gram obsługi urządzeń typu ?Wave?, a zapi- sane w nim wartości są kolejno podawane na wyjście przetwornika C/A karty dźwiękowej. Szybkość odczytu z bufora jest stała i równa maksymalnej częstotliwości próbkowania dla danej karty. Z  tego powodu o  częstot- liwości wytwarzanego przebiegu decyduje rozłożenie danych w buforze. Należy również zauważyć, że dane po- winny być tak rozłożone, aby mieściły na ca- łej długości bufora całkowitą liczbą okresów. Wynika to z faktu, że gdy licznik procedury odczytującej dojdzie do końca bufora, zostaje wyzerowany i  odczytywanie zaczyna się od początku. Gdybyśmy nie zachowali ciągłości sygnału, wystąpiłby silny impuls zakłócający przy przejściu licznika do początku bufora. Należy zauważyć pewną prawidłowość. Częstotliwość sygnału wyjściowego jest pro- porcjonalna do liczby okresów zawartych w buforze oraz zależy od czasu odczytu całe- go bufora. Można to wyrazić wzorem: gdzie: ? N: liczba okresów w całym buforze, ? Tbuf : czas odczytu całego bufora. W naszym przypadku chcemy, aby czę- stotliwość ustawiana była z rozdzielczością 0,1  Hz, więc długość bufora ustalamy tak, aby całkowity czas odczytu wynosił 10  s. Można to wyrazić za pomocą następującego wzoru: gdzie: ? fp : częstotliwość próbkowania. ? Tbuf : czas odczytu całego bufora. ? kanały: liczba kanałów. ? bajty: liczba bajtów na próbkę. W  naszym przypadku fp =96  kHz, Tbuf =10  s, kanały=2 (stereo), bajty=2 (16 bitów). Dane są zapisywane w posta- ci liczby całkowitej ze znakiem w notacji U2, czyli odpowiadają typowi short języ- ka C++. Opisane wyżej zależności pokazano gra- ficznie na rysunku 1 i rysunku 2. Interfejs użytkownika Interfejs użytkownika napisano w  po- staci okna dialogowego o  stałej wielkości. Można w  nim wydzielić dwie podstawo- we sekcje: ustawiania częstotliwości oraz ustawiania amplitudy. Parametry te można zmieniać za pomocą suwaków lub wpisując odpowiednie wartości w pola tekstowe. Do zmiany zakresów służą przyciski typu ?Ra- dio button? i odpowiednio dla częstotliwo- ści są to: Rysunek 1. Związek między rozmieszczeniem danych w buforze a częstotliwością 65ELEKTRONIKA PRAKTYCZNA 7/2010 Generator funkcyjny z karty dźwiękowej nych oraz uruchomieniu odpowiedniej pro- cedury odtwarzającej. Ważniejsze fragmenty programu realizującego generator funkcyjny umieszczono na listingu 1, którego dokładne przestudiowanie pozwoli zrozumieć sposób działania programu. Dokładniejszy opis funkcji ?Wave Audio? można znaleźć na stronie: http://msdn.microsoft. com/en-us/library w  sekcji: ?Win32 and COM Development/Audio and Video/Windows Multi- media/Multimedia Audio/Waveform Audio. Program napisano jako zwykłą aplika- cję Win32, niewykorzystującą żadnych roz- szerzeń ani dodatkowych bibliotek. Projekt został skompilowany z  użyciem Microsoft- Visual C++ ver.6.0, ale można go zaimporto- wać do nowszych wersji. Tomasz Krogulski tomaszkro@op.pl Ponadto, przyciskami w  sekcji ustawia- nia kształtu możemy zmieniać kształt gene- rowanego sygnału. Do wyboru są opcje po- dobne jak w  typowym generatorze funkcji, czyli: sinus, trójkąt, prostokąt. W przypadku gdy w komputerze mamy więcej niż jedno urządzenie typu ?Wave Au- dio?, możemy je wybrać za pomocą kontrolki typu ?Combo box?. Po przyciśnięciu przycisku ?Parametry? wyświetlane są parametry bieżącej (wybra- nej) karty dźwiękowej, natomiast wybranie przycisku ?Informacja? powoduje wyświe- tlenie podstawowych informacji na temat programu. Procedura generująca dźwięk Działanie tej procedury w zasadzie pole- ga na odpowiednim wypełnieniu bufora da- ? 100  Hz: umożliwia uzyskanie częstotli- wości do 100 Hz, ? 1 kHz: umożliwia uzyskanie częstotliwo- ści do 1 kHz, ? 20  kHz: umożliwia uzyskanie częstotli- wości do 20 kHz. Dla amplitudy są to: ? 1:1: maksymalna amplituda równa mak- symalnemu napięciu wyjściowemu karty dźwiękowej, ? 1:10: maksymalna amplituda równa 10% maksymalnego napięcia wyjściowego karty dźwiękowej, ? 1:100 maksymalna amplituda równa 1% maksymalnego napięcia wyjściowego karty dźwiękowej. Przy wpisaniu do pola tekstowego odpo- wiedniej wartości położenia suwaków oraz przy- ciski zakresów są aktualizowane automatycznie. Rysunek 2. Rozmieszczenie danych w buforze Listing 1. Ważniejsze fragmenty programu generatora funkcyjnego //zmienne globalne: char FU_Buffer[96000*4*10]; bufor odtwarzanych danych; HWAVEOUT FU_Hw = NULL; handler urządzenia ?Wave Audio?; WAVEFORMATEX FU_Wf; struktura parametrów przetwarzania; WAVEHDR FU_Hdr; nagłówek bufora; /*parametry: freq - częstotliwość*10; amp - amplituda (0-100000); shape - kształt: 0 - sinus, 1 - trójkąt, 2 - prostokąt; idx - indeks urządzenia ; chn ? liczba kanałów; fsample - częstotliwość próbkowania; */ void StartWave(int freq, int amp, int shape, int idx, int chn, int fsample) { if(FU_Hw) // Zamknięcie urządzenia ?Wave Audio?, jeśli jest otwarte { waveOutReset(FU_Hw); waveOutUnprepareHeader(FU_Hw, &FU_Hdr, sizeof(FU_Hdr)); waveOutClose(FU_Hw); } FU_Wf.nChannels = chn; // wypełnienie struktury FU_Wf.nSamplesPerSec = fsample; // parametrów przetwarzania FU_Wf.wBitsPerSample = 16; // która jest następnie przekazana FU_Wf.nAvgBytesPerSec = fsample*4; // do funkcji ?waveOutOpen? FU_Wf.wFormatTag = WAVE_FORMAT_PCM; FU_Wf.nBlockAlign = 4; FU_Wf.cbSize = 0; // otwarcie urządzenia ?Wave Audio? MMRESULT re1 = waveOutOpen(&FU_Hw, idx, &FU_Wf, NULL, NULL, CALLBACK_NULL); // wypełninie struktury nagłówka w której zawarty jest sposób // odtwarzania dźwięku (sygnału) FU_Hdr.dwBufferLength = fsample*chn*2*10; // długość bufora FU_Hdr.lpData = FU_Buffer; // adres bufora 66 ELEKTRONIKA PRAKTYCZNA 7/2010 Notatnik konstruktora Listing 1. cd. FU_Hdr.dwLoops = 0xFFFFFFFF; // liczba powtórzeń odczytu (całego // bufora) wpisałem maksymalną wartość, co w praktyce oznacza // nieskończoną liczbę powtórzeń FU_Hdr.dwFlags = WHDR_BEGINLOOP|WHDR_ENDLOOP; // Nagłówek jest pierwszym i zarazem ostatnim w pętli odtwarzania. union { char *cpt; short *wpt; short (*lpt)[2]; } pt; int i; pt.cpt = FU_Buffer; for(i=0; i(0.5/freal) ? -32768 : 32767; } if(chn==1) // przepisanie wartości do bufora pt.wpt[i] = val; else { pt.lpt[i][0] = val; pt.lpt[i][1] = val; } } // aby odtworzyć zawartość bufora, należy najpierw utworzyć nagłówek // za pomocą // funkcji ?waveOutPrepareHeader? waveOutPrepareHeader(FU_Hw, &FU_Hdr, sizeof(FU_Hdr)); // ustawianie amplitudy za pomocą funkcji ?waveOutSetVolume? waveOutSetVolume(FU_Hw,(unsigned short)((double)amp/100000.0*65535.0)); // rozpoczęcie odczytu - czyli start generatora waveOutWrite(FU_Hw, &FU_Hdr, sizeof(FU_Hdr)); } // Opis funkcji interfejsu API Windowsów obsługi urządzeń ?Wave // AUDIO? wykorzystywanych w naszej procedurze: // Otwarcie danego urządzenia ?Wave AUDIO? MMRESULT waveOutOpen( LPHWAVEOUT phwo, // zwracany handler dla nowo otwartego urządzenia ?Wave AUDIO? UINT_PTR uDeviceID, // numer urządzenia LPWAVEFORMATEX pwfx, // struktura z parametrami odtwarzania DWORD_PTR dwCallback, // wskaźnik do procedury obsługi odtwarzania DWORD_PTR dwCallbackInstance, // dana przesyłana do procedury obsługi DWORD fdwOpen // flagi - w naszym przypadku 0 ); // Zamknięcie urządzenia ?Wave AUDIO? waveOutClose( LPHWAVEOUT phwo // handler urządzenia ); // Wyłączenie urządzenia (zatrzymanie odtwarzania) waveOutReset( LPHWAVEOUT phwo // handler urządzenia ); 67ELEKTRONIKA PRAKTYCZNA 7/2010 Generator funkcyjny z karty dźwiękowej Listing 1. cd. // Przygotowanie nagłówka - trzeba wywołać przed wywołaniem // ?waveOutWrite? waveOutPrepareHeader( LPHWAVEOUT phwo // handler urządzenia LPWAVEHDR pwh, // przygotowywany nagłówek UINT cbwh // wielkość nagłówka ); // Zwolnienie nagłówka oraz związanego z nim bufora danych // trzeba ją wywołać przed zwolnieniem bufora danych waveOutUnprepareHeader( HWAVEOUT hwo, // handler urządzenia LPWAVEHDR pwh, // przygotowywany nagłówek UINT cbwh // wielkość nagłówka ); // Ustawia poziom głośności waveOutSetVolume( HWAVEOUT hwo, // handler urządzenia DWORD dwVolume // poziom głośności 0-65536 ); // Procedura rozpoczynająca odtwarzanie dźwięku (zapis do kraty // dźwiękowej) waveOutWrite( HWAVEOUT hwo, // handler urządzenia LPWAVEHDR pwh, // wskaźnik do nagłówka UINT cbwh // wielkość nagłówka ); // Opis struktur wykorzystywanych przez powyższe funkcje WAVEFORMATEX // struktura z parametrami odtwarzania Poszczególne pola: WORD wFormatTag; // typ format urządzenia WORD nChannels; // liczba kanałów DWORD nSamplesPerSec; // częstotliwość przetwarzania DWORD nAvgBytesPerSec; // średnia ilość bitów na sekundę = nBlockAlign*nSamplesPerSec WORD nBlockAlign; // liczba bajtów dla jednej próbki - w naszym przypadku 4 WORD wBitsPerSample; // liczba bitów jednej próbki WORD cbSize; // rozmiar dodatkowych danych - w naszym przypadku 0 WAVEHDR // nagłówek danych do odtwarzania Poszczególne pola: LPSTR lpData; // adres bufora DWORD dwBufferLength; // długość bufora DWORD dwBytesRecorded; // liczba odczytanych bajtów DWORD_PTR dwUser; // dane użytkownika DWORD dwFlags; // najważniejsze flagi to: WHDR_BEGINLOOP - pierwszy nagłówek w  // pętli, WHDR_ENDLOOP - ostatni nagłówek; DWORD dwLoops; // liczba powtórzeń pętli struct wavehdr_tag *lpNext; // wskaźnik do następnego nagłówka DWORD_PTR reserved; // zarezerwowane R E K L A M A
Artykuł ukazał się w
Lipiec 2010
DO POBRANIA
Pobierz PDF Download icon
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik czerwiec 2020

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio lipiec 2020

Świat Radio

Magazyn użytkowników eteru

APA - Automatyka Podzespoły Aplikacje czerwiec 2020

APA - Automatyka Podzespoły Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna czerwiec 2020

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Praktyczny Kurs Elektroniki 2018

Praktyczny Kurs Elektroniki

24 pasjonujące projekty elektroniczne

Elektronika dla Wszystkich czerwiec 2020

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów