logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C] ATmega644p - WAV Player zła jakość

norbus2000a 17 Wrz 2014 14:00 3285 31
  • #1 13968042
    norbus2000a
    Poziom 14  
    Cześć !

    Szukałem w internecie i na elektrodzie i pełno tego typu programów i gotowców, ale tylko pod BASCOM. Ja ostatnio zrezygnowałem z BASCOM'a i zacząłem z C.

    Zrobiłem odtwarzacz, ale strasznie charczy. Miałby ktoś pomysł jaka może być tego przyczyna?

    Kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #2 13968294
    witoldwitoldowicz
    Poziom 28  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 13968770
    norbus2000a
    Poziom 14  
    Wielkie dzięki! Piosenkę słychać fajnie. Ale "wcina" się też cykliczne cykanie. Podejrzewam, że to przez odczyt do bufora. Czy da się to wyeliminować?
  • Pomocny post
    #4 13968791
    witoldwitoldowicz
    Poziom 28  
    Wyeliminuj delay(40),sprobuj zwiekszyc bufor,zmien na
    if((pos...
    else if((pos...
  • Pomocny post
    #5 13968817
    tmf
    VIP Zasłużony dla elektroda
    Przede wszystkim należy czytać po sektorze - czyli po 512 bajtów. Karty SDHC nie umożliwiają odczytu dowolnego bajtu - odczyt 256 bajtu sektora wymaga odczytania i pominięcia pierwszych 256 bajtów, co trochę trwa.
  • #6 13968832
    norbus2000a
    Poziom 14  
    Dałem bufor 1024 i chyba zniknęło(albo tego nie wyłapuję). Delay chyba wkleiłem na forum przez przypadek. Wielkie dzięki.
  • #7 13968875
    tmf
    VIP Zasłużony dla elektroda
    Swoją drogą, jeśli robisz player wav to pomyśl o xmega - dlatego, że uzyskasz więcej bitów z PWM. Timer możesz taktować do 256 MHz, dzięki temu możesz odtwarzać próbki z rozdzielczością 12-14 bitów. To zdecydowanie poprawia jakość, możesz też skorzystać z wbudowanego DAC, dzięki czemu nie trzeba odfiltrowywać częstotliwości PWM. Jeśli cie to zainteresuje to przejrzyj przykłady do "AVR. Układy peryferyjne" - masz tam przykłady odtwarzacza wav, także PCM z kompresiją m.in. dialogic i ADPCM oraz mp3 z wykorzystaniem zewnętrznego koprocesora.
  • #8 13970110
    norbus2000a
    Poziom 14  
    Ma ktoś może pomysł ja zwolnić AVR'a? Przy moim kwarcu 10MHz max prędkość PWM 10000000:256 = ok.39KHz. Czyli plików 44.1KHz nie odtworzę, ale czy jak odczytam prędkość z nagłówka tko mogę jakoś zwolnić np. do 32KHz?
  • #9 13970606
    tmf
    VIP Zasłużony dla elektroda
    Ty nie chcesz zwolnić AVRa, lecz go przyśpieszyć, a konkretnie przyśpieszyć taktowanie timera. Czyli taktuj go 20 MHz, a konkretnie tak, abyś miał wielokrotność częstotliwości 44.1 kHz. Przy czym 8-bitowy PWM brzmi tak sobie.
  • #10 13972523
    norbus2000a
    Poziom 14  
    Chcę go zwolnić, by odtwarzał pliki 32KHz z prędkością 32KHz, a nie z 39KHz. Czy da się to zrealizować by player dostosowywał się do prędkości WAV'u?

    Trochę OffTopic: Czy są XMegi w obudowie Nie-SMD?
  • #11 13972588
    tmf
    VIP Zasłużony dla elektroda
    Da się to zrobić, ale efektem ubocznym będzie zmiana rozdzielczości PWM, gdyż zmianę taktowania timera możesz dokonać jedynie przez preskaler, czyli nie jest to zbyt elastyczne narzędzie. W XMEGA timer może być taktowany np. z innego timera, który w tym przypadku robi jako elastyczny preskaler, w efekcie łatwiej jest zmienić częstotliwość odtwarzania próbek. Można oczywiście dokonać programowej zmiany samplowania, ale na MCU ze względu na w wielu przypadkach raczej zawiłe algorytmy może to być karkołomne zadanie. Szczególnie jeśli taka zmiana miałaby byc dokonywana w locie. Co do XMEGA - nie ma ich w obudowach innych niż do SMD - możesz kupić albo przejściówkę na DIL - jest kilka gotowych polskiej produkcji, albo przyzyczaić się do SMD, których lutowanie jest o wiele łatwiejsze i nie trzeba wiercić dziur.
  • #12 13972888
    deus.ex.machina
    Poziom 32  
    Przede wszystkim poprawnie przygotuj sobie próbki np przy pomocy programu SoX.
    Jeśli uda ci się odgrywać próbki z prędkością 44100Hz to będziesz miał do dyspozycji szeroka gamę filtrów kształtujących błąd kwantyzacji (noiseshaping).

    http://sox.sourceforge.net/SoX/NoiseShaping

    np:

    
    @rem  lipshitz, f-weighted, modified-e-weighted, improved-e-weighted, gesemann, shibata, low-shibata, high-shibata 
    @set noiseshape=improved-e-weighted
    @sox --multi-threaded --buffer 131072 -S -V -D %1 -b 8 %1.wav rate -v -s -L 44100 gain -n -.633260 dither -f %noiseshape% -p 8 stats -b 8
    @sox --multi-threaded --buffer 131072 -S -V -D %1 -b 8 %1_mono.wav remix - rate -v -s -L 44100 gain -n -.633260 dither -f %noiseshape% -p 8 stats -b 8
    @pause
    



    Jeśli mógłbyś jeszcze bardziej przyspieszyć odgrywanie to przez trochę większe skomplikowanie skryptu dla SoX (lub użycie innego programu do re-kwantyzacji np Noise autorstwa Sebastian Gesemann) udałoby ci się osiągnąć jakość DSD na 8 bitach bez większych problemów.

    Za świetnym dokumentem "Stanley P. Lipshitz and John Vanderkooy - Why 1-Bit Sigma-Delta Conversion is Unsuitable for High-Quality Applications"

    "Finally, consider 8-bit, four-times-oversampled PCM with
    noise shaping. This is also a data rate one-half that of DSD and
    double that of CD, with a sampling rate of 4 × 44,100 =
    176,400 Hz. It can achieve a noise floor 120 dB below full
    scale up to 20 kHz, using 96 dB of noise shaping, and a total
    noise power of –19 dBFS. Its frequency response would be
    flat to 80 kHz. This example is perhaps the most instructive of
    the lot. For a data rate one-half that of DSD, it achieves a
    comparable signal bandwidth, with a similar noise power
    density up to 20 kHz, but much lower power above this
    frequency, and 28 dB lower total noise power. It is fully
    TPDF-dithered, and so is completely artefact free. At one-half
    the data rate it outperforms DSD on every count! DSD is a
    profligate wastrel of capacity."

    Oczywiscie możesz użyć tez niższej prędkości próbkowania niż 44100 - po prostu trochę będziesz musiał pokombinować no i jakość nie będzie optymalna (mniej miejsca na poprawny noiseshaping).
  • #13 13973590
    norbus2000a
    Poziom 14  
    Właśnie dostałem układy TDA1543, ma ktoś jakiś link do przykładu oprogramowania ich w C?
  • #14 13973630
    witoldwitoldowicz
    Poziom 28  
    Sciagnij datasheet i poczytaj o formacie I2S.
  • #15 13973648
    deus.ex.machina
    Poziom 32  
    norbus2000a napisał:
    Właśnie dostałem układy TDA1543, ma ktoś jakiś link do przykładu oprogramowania ich w C?


    A dokładnie co ma robić twoje urządzenie i dlaczego nie możesz przygotować sobie wcześniej dźwięków by je odtworzyć z zadana prędkością próbkowania?

    Sprawdziłem sobie ze bez problemu używając 8 bitowych próbek i nawet mniejszej niż 44100 prędkości próbkowania (czyli dokładnie 10MHz/256 jak w twoim układzie) udaje się uzyskać spokojnie 12 - 14 bitów dynamikę sygnału audio - jak na 8 bitowy układ to chyba całkiem OK.
  • #16 13973722
    norbus2000a
    Poziom 14  
    Chcę odtworzyć WAV z karty SD z pomocą DAC TDA1543.
  • #17 13973909
    deus.ex.machina
    Poziom 32  
    norbus2000a napisał:
    Chcę odtworzyć WAV z karty SD z pomocą DAC TDA1543.


    Jakie wav? 8 bitów? 16? Jaka prędkość próbkowania - od biedy mógłbyś dołożyć jakiś rejestr przesuwny (2x 74165)bo nie wiem czy SPI pozwoli przesłać 16 bitów jednym ciągiem. Pewnie przydałby się jakiś bufor przed tymi 74165 (znów 2x 74574).
    No i pewnie żeby się to nie rozjeżdżało obsługę trzeba zrobić na przerwaniach.
    Pomyśl o jakimś ARM z wbudowanym I2S i DMA zwłaszcza ze i tak używasz C.

    Nie bardzo rozumiem dlaczego nie chcesz używać wbudowanego PWM i próbek 8 bit ale być może czegoś nie wiem.
  • #18 13974107
    tmf
    VIP Zasłużony dla elektroda
    Nie ma jak sobie udziwniać... Robisz jakiś odtwarzacz muzyki z karty SD? Albo zrób to na PWM, albo użyj jak pisałem XMEGA, ktora ma DAC i niepotrzebny jest zewnętrzny, a jeśli chcesz odtwarzać różne formaty to użyj np. VS1003b lub podobny koprocesor muzyczny. Będziesz mógł odtwarzać także mp3, w dodatku masz w nim część analogową i możesz podłączyć go bezpośrednio pod słuchawki lub wejście wzmacniacza.
  • #19 13982213
    norbus2000a
    Poziom 14  
    Ma może ktoś jakiś przykład w C jak obsłużyć I2S? Męczę się z tym i nic nie wychodzi ;(
    Próbki najlepiej 44100Hz i stereo do TDA1543. Tylko jak obsłużyć I2S?
  • #20 13982590
    witoldwitoldowicz
    Poziom 28  
    Sprawdzałeś jaką predkość odczytu masz z karty?Czy zostanie jakiś czas na cokolwiek innego?
  • #21 13982606
    norbus2000a
    Poziom 14  
    A podpowiedziałbyś jak to zrobić?
  • #22 13982635
    witoldwitoldowicz
    Poziom 28  
    Najprościej to czytać forem np. po 512B jakis znanej wielkości plik(minimum kilka MB) po skończeniu dać sygnał (LCD lub Dioda LED) i zobaczyć jak długo ściągał.
  • #23 13983841
    deus.ex.machina
    Poziom 32  
    Wybacz ale masz ograniczone zasoby sprzętowe i zwyczajnie najlepiej będzie dostosować próbki do tych zasobów zwłaszcza ze jakość którą możesz uzyskać przekroczy twoje oczekiwania o ile przygotujesz dane w mądry sposób (i tak musisz używać PC do transferu danych - możesz uruchomić automatyczny skrypt który zwyczajnie przygotuje ci dane tak by wycisnęły maximum z twoich zasobów).
    Jeśli chcesz mogę wystawić próbki audio zakodowane w mądry sposób który oszczędzi tak wielkość plików (miejsce na nośniku) jak i wymagania dotyczące zasobów.
  • #24 13984457
    norbus2000a
    Poziom 14  
    Takie małe pytanie co rozumiesz przez "ograniczone zasoby sprzętowe"? Za małe taktowanie procesora, powinienem używać innego procka czy coś jeszcze innego? Jak "zakodować" te próbki?

    witoldwitoldowicz napisał:
    Sprawdzałeś jaką predkość odczytu masz z karty?


    Sprawdzę to w najbliższym czasie ;)
  • #25 13986760
    deus.ex.machina
    Poziom 32  
    norbus2000a napisał:
    Takie małe pytanie co rozumiesz przez "ograniczone zasoby sprzętowe"? Za małe taktowanie procesora, powinienem używać innego procka czy coś jeszcze innego? Jak "zakodować" te próbki?


    Jak rozumiem chcesz używać 8 bitowego HW (AVR) by odtwarzać próbki 16 bitów, do tego ten 8 bitowy sprzęt ma relatywnie mało RAM i nie posiada dedykowanego HW do audio 16 bitów. Chyba zgodzisz się ze mną ze taki HW można nazwać "ograniczone zasoby sprzętowe" - dlatego proponuje byś rozwiązał problem i dostosował to co chcesz odtwarzać do tych zasobów które posiadasz - minimalnie tracąc jakość (praktycznie na granicy percepcji i wiele osób nie zauważy utraty jakości) możesz sobie znacznie ułatwić życie i uzyskać rezultat więcej niż dobry.

    Założyłem (być może błędnie) ze i tak musisz przygotować sobie pliki wav (bo np formatem źródłowym jest mp3 lub podobny format który wymaga znacznej mocy obliczeniowej podczas dekodowania) - tak wiec z Twojego punktu widzenia nie ma większej różnicy czy przygotowujesz pliki wav w taki czy inny sposób.

    Sposób "zakodowania" podałem już wcześniej, nieco bardziej rozbudowany mogę podać teraz - generalnie pozwala on na uzyskanie jakości 12 - 14 bitów na 8 bitowym PWM w najważniejszej dla ludzkiego ucha części spektrum.

    Skopiuj poniższy tekst do pliku tekstowego z rozszerzeniem bat lub cmd, zakładam ze wcześniej ściągniesz aktualna wersje SoX http://sourceforge.net/projects/sox/ i poniższy batch umieścić w katalogu z programem SoX. Od tego momentu będziesz mógł otrzymać 8 bitowe, stereo, wav skonwertowane w taki sposób by odgrywały się na twoim HW bez problemów (skrypt dostosowuje prędkość próbkowania do 10MHz/256 czyli 39062.5Hz (po zaokrągleniu w dol do 39062Hz).

    
    @rem  lipshitz, f-weighted, modified-e-weighted, improved-e-weighted, gesemann, shibata, low-shibata, high-shibata 
    @set noiseshape=shibata
    @set avrclock=10
    @echo AVR clock [MHz] = %avrclock%
    @set /a srate=(1000000*%avrclock%)/256
    @echo sample rate = %srate% 
    @set /a sincomp=%srate%/4
    @echo Sinc slope compensation = %sincomp%
    @echo noise shape slope = %noiseshape%
    
    @sox --multi-threaded --buffer 131072 -S -V -D %1 -b 8 %1_8bit.wav sinc 16-19k -a 120 rate -v -s -L %srate% treble 6.0206 %sincomp% gain -n -.102389 dither -f %noiseshape% -p 8 stats -b 8
    
    

    --
    batch poprawiony i teraz jest na tzw "wypas"
  • #26 13986824
    tmf
    VIP Zasłużony dla elektroda
    Ja tylko nie rozumiem po co upierać się przy TDA1543, który kosztuje 7-10 zł, narobić się z tym, a na końcu mieć mocno ograniczone możliwości odtwarzania, skoro za 10-16zł można kupić np. VS1003b, który załatwia praktycznie wszystkie formaty i ma wszystko co potrzebne, żeby odtwarzać muzykę w wysokiej jakości, w dodatku cała obsługa jest tak prosta, że najprostszy AVR to pociągnie. Jeśli koszty są istotne, to można od biedy zaprząc sam mikrokontroler i to dosyć prosty - np. http://elm-chan.org/works/sd8p/report.html, można też po prostu użyć mikrokontrolera, który ma I2S sprzętowe, lub MCU, który po prostu bez problemu wygeneruje te 12-14 bitów przez PWM.
    Niemniej jednak warto by było, żeby autor podał konkretne założenia, co to ma robić i czego oczekuje bo mamy już 25 postów kompletnie o niczym. Tylko konkretnie, bo info "chcę odtwarzać pliki wav z karty SD" brzmi mniej więcej tak "chcę jeździć autem, doradźcie jaki kupić".
  • #27 13986916
    deus.ex.machina
    Poziom 32  
    tmf napisał:
    Ja tylko nie rozumiem po co upierać się przy TDA1543, który kosztuje 7-10 zł, narobić się z tym, a na końcu mieć mocno ograniczone możliwości odtwarzania, skoro za 10-16zł można kupić np. VS1003b, który załatwia praktycznie wszystkie formaty i ma wszystko co potrzebne, żeby odtwarzać muzykę w wysokiej jakości, w dodatku cała obsługa jest tak prosta, że najprostszy AVR to pociągnie. Jeśli koszty są istotne, to można od biedy zaprząc sam mikrokontroler i to dosyć prosty - np. http://elm-chan.org/works/sd8p/report.html, można też po prostu użyć mikrokontrolera, który ma I2S sprzętowe, lub MCU, który po prostu bez problemu wygeneruje te 12-14 bitów przez PWM.
    Niemniej jednak warto by było, żeby autor podał konkretne założenia, co to ma robić i czego oczekuje bo mamy już 25 postów kompletnie o niczym. Tylko konkretnie, bo info "chcę odtwarzać pliki wav z karty SD" brzmi mniej więcej tak "chcę jeździć autem, doradźcie jaki kupić".


    Ja zaś kompletnie nie rozumiem dlaczego wszyscy upierają się by odtwarzać próbki na 12 - 14 - 16 bitach PWM gdy 8 bitów zwyczajnie będzie w zasięgu każdego HW (stosowny dokument który wspomniałem mówi o tym ze 8 bitów przy 4x oversamplingu i poprawnym noiseshapingu zaoferuje parametry lepsze niż audiofilskie SACD - w realnym życiu przekłada się to na 8 bitowe PWM taktowane zegarem mniejszym niż 50MHz - realne z punktu widzenia technologi TTL serii AC/F) - co do reszty pełna zgoda - sztuka dla sztuki ale warto byłoby znać przeznaczenie.
  • #28 13987057
    tmf
    VIP Zasłużony dla elektroda
    Ja się nie upieram przy więcej niż 8 bitach, tylko autor wie po co chce więcej. Jedyna wada pozostania przy 8 bitach jest taka, że wymaga to konwersji odtwarzanych plików przed ich odtworzeniem. Przy 12-14 bitowym PWM można spokojnie odtwarzać pliki nagrane z 16-bitową głębią po prostu ignorując najmniej znaczące bity. A 12-14 bitowy PWM jest osiągalny dla 8 bitowych mikrokontrolerów bez większych problemów - zresztą takie przykłady umieściłem w swojej książce, więc można je sobie ściągnąć i zobaczyć jak to działa. Ba, można nawet i 16 bitowe odtwarzanie zrobić, kosztem dodania paru rezystorów...
  • #29 13987620
    norbus2000a
    Poziom 14  
    @Deus.ex.machina: Przerobiłem tą komendę pod linuxa tak:

    Kod: Bash
    Zaloguj się, aby zobaczyć kod


    Twoja wyrzuca: sox FAIL sinc: filter frequency must be less than sample-rate / 2
    Dziwne ... 39062/2 ≈ 19 ("sinc 14-15k" to najwyższa która działa)

    Po konwersji słychać(przy odtwarzaniu na komputerze) taki niemiły pisk. Czy to wina linuxa?

    Odnośnie celu oprogramowanie TDA: Chcę się czegoś nauczyć (w tym przypadku wysyłania dźwięku do TDA). Zrobić to, mieć satysfakcję...

    8bit już osiągnąłem, chcę nauczyć się wykorzystania TDA jako zewn. przetwornika. VS1003b zostawię sobie na "deser".

    EDIT: Wracając do tematu "zwolnienia" PWM, niedługo będę miał kwarc 20MHz i przy tym kwarcu częstotliwość PWM wyjdzie(przy 8bit i prescaler 1): 78125Hz. Jak go "przystosować" do określonej częstotliwości? Zmienić prescaler(chyba nie), zmienić na PWM 9bit? Jak wtedy podawać próbki 8 bitowe na ten PWM?

    Czy da się dokładnie dostroić PWM bez marginesu?
  • #30 13988476
    tmf
    VIP Zasłużony dla elektroda
    Niestety w zwykłej ATMega jest pewien problem o którym już zresztą ci pisałem - ponieważ źródłem taktowania timera jest wyłącznie preskaler, nie da się jednocześnie dowolnie określić częstotliwości odtwarzania i głębi PWM. Skoro się uczysz to weź sobie elastyczniejszy procek, np. XMEGA 8E5, a naktórym możesz timer taktować przebiegiem z innego timera, w efekcie i precyzyjnie określić częstotliwość PWM i jego głębię. Dla ATMegi najlepiej użyć kwarcu o częstotliwości będącej wielokrotnością czestotliwości próbkowania, wybranego dzielnika preskalera i błębi bitowej PWM.
REKLAMA