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

sprzętowy odtwarzacz WAV

beatcomber 05 Sie 2005 18:55 3893 13
  • #1 1709457
    beatcomber
    Poziom 11  
    Chcę przy pomocy ATMega16 i 8-bitowego DAC zrobić odtwarzacz plików WAV (mono, 8-bit, 22050Hz) i poszukuję w związku z tym odp. na dwa pytania:

    1) czy każdy odpowiednio szybki DAC nadaje się do odtwarzania dźwięku? (zrobiłem próbę z DAC0808 i w wyniku otrzymałem charczenie tylko trochę przypominające oryginalny dźwięk)

    2) jak miksować cyfrowo dźwięki z dwóch źródeł i odtwarzać jednocześnie przy pomocy jednego 8-bit DAC? Czy może rozdzielczość 8-bit DAC jest za mała do miksowania dwóch 8-bit dźwięków?

    Proszę o jakieś wskazówki i pozdrawiam.
  • #2 1709883
    Zbych_
    Poziom 25  
    beatcomber napisał:
    1) czy każdy odpowiednio szybki DAC nadaje się do odtwarzania dźwięku? (zrobiłem próbę z DAC0808 i w wyniku otrzymałem charczenie tylko trochę przypominające oryginalny dźwięk)


    Może nie każdy, ale większość nie powinna mieć kłopotów z tak małymi częstotliwościami. A co do charczenia to przyczyn może być wiele:
    - spaprany program
    - uszkodzony sprzęt
    - brak filtru wyjściowego (ale wtedy dźwięk jest bardziej metaliczny, a nie charczący, choć to zależy od częstotliwości próbkowania)
    - źle przygotowany dźwięk (rodzielczość, częstotliwość próbkowania, nieprzycięte pasmo przed downsamplingiem itp.)

    beatcomber napisał:

    2) jak miksować cyfrowo dźwięki z dwóch źródeł i odtwarzać jednocześnie przy pomocy jednego 8-bit DAC? Czy może rozdzielczość 8-bit DAC jest za mała do miksowania dwóch 8-bit dźwięków?


    Najprostszym rozwiązaniem jest dodanie do siebie próbek dzwięków i przeskalowanie wyniku tak, żeby nadal mieścił się na 8 bitach. Np. tak DAC=(próbka_dźwięku1 + próbka_dźwięku2)/2. Przy ośmi bitowym miksowaniu da się niestety zauważyć wzrost szumu sygnału wyjściowego (szumy kwantyzacji). Najprościej by było wziąć jakiś pakiet matematyczny (scilab, matlab), albo przeznaczony do obróbki dzwięków (cool edit, audacity) i nausznie przekonać się jakie efekty daje zmiana rozdzielczości próbek, zmiana częstotliwości próbkowania, odpowiednia filtracja dźwięków itp.
  • #3 1709943
    MirekCz
    Poziom 35  
    Zbych_ napisał:

    beatcomber napisał:

    2) jak miksować cyfrowo dźwięki z dwóch źródeł i odtwarzać jednocześnie przy pomocy jednego 8-bit DAC? Czy może rozdzielczość 8-bit DAC jest za mała do miksowania dwóch 8-bit dźwięków?


    Najprostszym rozwiązaniem jest dodanie do siebie próbek dzwięków i przeskalowanie wyniku tak, żeby nadal mieścił się na 8 bitach. Np. tak DAC=(próbka_dźwięku1 + próbka_dźwięku2)/2. Przy ośmi bitowym miksowaniu da się niestety zauważyć wzrost szumu sygnału wyjściowego (szumy kwantyzacji). Najprościej by było wziąć jakiś pakiet matematyczny (scilab, matlab), albo przeznaczony do obróbki dzwięków (cool edit, audacity) i nausznie przekonać się jakie efekty daje zmiana rozdzielczości próbek, zmiana częstotliwości próbkowania, odpowiednia filtracja dźwięków itp.


    Nie.
    Poprawnym rozwiazaniem jest dodanie dziekow i sprawdzenie, czy nie wychodza "poza skale". Jezeli wychodza to je przycinamy do skali (czyli dla 8bitow przycinamy do przedzialu 0..255)
    Nie robimy zadnego skalowania. Skalowanie bedzie "dzialac", ale spowoduje przyciszenie dzwieku, co jest niepoprawne i nieporzadane.
  • #4 1714083
    Zbych_
    Poziom 25  
    MirekCz napisał:

    Nie.
    Poprawnym rozwiazaniem jest dodanie dziekow i sprawdzenie, czy nie wychodza "poza skale". Jezeli wychodza to je przycinamy do skali (czyli dla 8bitow przycinamy do przedzialu 0..255)
    Nie robimy zadnego skalowania. Skalowanie bedzie "dzialac", ale spowoduje przyciszenie dzwieku, co jest niepoprawne i nieporzadane.


    Nie zgodzę się z tobą. Jeśli będziesz dla każdej sumy próbek 2 dzwięków decydował o tym, czy należy zrobić skalowanie to wprawadzasz nieliniowość do toru przetwarzania i do tego taką, która zmienia się w czasie. Co do przyciszania to oczywiście masz rację, jest to nieunikniony skutek skalowania. Ale jest to o tyle nieistone, że można to skorygować na wzmacniaczu końcowym. O wiele poważniejszym problemem jest w tym przypadku zmiejszenie rozdzielczości sygnału (z 8 do 7 bitów dla każdego z dwóch dźwięków), co objawi się wzrostem szumów w sygnale wyjściowym. Dlatego być może lepszym wyjściem jest zaprzęgnięcie do pracy dwóch przetworników D/A i analogowe zsumowanie sygnałów.
  • #5 1714897
    shg
    Poziom 35  
    Można też miksowanie zrobić w połowie sprzętowo, a w połowie programowo. Wystarczy na wejście DAC podawać oba sygnały naprzemiennie przełączane z częstotliwością 2 razy większą od częstotliwości próbkowania obu, a za wyjściem DAC wstawić filtr dolnoprzepustowy (jakiś o bardzo stromej charakterystyce) :] Ale to nie ma sensu, bo drugi DAC wyjdzie taniej, niż taki filtr.

    Koncept numer 2:
    Zwiększając częstotliwość próbkowania dwukrotnie możesz zmniejszyć ilość bitów o jeden, a uzystana jakość pozostanie taka sama.

    Wobec tego liczymy sumę obu dżwięków i przechowujemy ją jako dziewięciobitową.
    Odtwarzanie przeprowadzamy z częstotliwością dwa razy większą.
    Za pierwszym razem podajemy na wyjście osiem najstarszych bitów próbki
    Za drugim razem podajemy to samo, jeżeli najmniej znaczący bit (w próbce 9-cio bitowej) był równy 0, lub wartość zwiększoną o 1, jeżeli najmniej znaczący bit był równy 1

    Mogło by się wyydawać, że specjalnego traktowania wymaga tylko próbka zawierająca same jedynki, bo w wyniku dodawania mogło by wystąpić przepełnienie. Otóż nie, bo w wyniku sumowania dwóch ośmiobitowych liczb nie da się uzyskać wartości większej niż 510, a co za tym idzie - przepełnienie nigdy nie wystąpi.

    Na wyjściu oczywiście należy zastosować filtr dolnoprzepustowy, aby w wyniku uśredniania dwóch sąsiednich próbek uzyskać pożądaną rozdzielczość.
  • #6 1714978
    beatcomber
    Poziom 11  
    W takim razie może jeszcze lepiej zaprząc jeden 16-bitowy przetwornik i nie skalować sumy sygnałów?

    DAC0808 źle działał z mojej winy. Już to poprawiłem, ale symetryczne napięcie zasilające to bolączka :(

    Znalazłem inny przetwornik - TDA1543. Zapowiada się ciekawie: 16-bit, stereo, pojedyncze zasilanie +5V, niewielki (DIP8) i niska cena (5zł). Dane są wprowadzane w formacie I2S i tu mam znow do Was pytanie: czy ktoś miał już do czynienia z tym protokołem? Może macie przykładowe programy do obsługi (najlepiej w ASM)?

    Do SHG: pomysł z dwukrotnym zwiększeniem częstotliwości próbkowania wydaje się być ciekawy, ale czy nie da się tego zrobić prościej, własnie tak jak napisałem u góry?
  • #7 1715170
    Zbych_
    Poziom 25  
    beatcomber napisał:
    W takim razie może jeszcze lepiej zaprząc jeden 16-bitowy przetwornik i nie skalować sumy sygnałów?


    Oczywiście takie rozwiązanie jest najprostsze (wystarczy przetwornik >= 9-bit). Pisząc o zdublowaniu przetworników miałem na myśli sytuację, gdy i tak mamy kilka DACy w jednym układzie scalonym, albo wykorzystujemy PWMy procesora. W przypadku, gdy masz jeden przetwornik 8-bitowy to dokładanie drugiego byłoby bez sensu.
  • #8 1715239
    MirekCz
    Poziom 35  
    Zbych_ napisał:
    MirekCz napisał:

    Nie.
    Poprawnym rozwiazaniem jest dodanie dziekow i sprawdzenie, czy nie wychodza "poza skale". Jezeli wychodza to je przycinamy do skali (czyli dla 8bitow przycinamy do przedzialu 0..255)
    Nie robimy zadnego skalowania. Skalowanie bedzie "dzialac", ale spowoduje przyciszenie dzwieku, co jest niepoprawne i nieporzadane.


    Nie zgodzę się z tobą. Jeśli będziesz dla każdej sumy próbek 2 dzwięków decydował o tym, czy należy zrobić skalowanie to wprawadzasz nieliniowość do toru przetwarzania i do tego taką, która zmienia się w czasie. Co do przyciszania to oczywiście masz rację, jest to nieunikniony skutek skalowania. Ale jest to o tyle nieistone, że można to skorygować na wzmacniaczu końcowym. O wiele poważniejszym problemem jest w tym przypadku zmiejszenie rozdzielczości sygnału (z 8 do 7 bitów dla każdego z dwóch dźwięków), co objawi się wzrostem szumów w sygnale wyjściowym. Dlatego być może lepszym wyjściem jest zaprzęgnięcie do pracy dwóch przetworników D/A i analogowe zsumowanie sygnałów.


    Nie zrozumiales mnie.
    NIGDY nie robisz skalowania.
    Zawsze dodajesz tylko probki i przycinasz do mozliwych wartosci.

    To ja teraz mam ciekawe pytanie.

    Powiedzmy ze (czysto teoretycznie, nie znam sie na analogowym przetwarzaniu dzwieku) mamy dwa dzwieki do zsumowania, oba o wartosci 200.

    Skalujac mamy cos takiego 200/2+200/2=200;

    Robiac "moja" metoda dodawania i "ucinania" do pasma mamy 200+200=400 , 400>255 wiec wynik=255

    Robiac metoda dodawania analogowego (zakladajac ze napiecie wyjsciowe ma byc w przedziale 0-5V a wartosc 200 po DAC to ~4V)
    4V+4V=8V ? (przy maksymalnym napieciu przewidzianym 5V)

    Mozesz mi wytlumaczyc jak to ma dzialac? Czy moze wartosc analogowa tez mamy przeskaloawc? (co w sumie wychodzi na to samo co przeskalowanie wartosci cyfrowej, ale uzycie 9 bitowego przetwornika DAC)


    ja przerabialem cyfrowe dodawanie dzwieku w praktyce. Przy 8 kanalach takie "skalowanie" dzwieku doprowadzalo do tego, ze nawet po rozregulowaniu glosnosci na maksa dzwiek byl cichy (a do tego bylo sporo szumow).
    Dodawanie dzwieku i jego "przycinanie" (przy czym najpierw dodajesz je jako liczba 16bitowa a dopiero po zsumowaniu wszystkich sygnalow je przycinasz do 8bitowej wartosci) dawalo znakomite rezultaty. Po prostu gdy dzwieki staja sie takie, ze wychodza poza skale, to glosniki najwyrazniej daja ostro czadu i twoje ucho czy tak nie wylapie takich niuansow. Poza tym (jezeli nie nagrywales dzwiekow BARDZO, BARDZO glosno) to bardzo maly promil probek po zsumowaniu dochodzi do granicznej wartosci.
  • #9 1717932
    Zbych_
    Poziom 25  
    MirekCz napisał:

    NIGDY nie robisz skalowania.
    [...]
    Robiac "moja" metoda dodawania i "ucinania" do pasma mamy 200+200=400 , 400>255 wiec wynik=255


    To co proponujesz to naprostszy sposób na przesterowanie. Jak ktoś robi fuz do gitary to może jest to ok, ale na pewno nie przy odtwarzaniu mowy, muzyki itp.

    MirekCz napisał:

    Robiac metoda dodawania analogowego (zakladajac ze napiecie wyjsciowe ma byc w przedziale 0-5V a wartosc 200 po DAC to ~4V)
    4V+4V=8V ? (przy maksymalnym napieciu przewidzianym 5V)

    Oczywiście, że trzeba odpowiednio stłumić oba sygnały, tak żeby suma mieściła się w zakresie. Nie widzę w tym nic dziwnego/niezwykłego.

    MirekCz napisał:

    Mozesz mi wytlumaczyc jak to ma dzialac? Czy moze wartosc analogowa tez mamy przeskaloawc? (co w sumie wychodzi na to samo co przeskalowanie wartosci cyfrowej, ale uzycie 9 bitowego przetwornika DAC)

    Aplitudowo wychodzi to samo, ale jakościowa różnica jest duża (zwłaszcza przy niskich rozdzielczościach). Analogowe tłumienie nie powoduje zmniejszenia dynamiki/rozdzielczości sygnału (oczywiście w pewnych rozsądnych granicach wyznaczonych przez szumy).

    MirekCz napisał:

    ja przerabialem cyfrowe dodawanie dzwieku w praktyce. Przy 8 kanalach takie "skalowanie" dzwieku doprowadzalo do tego, ze nawet po rozregulowaniu glosnosci na maksa dzwiek byl cichy (a do tego bylo sporo szumow).

    A nie przyszło ci do głowy, żeby przygotować próbki z większą amplitudą sygnału ?

    MirekCz napisał:

    Dodawanie dzwieku i jego "przycinanie" (przy czym najpierw dodajesz je jako liczba 16bitowa a dopiero po zsumowaniu wszystkich sygnalow je przycinasz do 8bitowej wartosci) dawalo znakomite rezultaty. Po prostu gdy dzwieki staja się takie, ze wychodza poza skale, to glosniki najwyrazniej daja ostro czadu i twoje ucho czy tak nie wylapie takich niuansow. Poza tym (jezeli nie nagrywales dzwiekow BARDZO, BARDZO glosno) to bardzo maly promil probek po zsumowaniu dochodzi do granicznej wartosci

    Widzisz i tu dochodzimy do sedna sprawy. Ja tak nagrywam dźwięki, aby miały max. amplitudę pik-pik ok 90% zakresu. Aby odtworzyć dwa dźwięki bez przesterowań twoją metodą należałoby je tak nagrać, żeby ich sumaryczna amplituda nie przekraczała zakresu, czyli np. amplituda p-p każdego z nich była <50% zakresu. To w praktyce oznacza, że zostaną nagrane z rozdzielczością mniejszą o 1 bit. Przy rozdzielczości przetwornika 8-bitów oznacza to nagranie dzwięku z 7-bitową rozdzielczością, spadek jakości dzwięku będzie wyraźnie słyszalny.
    W mojej metodzie jeden dźwięk jestem w stanie odtworzyć z pełną dostępną rodzielczością (dopiero przy dwóch rozdzielczość każdego z nich spadnie o połowę). Oczywiście gdybym miał za dużo miejsca w pamięci to pewnie przechowywałbym dźwięki z rozdzielczością 16-bitową i nie zawracałbym sobie d... skalowaniem. Ale w tej chwili próbuję przy pomocy atmega8 jednocześnie ściągać i odtwarzać w tle głównej aplikacji dwa równoległe strumienie dźwiękowe pobierane z zewnętrznego dataflasha i ograniczenie ilości przepływających w ciągu sekundy danych jest dla mnie dość istotne.
  • #11 1718527
    MirekCz
    Poziom 35  
    Zbych_ napisał:
    MirekCz napisał:

    Mozesz mi wytlumaczyc jak to ma dzialac? Czy moze wartosc analogowa tez mamy przeskaloawc? (co w sumie wychodzi na to samo co przeskalowanie wartosci cyfrowej, ale uzycie 9 bitowego przetwornika DAC)

    Aplitudowo wychodzi to samo, ale jakościowa różnica jest duża (zwłaszcza przy niskich rozdzielczościach). Analogowe tłumienie nie powoduje zmniejszenia dynamiki/rozdzielczości sygnału (oczywiście w pewnych rozsądnych granicach wyznaczonych przez szumy).


    Nie wiem czy zauwazyles, ale mowie o 9bitowym DAC. Wiec rozdzielczosc jest dokladnie ta sama.
    W twojej metodzie zamiast uzywac 2x8bit DAC + dodawanie/skalowanie analogowe mozesz po prostu uzyc 9bitowy DAC a ten dodatkowy bit to reszta z dzielenia /2 sumy probek.
    Nie potrzeba zadnych dodatkowych danych z karty pamieci, dzwiek ma ta sama jakosc a uklad sie upraszcza.

    Czyli program musialby wygladac tak:

    -wczytanie bajtu z 1wavea
    -wczytanie bajtu z 2wavea
    -rejestr=bajt z 1 + bajt z 2
    -ror rejestr (obracamy rejestr w prawo, w rejestrze jest 8 najwazniejszych bitow, najmniej wazny jest jako carry flag)
    -wyrzuc rejestr na wyjscie do 8 najwazniejszych bitow DAC
    -wyrzuc "1" do najmniej waznego bitu DAC (dziewiatego)
    -brcs dalej (przeskok do "dalej" jezeli flaga carry=='1')
    -wyrzuc "0" do najmniej wanego bitu DAC (nie bylo przeskoku, wiec carry=="0"
    -etykieta dalej
    -koniec petli

    Chyba to prostsze niz 2xDAC + uklad analogowy?
  • #12 1720425
    Zbych_
    Poziom 25  
    MirekCz napisał:

    Nie wiem czy zauwazyles, ale mowie o 9bitowym DAC. Wiec rozdzielczosc jest dokladnie ta sama.

    Skoro sam to napisałem to pewnie zauważyłem.

    MirekCz napisał:

    W twojej metodzie zamiast uzywac 2x8bit DAC + dodawanie/skalowanie analogowe mozesz po prostu uzyc 9bitowy DAC a ten dodatkowy bit to reszta z dzielenia /2 sumy probek.

    Oczywiście, że prościej wziąć przetwornik 9-bitowy niż dwa 8-bitowe. No chyba, że masz dwa przetworniki 8-bitowe w jednym układzie scalonym, a nie masz pod ręką przetwornika >=9-bit (o tym też pisałem). Sytuacja wygląda trochę gorzej w przypadku wykorzystania PWMów w charakterze przetworników. Każde powiększenie rozdzielczości o 1 bit to dwukrotny spadek częstotliwości PWMa. W tym przypadku wykorzystanie 2xPWM 8-bit ma większy sens niż jednego PWMa 9-bit. Podobny myk był zastosowany w generatorze funkcyjnym, w którymś z ostanich numerów EP, albo EdW (tam przetwarzanie 8-bitowe było zrobione z dwóch PWMów 7-bitowych). A co do zaproponowanego przez ciebie sposobu uzyskania tego 9-bitu, to po kiego grzyba chcesz sumę dzielić i badać resztę, skoro dodanie swóch liczb 8-bitowych od razu daje wynik 9-bitowy.


    MirekCz napisał:

    Nie potrzeba zadnych dodatkowych danych z karty pamieci, dzwiek ma ta sama jakosc a uklad się upraszcza.

    Wiesz, nie każdy mały procesor ma tyle pamięci, żeby pomieścić > kilka sekund dźwięku próbkowanego kilka(naście) kHz.

    MirekCz napisał:

    Czyli program musialby wygladac tak:

    -wczytanie bajtu z 1wavea
    -wczytanie bajtu z 2wavea
    -rejestr=bajt z 1 + bajt z 2
    -ror rejestr (obracamy rejestr w prawo, w rejestrze jest 8 najwazniejszych bitow, najmniej wazny jest jako carry flag)
    -wyrzuc rejestr na wyjscie do 8 najwazniejszych bitow DAC
    -wyrzuc "1" do najmniej waznego bitu DAC (dziewiatego)
    -brcs dalej (przeskok do "dalej" jezeli flaga carry=='1')
    -wyrzuc "0" do najmniej wanego bitu DAC (nie bylo przeskoku, wiec carry=="0"
    -etykieta dalej
    -koniec petli


    A ja bym to zrobił tak:
    -wczytanie bajtu z 1wavea
    -wczytanie bajtu z 2wavea
    -rejestr=(rzutowanie na 16-bitów)(bajt z 1 + bajt z 2)

    Wynik jest od razu 9 bitowy. Niepotrzebne bity i tak zostaną zignorowane przez przetwornik D/A. Ten sposób jest chyba jeszcze prostszy ?
  • #13 1842704
    Jasiex
    Poziom 13  
    tak, naprościej to jest zostawić sobie LSB a odpowiednie nie mieszczące się w porcie wyjściowym bity MSB olać.
    Można też zastosować filtr podobny jaki stosuje się w uLaw (tam jest z 16 do 12 bitów).

    mniej więcej tak jak na rysunku:
  • #14 1842824
    Jasiex
    Poziom 13  
    przypomniała mi się jeszcze jedna rzecz, a mianowicie projekt PICSOUND w którym autor pokazuje jak zrobić szeregowy DAC.
    Wymagania niewielkie bo 4MHz PIC to 1Mips a i tak nie jest to w pełni wykorzystane.

    Jakość próbek można odsłuchać po pobraniu ze strony i według mnie nieodbiegają od 16bitowych, a jeśli jest jakaś różnica to w niektórych przypadkach niskie tony są mniej wzmocnione, ale to zjawisko można na etapie budowy preampa wyeliminować.

    pozdrawiam.

    tutaj jest link do picsound:
    http://centauri.ezy.net.au/~fastvid/picsound.htm
REKLAMA