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

Jak przesłać plik WAV (8KHz, 8bit, mono) przez UART i odtworzyć przez PWM?

zabex 06 Mar 2012 00:05 3001 19
  • #1 10639701
    zabex
    Poziom 22  
    Witam. Czy jest może na sali osoba która pomogła by mi w zrozumieniu jak przesłać prawidłowo plik wav (8KHz, 8bits, mono) poprzez UART i odtworzenie go za pomocą PWM?
    Na początek próbowałem w ten sposób:

    Kod: text
    Zaloguj się, aby zobaczyć kod

    ...ale oczywiście słychać tylko "pierdzenie".
    Będę wdzięczny za podanie przykładowego kodu programu (Bascom) i ewentualne wytłumaczenie co się w nim znajduje. Pozdrawiam.
  • #2 10639712
    Zocha24
    Poziom 21  
    Zwróć uwagę na prędkość przesyłu danych uartem
  • #3 10639720
    mirekk36
    Poziom 42  
    Biorąc pod uwagę twój przykład kodu na "pierdzenie" jak sam powiedziałeś, widać, że ty najpierw musisz zacząć od takich podstaw jak:

    1. obsługa timerów sprzętowych
    2. obsługa UART na przerwaniach
    3. obsługa buforów cyklicznych (FIFO)

    i jeszcze kilka innych - a dopiero potem myśleć o tym celu. Tak mi z tego wynika.
  • #4 10643880
    zabex
    Poziom 22  
    Pomęczyłem się trochę dzisiaj i chciałbym zapytać czy w dobrym kierunku idę.
    Poniżej dwa przykłady oraz próbki tego co uzyskałem. Przepraszam za jakość dźwięku. Niestety byłem zmuszony nagrać to przez mikrofon.

    Kod 1:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Kod 2:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    I teraz mam kilka pytań.
    1. Czy prawidłowo wyliczyłem częstotliwość próbkowania około 8KHz?
    2. Którego rozwiązania się trzymać?
    3. Jak się obsługuje FIFO w Bascom-ie?
    4. Prędkość odtwarzania dźwięków nie jest prawidłowa. Jak sobie z tym radzić?
    5. W przykładzie 1.mp3 na początku słychać czysty dźwięk (poza trzaskiem) po czym zaczyna się robić kaszana. Czy to ma związek z przepełnieniem bufora?

    W załącznikach dźwięk otrzymany z poszczególnych kodów.
  • #5 10644002
    gaskoin
    Poziom 38  
    zabex napisał:

    I teraz mam kilka pytań.
    1. Czy prawidłowo wyliczyłem częstotliwość próbkowania około 8KHz?


    Nie, ale o tym dalej.

    zabex napisał:

    4. Prędkość odtwarzania dźwięków nie jest prawidłowa. Jak sobie z tym radzić?


    wolniej podawać próbki przez pwm (stąd odp do pkt 1), lub ich nie gubić :)

    zabex napisał:

    5. W przykładzie 1.mp3 na początku słychać czysty dźwięk (poza trzaskiem) po czym zaczyna się robić kaszana. Czy to ma związek z przepełnieniem bufora?


    gubisz waść próbki gdzieś
  • #6 10644231
    mirekk36
    Poziom 42  
    gaskoin napisał:

    gubisz waść próbki gdzieś


    Nie gdzieś tylko w tych dwóch kodach, i to bardzo mocno gubisz ..... A dlaczego? No nie dziwne, żadnego śladu buforowania.

    1. robisz bufor cykliczny (FIFO)
    2. do bufora odbierasz dane przez RS232 na przerwaniach
    3. z bufora (FIFO) odczytujesz w przerwaniu timera o zadanej częstotliwości próbkowania dane

    to wystarczy.
  • #7 10644262
    zabex
    Poziom 22  
    Myślałem, że za buforowanie odpowiada:
    Config Serialin = Buffered , Size = 255


    No nic... W takim razie zabieram się za poszukiwanie informacji odnośnie FIFO i jak to robić w Bascom-ie.
  • #8 10644375
    mirekk36
    Poziom 42  
    Oooops! sorki nie zauważyłem tej linii Config serialin - a masz rację to jest buforowanie sprzętowe w bascomie i to buforki cykliczne ....

    Spróbuj może z dużo większym buforem niż 255 bajtów - masz przecież w m32 sporo RAM'u
  • #9 10645619
    Longos
    Poziom 12  
    A nie wystarczy przesyłać dane z prędkością 56kbps ? Wówczas wychodzi z tego 7k bajtów/s czyli całkiem wysoka częstotliwość próbkowania. Dane z RS prosto na rejestr PWM i po sprawie.
  • #10 10645666
    snnaap
    Poziom 25  
    Longos napisał:
    A nie wystarczy przesyłać dane z prędkością 56kbps ? Wówczas wychodzi z tego 7k bajtów/s czyli całkiem wysoka częstotliwość próbkowania. Dane z RS prosto na rejestr PWM i po sprawie.


    Stracisz synchronizację.
  • #11 10645715
    zabex
    Poziom 22  
    Dane odbierane przez USART tak jak pisze kol. mirekk36 muszę buforować. Niestety mam taki mętlik w głowie, że nie wiem jak wykorzystać do tego RAM procesora. Szukam, czytam i chyba mnie to przerasta. Niby zwykłe buforowanie...
    Może ktoś mógłby wyjaśnić jak buforować dane większe od 256 bajtów?
  • #12 10645742
    snnaap
    Poziom 25  
    Nie wiem jak robi to kolega mirekk36 i z chęciom chciałby się dowiedzieć tak z ciekawości ale ja zrobiłbym to na tablicy N - elementowej gdzie N to wielkość twojego bufora.
    Dane z RS wpadają do kolejnych elementów tablicy przy czym indeksem tablicy jest np zmienna "i". Każdy zapis do tablicy zwiększa indeks "i'. Po zapełnieniu całej tablicy nadpisujesz dane od początku.

    Kolejny indeks do tej samej tablicy to np zmienna 'j' z indeksu tego korzysta uK aby odczytać dane z tablicy. I tak samo jak w przypadku zapisywania po odczytaniu ostatniego elementu zaczynasz czytać tablicę od początku.
  • #13 10648001
    zabex
    Poziom 22  
    Zrobiłem bufor na tablicy i oto co wyszło:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Jak widać i słychać podczas prawidłowego próbkowania dane do bufora są szybciej ładowane niż odczytywane a więc aby prawidłowo odtworzyć cały utwór bufor musiał by pomieścić znaczną część jeśli nie całość wysyłanego pliku.
    Jedyne co przychodzi mi do głowy to buforować zawartość UART w jakiejś pamięci zewnętrznej. Bo chyba w ten sposób już nic więcej nie wycisnę. No chyba, że ktoś ma na to jakiś inny sposób. Kompilator nie pozwala mi na zwiększenie bufora powyżej 2026. Nawet zmiana wielkości stosów niewiele zmienia.
    Tak siedzę i kombinuje czy jest może jakaś funkcja (procedura) która pozwala na zatrzymanie transmisji RS232 od strony UART. Chodzi mi o to żeby zatrzymać odbieranie danych do czasu kiedy bufor programowy zostanie zwolniony bez utraty danych wysyłanych przez RS232. Coś mi się wydaje, że za dużo wymagam ale może ktoś ma jakiś pomysł?
  • Pomocny post
    #14 10648937
    mirekk36
    Poziom 42  
    No tak na marginesie to bardzo ciekawy efekt ci wyszedł ;)

    A na poważnie to działasz na ATmega32 więc jak możesz próbować nawet tworzyć bufor w RAM o rozmiarze 2026 ??? nie wspominając o większym - skoro cały RAM tego procka to 2kB. Zastanowiłeś się nad tym?

    hmmm widzisz tutaj twoim problemem jest na razie prawidłowe zorganizowanie binarnej transmisji po RS232 i to powinieneś poćwiczyć.....

    Bufor FIFO musi tak działać, że PC pcha do niego dotąd dokąd jest w nim miejsce (trzeba to sprawdzać w procku) natomiast procedura przerwania musi pobierać tylko dane w kolejności w jakiej przyszły i tylko jeśli są .... chociaż w tym projekcie to jest właśnie priorytet.

    Tymczasem ty na razie wykorzystałeś bufor ale go nie kontrolujesz w żaden sposób. Czyli pchasz na siłę ile wlezie - a że jest on cykliczny do pewnie dochodzi do nadpisywania danych i stąd te efekty.
  • #15 10648966
    zabex
    Poziom 22  
    mirekk36 napisał:
    No tak na marginesie to bardzo ciekawy efekt ci wyszedł ;)

    A na poważnie to działasz na ATmega32 więc jak możesz próbować nawet tworzyć bufor w RAM o rozmiarze 2026 ??? nie wspominając o większym - skoro cały RAM tego procka to 2kB. Zastanowiłeś się nad tym?

    Rany julek, teraz dopiero zdałem sobie sprawę z tego co próbowałem "na siłę" zrobić.

    Z tym buforem chyba długo jeszcze się będę męczył. Nie bardzo potrafię sobie wyobrazić jak procesor może "zablokować" (wstrzymać) wysyłanie danych przez RS232 do bufora UART w momencie kiedy jest pełny. Nigdzie się na to nie natknąłem.

    Teraz też zdałem sobie sprawę, że... Skoro $baud mam ustawione na 115200 to czy czasami nie powinienem wysyłać pliku wav 11.520 SR (sample rate) zamiast 8000? Coś mi mówi, że w takim wypadku mogę wykorzystać sprzętowy bufor cykliczny bo i tak prędkość wysyłanych danych będzie zgodna z SR pliku wav. Dobrze myślę?

    ---------------------------------------------------
    Niestety pomysł nie wypalił. Niby jest lepiej ale to tylko odkładanie "kaszany" w czasie.
    Jak kontrolować przesyłanie danych do bufora? Jak wstrzymać przesyłanie bez ich utraty? Będę wdzięczny za jakąkolwiek pomoc z tymi buforami w Bascom-ie.
  • #17 10650196
    zabex
    Poziom 22  
    RS-232 Transceiver Cezarego Zielińskiego. Nic innego nie chce u mnie dobrze działać np Terminal v1.9 zachowuje się jak by wysyłał kilka bajtów na sekundę. Przy poruszaniu myszką kilkanaście. Bascom-owy terminal robi tylko "pyk" i koniec.
  • Pomocny post
    #18 10650264
    snnaap
    Poziom 25  
    Musisz sterować linią CTS nic innego Ci nie pozostało. Po wykryciu, że bufor się zapełnia i istnieje ryzyko nadpisania należy sprzętowo wstrzymać nadawanie przez terminal.

    Wymagana jest pełna przejściówka.

    PS na jakiej podstawie ustalasz częstotliwość próbkowania? Wysyłasz oryginalny plik WAV czy jakoś modyfikowany? Wykorzystujesz nagłówek pliku?
    Mono czy stereo?
  • #19 10650429
    mpo
    Poziom 12  
    snnaap napisał:
    Musisz sterować linią CTS nic innego Ci nie pozostało. ...

    A może Xon/Xoff ?
    Nie wiem tylko czy bascom ma standardowo obsługę tego protokołu.
  • #20 10650926
    zabex
    Poziom 22  
    Udało się osiągnąć zamierzony cel :)

    Plik wav - 11,025KHz, 8 bitów, mono, PCM
    Prędkość transmisji - 115200
    Bufor - sprzętowy UART 255 bajtów
    Program transmitujący - Real Term
    Jak przesłać plik WAV (8KHz, 8bit, mono) przez UART i odtworzyć przez PWM?
    Tak jak koledzy pisali wcześniej nie można pchać na siłę danych do bufora bo prędzej czy później dojdzie do nadpisania próbek. Program Real Term kontroluje przesyłanie danych do bufora UART tak aby go nie przepełnić inaczej wiadomo "kaszana" ;)
    Oczywiście nie zmienia to faktu, że muszę jeszcze poćwiczyć i poświęcić sporo czasu na kontrolowanie tego co, gdzie i kiedy znajduje się w buforze. Np aby do tego co jest, zrobić jakiś mały pogłos.
    Kontynuując temat prosiłbym o wyjaśnienie jak i czy w ogóle da się kontrolować przesyłanie danych po RS232 z poziomu Bascom-a, a póki co dziękuję wszystkim za pomoc. :)

    P.S. W załączniku nagrany utworek poprzez line-in.
    Modyfikacje:
    - konwersja pliku do wav
    - wycięcie początku i końca danych w celu eliminacji zakłóceń wynikających z rozpoczęcia i zakończenia transmisji
    - pominięcie nagłówka pliku.
REKLAMA