Thread View: pl.comp.lang.delphi
17 messages
17 total messages
Started by stchebel
Mon, 05 Sep 2016 23:25
Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Mon, 05 Sep 2016 23:25
Date: Mon, 05 Sep 2016 23:25
37 lines
3035 bytes
3035 bytes
Witam, Mam "zgryza" jak to zrobić. Zagadnienie jest następujące: 1) Jest urządzenie, które generuje sygnał w zakresie częstotliwości akustycznych (słyszalnych dla humanoida), czyli od kilkudziesięciu Hz, do kilku KHz. 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB. Dla obeznanych w warunkach czasowych protokołu USB, natychmiast pojawi się problem synchronizacji. To zupełnie inna bajka, załóżmy że tego problemu nie ma. 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-). 4) Z odczytem danych przez USB (układ FT2232H) nie ma problemów. Problem jest z "wyświetleniem" danych na głośniku. 5) Dla uproszczenia zagadnienia/pytania, zróbmy takie coś (sinus 1kHz): t:=0; DeltaT:=10; // 10 ms - Częstotlwość odczytu=próbkowania (takie założenie) f:=1000; // Częstotliwość 1kHz repeat a:=Round(2047*sin(2*pi*f*t/1000)); // dzielimy/1000, bo DeltaT jest w ms WyslijNaKarteDzwiekowa(a); t:=t+DeltaT; sleep(DeltaT); until CosTam; ============= Pytanie/Prośba: Jakich zaklęć użyć w procedure WyslijNaKarteDzwiekowa(a:word); Chyba trzeba wykorzystać jakieś windowsowe API, ale kompletnie się na tym nie znam. Myślałem też o buforowaniu danych w FIFO o pewnej głębokości, natępnie o szybkim odczycie i konwersji na plik np. WMV. Też co prawda nie wiem jak tego dokonać, ale obawiam się, że soft mógłby mieć "czkawkę". Zagadnienie jest typu: [mikrofon/wzmacniacz/ADC]=>[USB]=>[Karta Dźwiękowa/głośnik] . Jak to zrobić? Oczywiście, "gotowiec" najmilej widziany, ale wszelakie wskazówki również. Pzdr., Stachu
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Mon, 05 Sep 2016 23:40
Date: Mon, 05 Sep 2016 23:40
50 lines
3776 bytes
3776 bytes
W dniu wtorek, 6 września 2016 01:25:52 UTC+2 użytkownik stch...@gmail.com napisał: > Witam, > Mam "zgryza" jak to zrobić. Zagadnienie jest następujące: > > 1) Jest urządzenie, które generuje sygnał w zakresie częstotliwości akustycznych (słyszalnych dla humanoida), czyli od kilkudziesięciu Hz, do kilku KHz. > > 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB. > Dla obeznanych w warunkach czasowych protokołu USB, natychmiast pojawi się problem synchronizacji. To zupełnie inna bajka, załóżmy że tego problemu nie ma. > > 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-). > > 4) Z odczytem danych przez USB (układ FT2232H) nie ma problemów. Problem jest z "wyświetleniem" danych na głośniku. > > 5) Dla uproszczenia zagadnienia/pytania, zróbmy takie coś (sinus 1kHz): > > t:=0; > DeltaT:=10; // 10 ms - Częstotlwość odczytu=próbkowania (takie założenie) > f:=1000; // Częstotliwość 1kHz > repeat > a:=Round(2047*sin(2*pi*f*t/1000)); // dzielimy/1000, bo DeltaT jest w ms > WyslijNaKarteDzwiekowa(a); > t:=t+DeltaT; > sleep(DeltaT); > until CosTam; > > ============= > > Pytanie/Prośba: > > Jakich zaklęć użyć w procedure WyslijNaKarteDzwiekowa(a:word); > > Chyba trzeba wykorzystać jakieś windowsowe API, ale kompletnie się na tym nie znam. Myślałem też o buforowaniu danych w FIFO o pewnej głębokości, natępnie o szybkim odczycie i konwersji na plik np. WMV. Też co prawda nie wiem jak tego dokonać, ale obawiam się, że soft mógłby mieć "czkawkę". > > Zagadnienie jest typu: [mikrofon/wzmacniacz/ADC]=>[USB]=>[Karta Dźwiękowa/głośnik] . > > Jak to zrobić? Oczywiście, "gotowiec" najmilej widziany, ale wszelakie wskazówki również. > > Pzdr., Stachu ================== Poprawka : Jest: 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-). Powinno być: 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-) jest z zakresu (-2048,2047).
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: arivald
Date: Tue, 06 Sep 2016 04:35
Date: Tue, 06 Sep 2016 04:35
58 lines
2876 bytes
2876 bytes
W dniu 2016-09-06 o 01:25, stchebel@gmail.com pisze: > Witam, > Mam "zgryza" jak to zrobić. Zagadnienie jest następujące: > > 1) Jest urządzenie, które generuje sygnał w zakresie częstotliwości akustycznych > (słyszalnych dla humanoida), czyli od kilkudziesięciu Hz, do kilku KHz. > > 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością > spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB. > Dla obeznanych w warunkach czasowych protokołu USB, natychmiast pojawi się > problem synchronizacji. To zupełnie inna bajka, załóżmy że tego problemu nie ma. > > 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, > próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe > (Najstarszy bit, to znak +/-). > > 4) Z odczytem danych przez USB (układ FT2232H) nie ma problemów. Problem jes >t z "wyświetleniem" danych na głośniku. > > 5) Dla uproszczenia zagadnienia/pytania, zróbmy takie coś (sinus 1kHz): > > t:=0; > DeltaT:=10; // 10 ms - Częstotlwość odczytu=próbkowania (takie założenie) > f:=1000; // Częstotliwość 1kHz > repeat > a:=Round(2047*sin(2*pi*f*t/1000)); // dzielimy/1000, bo DeltaT jest w ms > WyslijNaKarteDzwiekowa(a); > t:=t+DeltaT; > sleep(DeltaT); > until CosTam; > > ============= > > Pytanie/Prośba: > > Jakich zaklęć użyć w procedure WyslijNaKarteDzwiekowa(a:word); > https://msdn.microsoft.com/en-us/library/windows/desktop/dd743834(v=vs.85).aspx Najpierw waveOutOpen, potem seria waveOutWrite, i na koniec waveOutClose. Generalnie swoje sample zbierasz w buforze (jeden wątek), a w drugim, na callbacku, przekazujesz zebrane fragmenty do odtwarzania. Tu masz podobny przykład: http://4programmers.net/Delphi/Artyku%C5%82y/Odtwarzanie_wave_z_WinAPI Jest też "gotowiec", ale nie wiem jak tego się używa. TLiveAudioPlayer z biblioteki http://www.delphiarea.com/products/delphi-packages/waveaudio/ -- Arivald
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: alex.cianciara
Date: Tue, 06 Sep 2016 10:02
Date: Tue, 06 Sep 2016 10:02
13 lines
2384 bytes
2384 bytes
W dniu wtorek, 6 września 2016 01:25:52 UTC+2 użytkownik stch...@gmail.com napisał: > 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB. [...] > 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-). 8) Oj kolega Nyquist to się w grobie przewraca... 1 kHz to okres 1 ms, czyli wzorem Nyquista max 500 us krok próbkowania. A jak chcesz tak do 20 kHz to 25 us będzie bardziej odpowiednie. Jak chcesz dźwięk lepszej jakości to i 10 us nie będzie za dużo. I teraz pytanie jak oprogramować PCta aby utrzymać równomierny takt 25 us. Napewno nie w takiej pętelce, a już użycie Sleep() to zbrodnia. :) Pozdrawiam AC
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: wloochacz
Date: Tue, 06 Sep 2016 11:06
Date: Tue, 06 Sep 2016 11:06
7 lines
1356 bytes
1356 bytes
W dniu 2016-09-06 o 12:02, alex.cianciara@gmail.com pisze: > I teraz pytanie jak oprogramować PCta aby utrzymać równomierny takt 25 us. Napewno nie w takiej pętelce, a już użycie Sleep() to zbrodnia. :) https://github.com/LaKraven/LKSL Szukać "High Precision Threads". -- wloochacz
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Tue, 06 Sep 2016 11:20
Date: Tue, 06 Sep 2016 11:20
18 lines
2700 bytes
2700 bytes
W dniu wtorek, 6 września 2016 12:02:56 UTC+2 użytkownik alex.ci...@gmail.com napisał: > W dniu wtorek, 6 września 2016 01:25:52 UTC+2 użytkownik stch...@gmail.com napisał: > > > 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB. > [...] > > 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-). > > > 8) > Oj kolega Nyquist to się w grobie przewraca... 1 kHz to okres 1 ms, czyli wzorem Nyquista max 500 us krok próbkowania. A jak chcesz tak do 20 kHz to 25 us będzie bardziej odpowiednie. Jak chcesz dźwięk lepszej jakości to i 10 us nie będzie za dużo. > I teraz pytanie jak oprogramować PCta aby utrzymać równomierny takt 25 us. Napewno nie w takiej pętelce, a już użycie Sleep() to zbrodnia. :) > > Pozdrawiam > AC ======== O Q... !! Tak to jest, jak się bierze dane "z sufitu" bez grama pomyślunku i rachunku. Racja po Twojej stronie, po mojej czerwony rumieniec na pysku. Co do sleep(), nie ma się co czepiać, bo nie w tym problem. Oczywiście masz rację co do stabilności, a raczej jej braku w takim "zegarze", nie mniej jednak chodzi mi tylko o "wyświetlanie" danych na głośniku.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Tue, 06 Sep 2016 11:29
Date: Tue, 06 Sep 2016 11:29
23 lines
2967 bytes
2967 bytes
W dniu wtorek, 6 września 2016 13:20:15 UTC+2 użytkownik stch...@gmail.com napisał: > W dniu wtorek, 6 września 2016 12:02:56 UTC+2 użytkownik alex.ci...@gmail.com napisał: > > W dniu wtorek, 6 września 2016 01:25:52 UTC+2 użytkownik stch...@gmail.com napisał: > > > > > 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB. > > [...] > > > 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-). > > > > > > 8) > > Oj kolega Nyquist to się w grobie przewraca... 1 kHz to okres 1 ms, czyli wzorem Nyquista max 500 us krok próbkowania. A jak chcesz tak do 20 kHz to 25 us będzie bardziej odpowiednie. Jak chcesz dźwięk lepszej jakości to i 10 us nie będzie za dużo. > > I teraz pytanie jak oprogramować PCta aby utrzymać równomierny takt 25 us. Napewno nie w takiej pętelce, a już użycie Sleep() to zbrodnia. :) > > > > Pozdrawiam > > AC > > ======== > > O Q... !! Tak to jest, jak się bierze dane "z sufitu" bez grama pomyślunku i rachunku. Racja po Twojej stronie, po mojej czerwony rumieniec na pysku. Co do sleep(), nie ma się co czepiać, bo nie w tym problem. Oczywiście masz rację co do stabilności, a raczej jej braku w takim "zegarze", nie mniej jednak chodzi mi tylko o "wyświetlanie" danych na głośniku. ============ Oczywiście zmieniam na f=100Hz i sleep(1). Teraz Pan Nyquist może spać spokojnie.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: alex.cianciara
Date: Tue, 06 Sep 2016 13:13
Date: Tue, 06 Sep 2016 13:13
41 lines
3915 bytes
3915 bytes
W dniu wtorek, 6 września 2016 13:29:15 UTC+2 użytkownik stch...@gmail.com napisał:
> W dniu wtorek, 6 września 2016 13:20:15 UTC+2 użytkownik stch...@gmail.com napisał:
> > W dniu wtorek, 6 września 2016 12:02:56 UTC+2 użytkownik alex.ci...@gmail.com napisał:
> > > W dniu wtorek, 6 września 2016 01:25:52 UTC+2 użytkownik stch...@gmail.com napisał:
> > >
> > > > 2) Sygnał jest próbkowany "na zewnątrz", czyli poza pecetem z częstotliwością spełniającą warunek Nyquista i jest dostępny w postaci cyfrowej np. poprzez USB.
> > > [...]
> > > > 3) Załóżmy, że przychodzi mi czysty sinus o częstotliwości dajmy na to 1kHz, próbkowany z interwałem czasowym 10ms. Słowo w kodzie U2, więc 12-to bitowe (Najstarszy bit, to znak +/-).
> > >
> > >
> > > 8)
> > > Oj kolega Nyquist to się w grobie przewraca... 1 kHz to okres 1 ms, czyli wzorem Nyquista max 500 us krok próbkowania. A jak chcesz tak do 20 kHz to 25 us będzie bardziej odpowiednie. Jak chcesz dźwięk lepszej jakości to i 10 us nie będzie za dużo.
> > > I teraz pytanie jak oprogramować PCta aby utrzymać równomierny takt 25 us. Napewno nie w takiej pętelce, a już użycie Sleep() to zbrodnia. :)
> > >
> > > Pozdrawiam
> > > AC
> >
> > ========
> >
> > O Q... !! Tak to jest, jak się bierze dane "z sufitu" bez grama pomyślunku i rachunku. Racja po Twojej stronie, po mojej czerwony rumieniec na pysku. Co do sleep(), nie ma się co czepiać, bo nie w tym problem. Oczywiście masz rację co do stabilności, a raczej jej braku w takim "zegarze", nie mniej jednak chodzi mi tylko o "wyświetlanie" danych na głośniku.
>
> ============
>
> Oczywiście zmieniam na f=100Hz i sleep(1). Teraz Pan Nyquist może spać spokojnie.
Obawiam się, że nie do końca. Z moich testów czas wykonania sleep(1) bardzo zależy od komputera.
Na moim trwa od 1,02 do prawie 3 ms, ale jak wykonywałem testy na innych to czas trwania wynosił od prawie 0 ms do 20 ms.
Test wykonywany w pętli x 1000. Fragment testowy:
[...]
for i := 0 to ile_prob - 1 do
begin
QueryPerformanceCounter( istart );
Sleep( czas );
QueryPerformanceCounter( istop );
wartosci[ i ] := istop - istart;
end;
// aby policzyć czas potrzeba jeszcze wykonać
QueryPerformanceFrequency( frq );
// czas to (istop - istart) / frq * 1000 [ms]
AC
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: wloochacz
Date: Tue, 06 Sep 2016 13:21
Date: Tue, 06 Sep 2016 13:21
17 lines
1815 bytes
1815 bytes
W dniu 2016-09-06 o 15:13, alex.cianciara@gmail.com pisze: /ciach/ > Obawiam się, że nie do końca. Z moich testów czas wykonania sleep(1) bardzo zależy od komputera. /ciach/ To zależy nie tyle od komputera, co od OSu. Windows to nie jest system czasu rzeczywistego i *nigdy* nie będzie pewności co do tego ile to ma trwać. Nie da się i koniec. Można to tylko lepiej lub gorzej aproksymować. Gorzej to sleep(100) Lepiej to sleep(1) i GetTickCount. A w tym co podałem jest to zrobione jeszcze lepiej, ale to i tak nie jest idealne. -- wloochacz
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: Sebastian Biały
Date: Tue, 06 Sep 2016 18:11
Date: Tue, 06 Sep 2016 18:11
35 lines
2138 bytes
2138 bytes
On 2016-09-06 01:25, stchebel@gmail.com wrote:
> Jakich zaklęć użyć w procedure WyslijNaKarteDzwiekowa(a:word);
Ogolnie tego się tak nie robi.
Karty dzwiękowe posiadają zazwyczaj dwa bufory wyjściwe (tak samo
zazwyczaj DMA w mikrokontrolerach). Podstawowy i nastepny. Jak karta
skończy wysylac próbki w podstawowym to generuje przerwanie i jedzie
dalej z nastepnym jako podstawowym. W tym czasie CPU ma obowiązek
wypełnić znowu bufor.
Robi się to jakoś tak:
WyślijBuforNaKartę( dane, rozmiar );
WyślijBuforNaKartę( nastepneDane, rozmiar );
while( true )
{
...
if ( przerwanieKacieZabrakoDanychWPodstawowymBuforze )
WysliBuforNaKartę( następneDane + rozmiar );
nastepneDane += ...
}
Problemy czasu rzeczywistego zostawia się karcie. Tylko ona jest w
stanie wyrzucać dzwięk z okresloną prędkością.
Rozmiar bufora zależy od sytuacji w systemie operacyjnym w przypadku
windwosa jak zabranie RAM i zacznie swapować dowolnie długi bufor jest
za mały.
Zagadnienie, jak to z APi windowsa jest, tylko pozornie proste. Tu więcej:
http://blogersii.pl/2016/02/24/niskopoziomowa-obsluga-audio-w-windows/
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Wed, 07 Sep 2016 00:29
Date: Wed, 07 Sep 2016 00:29
51 lines
3515 bytes
3515 bytes
W dniu wtorek, 6 września 2016 20:11:32 UTC+2 użytkownik Sebastian Biały napisał:
> On 2016-09-06 01:25, stchebel@gmail.com wrote:
> > Jakich zaklęć użyć w procedure WyslijNaKarteDzwiekowa(a:word);
>
> Ogolnie tego się tak nie robi.
>
> Karty dzwiękowe posiadają zazwyczaj dwa bufory wyjściwe (tak samo
> zazwyczaj DMA w mikrokontrolerach). Podstawowy i nastepny. Jak karta
> skończy wysylac próbki w podstawowym to generuje przerwanie i jedzie
> dalej z nastepnym jako podstawowym. W tym czasie CPU ma obowiązek
> wypełnić znowu bufor.
Na pewno WYJŚCIOWE? Chyba raczej WEJŚCIOWE?! Karta dźwiękowa to SLAVE, pecet jest MASTER. Pecet/uC/czy_cokolwiek_innego podaje dane do karty audio. Być może "literówka" Ci się przytrafiła, jeżeli TAK, to póki co rozumiemy się.
>
> Robi się to jakoś tak:
>
> WyślijBuforNaKartę( dane, rozmiar );
> WyślijBuforNaKartę( nastepneDane, rozmiar );
No tyle to ja wiem. Przeczytaj główny wątek jeszcze raz.
>
> while( true )
> {
> ...
> if ( przerwanieKacieZabrakoDanychWPodstawowymBuforze )
> WysliBuforNaKartę( następneDane + rozmiar );
>
> nastepneDane += ...
> }
Rozumiem powyższe, ale.. Na tej grupie pisze się w Pascalu.
>
> Problemy czasu rzeczywistego zostawia się karcie. Tylko ona jest w
> stanie wyrzucać dzwięk z okresloną prędkością.
>
> Rozmiar bufora zależy od sytuacji w systemie operacyjnym w przypadku
> windwosa jak zabranie RAM i zacznie swapować dowolnie długi bufor jest
> za mały.
Problem czasowy, to zupełnie inna bajka. Czytaj ze zrozumieniem główny wątek (z poprawkami). Zostawmy w spokoju sleep(). Załóżmy, że działa bez zarzutu. Chodzi mi tylko o "wyświetlenie" danych na głośniku.
>
> Zagadnienie, jak to z APi windowsa jest, tylko pozornie proste. Tu więcej:
>
> http://blogersii.pl/2016/02/24/niskopoziomowa-obsluga-audio-w-windows/
Chyba dobry namiar - Dzięki. Jutro to przetrawię, i jakby co będę dalej tutaj marudził.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Wed, 07 Sep 2016 01:05
Date: Wed, 07 Sep 2016 01:05
22 lines
2475 bytes
2475 bytes
W dniu wtorek, 6 września 2016 15:21:01 UTC+2 użytkownik wloochacz napisał: > W dniu 2016-09-06 o 15:13, alex.cianciara@gmail.com pisze: > /ciach/ > > Obawiam się, że nie do końca. Z moich testów czas wykonania sleep(1) bardzo zależy od komputera. > /ciach/ > > To zależy nie tyle od komputera, co od OSu. Windows to nie jest system > czasu rzeczywistego i *nigdy* nie będzie pewności co do tego ile to ma > trwać. Nie da się i koniec. > Można to tylko lepiej lub gorzej aproksymować. > Gorzej to sleep(100) > Lepiej to sleep(1) i GetTickCount. > > A w tym co podałem jest to zrobione jeszcze lepiej, ale to i tak nie > jest idealne. > > -- > wloochacz ==================== Zostawmy problemy czsowe na inny wątek. W głównym wątku poczyniłem drobny, aczkolwiek istotny błąd (Nyquist). Nie w tym rzecz. Chodzi o "wyświetlenie" jakiejś tam wartości na głośniku. Częstotliwość powtarzania owego "wyświetlania", to zupełnie inna bajka.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: Sebastian Biały
Date: Wed, 07 Sep 2016 15:59
Date: Wed, 07 Sep 2016 15:59
38 lines
2495 bytes
2495 bytes
On 2016-09-07 02:29, stchebel@gmail.com wrote: >> Karty dzwiękowe posiadają zazwyczaj dwa bufory wyjściwe (tak samo >> zazwyczaj DMA w mikrokontrolerach). Podstawowy i nastepny. Jak karta >> skończy wysylac próbki w podstawowym to generuje przerwanie i jedzie >> dalej z nastepnym jako podstawowym. W tym czasie CPU ma obowiązek >> wypełnić znowu bufor. > > Na pewno WYJŚCIOWE? Tak. Dane z tych buforów znajdą się na *wyjściu* karty i dlatego są wyjściowe. > Chyba raczej WEJŚCIOWE?! Są również takie. Do line-in/mikrofonu. > Karta dźwiękowa to SLAVE, pecet jest MASTER. Nie patrz na peceta. Patrz na kartę. Od zawsze bufor który zostanie wysłany na wyjście karty nazywa się wyjsciowym. W kazdym DMA jest to tak samo nazywane. > Rozumiem powyższe, ale.. Na tej grupie pisze się w Pascalu. Zapis klamrowy jest bardziej zwięzly. >> Rozmiar bufora zależy od sytuacji w systemie operacyjnym w przypadku >> windwosa jak zabranie RAM i zacznie swapować dowolnie długi bufor jest >> za mały. > Problem czasowy, to zupełnie inna bajka. Czytaj ze zrozumieniem główny wątek (z poprawkami). Zostawmy w spokoju sleep(). Poprawny algorytm nie zawiera sleep. > Załóżmy, że działa bez zarzutu. Chodzi mi tylko o "wyświetlenie" danych na głośniku. Dostaleś odpowiedź. Masz dwa bufory które naprzemiennie wysycasz danymi w miarę jak karta zglasza przerwania.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: stchebel
Date: Wed, 07 Sep 2016 18:07
Date: Wed, 07 Sep 2016 18:07
9 lines
1796 bytes
1796 bytes
W dniu środa, 7 września 2016 18:00:11 UTC+2 użytkownik Sebastian Biały napisał: > > > Załóżmy, że działa bez zarzutu. Chodzi mi tylko o "wyświetlenie" danych na głośniku. > > Dostaleś odpowiedź. Masz dwa bufory które naprzemiennie wysycasz danymi > w miarę jak karta zglasza przerwania. Jakoś nie widzę tej odpowiedzi jak wysłać dane(pojedyńcze słowo) na kartę audio.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: Sebastian Biały
Date: Wed, 07 Sep 2016 18:44
Date: Wed, 07 Sep 2016 18:44
24 lines
2509 bytes
2509 bytes
On 2016-09-07 20:07, stchebel@gmail.com wrote: >>> Załóżmy, że działa bez zarzutu. Chodzi mi tylko o "wyświetlenie" danych na głośniku. >> Dostaleś odpowiedź. Masz dwa bufory które naprzemiennie wysycasz danymi >> w miarę jak karta zglasza przerwania. > Jakoś nie widzę tej odpowiedzi jak wysłać dane(pojedyńcze słowo) na kartę audio. Jest to bezuzyteczne. Żaden duży system nie jest RT wiec nie ma po co robić takiego ficzera jak natychmiastowe sterowanie membraną glośnika ponieważ nie masz kontroli nad wywlaszczaniem i nie jesteś w stanie osiągnąć stabilnych odstepow. To zadanie dla DMA karty które jest stabilne bez względu na zachowanie OSa. Oodpowiedź brzmi: funkcja "wyslij słowo na kartę" tak naprawdę dopisze do bufora i jak się on zapełni wysle go na kartę. nie wiem jak rozwiążesz problem aby tą funkcję wołać odpowiednio często aby nie zabrakło danych w buforach i odpowiednio nieczęsto aby nie przepełnić bufora. Ewentualnie jeśli koniecznie potrzebujesz nonsensowną funkcję, to niech ona wypełnia bufor tą samą daną i wysyła ją do karty. Jak zawołasz z inna daną to anulujesz odtwarzanie i ponownie wypełnisz bufory nową daną. A tak naprawdę: nie potrzebujesz i nie chcesz mieć funkcji "wyślijSłowoNaGłośnik". Chcesz mieć podwójne buforowanie.
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: arivald
Date: Wed, 07 Sep 2016 23:10
Date: Wed, 07 Sep 2016 23:10
45 lines
3277 bytes
3277 bytes
W dniu 2016-09-07 o 20:44, Sebastian Biały pisze: > On 2016-09-07 20:07, stchebel@gmail.com wrote: >>>> Załóżmy, że działa bez zarzutu. Chodzi mi tylko o "wyświetlenie" >>>> danych na głośniku. >>> Dostaleś odpowiedź. Masz dwa bufory które naprzemiennie wysycasz danymi >>> w miarę jak karta zglasza przerwania. >> Jakoś nie widzę tej odpowiedzi jak wysłać dane(pojedyńcze słowo) na >> kartę audio. > > Jest to bezuzyteczne. Żaden duży system nie jest RT wiec nie ma po co > robić takiego ficzera jak natychmiastowe sterowanie membraną glośnika > ponieważ nie masz kontroli nad wywlaszczaniem i nie jesteś w stanie > osiągnąć stabilnych odstepow. To zadanie dla DMA karty które jest > stabilne bez względu na zachowanie OSa. > > Oodpowiedź brzmi: funkcja "wyslij słowo na kartę" tak naprawdę dopisze > do bufora i jak się on zapełni wysle go na kartę. nie wiem jak > rozwiążesz problem aby tą funkcję wołać odpowiednio często aby nie > zabrakło danych w buforach i odpowiednio nieczęsto aby nie przepełnić > bufora. > > Ewentualnie jeśli koniecznie potrzebujesz nonsensowną funkcję, to niech > ona wypełnia bufor tą samą daną i wysyła ją do karty. Jak zawołasz z > inna daną to anulujesz odtwarzanie i ponownie wypełnisz bufory nową daną. > > A tak naprawdę: nie potrzebujesz i nie chcesz mieć funkcji > "wyślijSłowoNaGłośnik". Chcesz mieć podwójne buforowanie. > Albo, jak koniecznie potrzebujesz wysyłania sampla po samplu, zainwestuj w odpowiedni hardware. Z prostych i tanich, kartę z dwoma portami równoległymi i 16-bitowy Covox. Albo zamiast portów równoległych kartę z 16-toma portami GPIO + Covox. Tylko pod Windows nie dasz rady tego poprawnie obsłużyć, nawet jak zarżniesz procesor w busy-loop, i tak system może twój proces wywłaszczyć i będzie przerwa. Z lepszych rozwiązań, własną kartę PCIE z jakimś DACem (digital audio converter), plus sterownik sobie napiszesz, taki co wysyła pojedyncze sample. Bo AFAIK wszystkie gotowe rozwiązania, w tym te znane jako "karty dźwiękowe", używają buforowania, inaczej się nie da pod Windows. -- Arivald
Re: Odtwarzanie Audio - trochę inaczej (D6)
Author: jh
Date: Mon, 12 Sep 2016 20:26
Date: Mon, 12 Sep 2016 20:26
47 lines
3524 bytes
3524 bytes
W dniu 2016-09-06 o 01:25, stchebel@gmail.com pisze: > Pytanie/Prośba: > > Jakich zaklęć użyć w procedure WyslijNaKarteDzwiekowa(a:word); waveOut i spółka (waveXXX). > Chyba trzeba wykorzystać jakieś windowsowe API, ale kompletnie się na tym nie znam. Myślałem też o buforowaniu danych w FIFO o pewnej głębokości, natępnie o szybkim odczycie i konwersji na plik np. WMV. Też co prawda nie wiem jak tego dokonać, ale obawiam się, że soft mógłby mieć "czkawkę". Z grubsza: otwierasz urządzenie wejściowe audio (waveInOpen), jeśli takie masz, zgodnie z wybranym formatem; przygotowujesz i formatujesz bufory (waveInPrepareHeader, WAVEHDR); dodajesz (waveInAddBuffer) je do kolejki urządzenia audio i uruchamiasz urządzenie (waveInStart). Urządzenie audio (sterownik) zapełnia Ci bufor i zwraca do aplikacji w callback, kopiujesz sobie bufor do swoich danych, jak najszybciej się da, zerujesz bufor, przygotowujesz go jak poprzednio i ponownie podsyłasz do urządzenia. Na koniec stopujesz urządzenie waveInStop, czekasz, aż wrócą wszystkie bufory, których już nie dodajesz do kolejki, a następnie zamykasz urządzenie waveInClose. W drugą stronę robisz praktycznie to samo - różnica w funkcjach WaveAPI to waveOutXXX, a nie waveInXXX. W obu przypadkach obowiązuje zasada - im większy bufor i większa ich ilość tym bezpieczniej uniknąć buffer underrun, czyli jeśli spóźnisz się z dostawą buforów - masz dziurę i błąd. Ale większe bufory i większa ich liczba, to dłuższy czas na odebranie dźwięku lub jego "zagranie" przez urządzenie, oraz czas potrzebny do odczekania na powrót buforów przy stopowaniu urządzenia. > Zagadnienie jest typu: [mikrofon/wzmacniacz/ADC]=>[USB]=>[Karta Dźwiękowa/głośnik] . Generalnie jak chcesz oprzeć się o odczyt danych po USB w czasie rzeczywistym korzystając ze standardowych bibliotek to IMHO strata czasu. Potrzebujesz sterownika, który poradzi sobie z jitterem, będzie umiał się po ludzku zsynchronizować, a jednocześnie układ USB będzie posiadał własny bufor, inaczej na specyfikę łącza nie utrzymasz tak stabilnego zegara, jakbyś oczekiwał. Takie firmy jak np. RME robią własne układy do USB, które gwarantują dużą stabilność przy przesyłaniu naprawdę dużej ilości danych. > Jak to zrobić? Oczywiście, "gotowiec" najmilej widziany, ale wszelakie wskazówki również. https://github.com/CHERTS/newac Masz wszystko, co potrzeba poza samym dostarczaniem danych od USB. Free. jh
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads