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

Atmega32: Brak dźwięku w słuchawkach przy odtwarzaniu pliku WAV z karty SD

dirgon 11 Mar 2017 16:52 1110 13
REKLAMA
  • #1 16338279
    dirgon
    Poziom 9  
    Cześć,
    Napisałem program, który miał odtwarzać utwór z karty SD o nazwie o.wav . Program poprawie otwiera plik, jednak ze słuchawka nie wydaje dźwięku... Czy mógłby ktoś sprawdzić mój kod czy nie ma tam żadnego błędu ? Myślałem że same wyprowadzenie odczytanych wartości hex z pliku muzycznego i "wypuszczenie" ich na PWM w zupełności wystarczy, ale widocznie się myliłem. Mógłby ktoś mnie nakierować ? Bardzo proszę :>
    Projekt wykonywany na atmedze32

    Narazie nie zależy mi na tym żeby dźwięk był odtwarzany płynnie może być spowolniony (wiem ze powinienem korzystać z rezonatora). Chcę narazie uzyskać jakikolwiek dźwięk w słuchawce bo jak do tej pory to otrzymuje same piski i nic więcej.
    Nie odczytuje też nagłówka, ponieważ chce to zrobić potem wiem, że próbki są 8 bitowe mono, ponieważ sam ustawiałem te parametry.

    Schemat :
    Atmega32: Brak dźwięku w słuchawkach przy odtwarzaniu pliku WAV z karty SD
    Kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    Atmega32: Brak dźwięku w słuchawkach przy odtwarzaniu pliku WAV z karty SD
  • REKLAMA
  • #3 16342485
    trol.six
    Poziom 31  
    dirgon napisał:
    Myślałem że same wyprowadzenie odczytanych wartości hex z pliku muzycznego i "wypuszczenie" ich na PWM w zupełności wystarczy

    Mnie też tak się wydaje, że trzeba mieć właściwy format danych (signed lub unsigned) i wysyłać je na właściwie skonfigurowane PWM we właściwy sposób :)

    Przetestuj sobie na kilku tablicach sinusa umieszczonych bezpośrednio w mikrokontrolerze, czy w ogóle wyjście działa.

    Tutaj gubisz próbki:
    if(i>=253) {i= 0; read = 1; }
    To jest jakaś forma czytania z wyprzedzeniem?
    Może raczej coś w tym stylu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    ?
  • REKLAMA
  • #4 16342786
    dirgon
    Poziom 9  
    Chciałem zrobić tak ze jak odczytam wszystkie próbki z bufora to ustawiam zmienna read na 1 wtedy następuje wczytanie kolejnych próbek z pliku do bufora i znowu wysyłanie tych próbek na pwm. Możliwe jest to ze program nie działa bo za wolno procesor jest taktowany ? ( potrzebny zewnętrzny rezonator )

    Potem wypróbuje twój pomysł :)

    Wyjście działa tworzyłem plik txt z jedna liczba i sterowalem jasnością diody
  • #5 16343901
    trol.six
    Poziom 31  
    dirgon napisał:
    Chciałem zrobić tak ze jak odczytam wszystkie próbki z bufora to ustawiam zmienna read na 1 wtedy następuje wczytanie kolejnych próbek z pliku do bufora i znowu wysyłanie tych próbek na pwm

    W czasie 125us to raczej za wiele na tym nie odczytasz. :)

    Jeśli jesteś pewien że timery i odczyt z karty działa, to zrób sobie przebieg 8000/32 = 250Hz. Odczytaj wstępnie ze 20 bloków, a potem już więcej nie odczytuj. Niech sobie samo przerwanie działa z buforem.

    Jeśli usłyszysz te 250Hz, to się odczyt nie wyrabia, weź większy bufor, albo czytanie z wyprzedzeniem jeśli zadziała, albo więcej buforów.

    Jeśli nie usłyszysz, tzn coś masz jeszcze źle.

    Przecież szybkość odczytu możesz sobie sprawdzić na wiele sposobów. Poprzez zmiane stanu na pinie po odczycie, albo licząc w przerwaniu licznik do czasu odczytu. Tak samo częstotliwość atmegi, generując określoną częstotliwość.
  • #6 16344342
    nsvinc
    Poziom 35  
    Powyzsze kawalki kodu to proszenie sie o buffer underrun... i niezawodnie to nigdy dzialać nie będzie.
    Rozwiązaniem jest FIFO:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    To taki tylko szkic, ale mam nadzieje, ze pomocny...
    PS.
    return z maina w ktorym masz while(1) z ktorego nigdy nie wychodzisz, jest nieosiagalny - po co ci on...
  • #7 16344710
    trol.six
    Poziom 31  
    nsvinc napisał:
    Powyzsze kawalki kodu to proszenie sie o buffer underrun... i niezawodnie to nigdy dzialać nie będzie.
    Rozwiązaniem jest FIFO

    Każdy bufor cyklicznie odczytywany jest FIFO. Co za różnica czy będziemy mieli za szybki zapis do bufora czy za szybki z bufora? To jest audio, musi zapewnić ciągłość, teoretycznie nie możemy sobie go na chwile zatrzymać jak to czasem można zrealizować w innych sytuacjach, choć można taką ewentualność zaimplementować, zawsze to lepiej mieć zastoje w dźwięku niż coś nieokreślonego.

    Jak nam się program z buforami nie wyrabia trzeba go po prostu zwiększyć, albo dać ich więcej. Przede wszystkim liczy się czas odczytu z mediów zewnętrznych ;)
  • #8 16345036
    Badmaneq
    Poziom 23  
    Głośnik źle podłączony, dodatkowo powinien być podłączony przez kondesator np. 100 uF
  • REKLAMA
  • #9 16345317
    dirgon
    Poziom 9  
    Badmaneq napisał:
    Głośnik źle podłączony, dodatkowo powinien być podłączony przez kondesator np. 100 uF

    Dobra masz rację tam powinien być kondensator, ale ze słuchawki wychodzi jedynie pisk.... a nic podobnego nawet do dźwięku.

    nsvinc napisał:
    Rozwiązaniem jest FIFO:

    Zaimplementowałem twoją metodę jednak ciągle nic z tego.

    Wydaje mi się że to wszystko jest za wolne i się sypie... Zewnętrzny kwarc poprawi sytuację ??
  • #10 16345443
    Badmaneq
    Poziom 23  
    Miałem na myśli wyjście PWM do + kondesatora, - kondesatora do jednego z końcówki głośniczka. Druga końcówka głośniczka do masy.
  • #11 16345740
    dirgon
    Poziom 9  
    Badmaneq napisał:
    Miałem na myśli wyjście PWM do + kondesatora, - kondesatora do jednego z końcówki głośniczka. Druga końcówka głośniczka do masy.

    Zapomniałem GND dorysować na schemacie- mój błąd edytowałem już post. Dodałem również kondensatory jednak nic nie poprawiły...
  • REKLAMA
  • #12 16345881
    nsvinc
    Poziom 35  
    upewnij sie ze na pinie procka faktycznie jest cos, co przypomina PWM. Zamiast sluchawek podlacz przez rezystor LEDa i odpal nastepujacy kod:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Jasność LEDa powinna się zmieniać z 0 do max i spowrotem z taktem 0.4Hz. Jeśli tak, to PWM działa, nastepnie przywróć słuchawki, i zmien kod w przerwaniu na:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    w słuchawkach powinienes uslyszec raczej niemiły dla ucha 'trójkątny' dzwienk 500Hz.
    Jesli bzyczy, to twoj mechanizm odczytujący dane z karty nie działa.
    A jesli nie bzyczy, to PWM nie działa jak powinien...

    Swoją drogą, ten caly patent to generalnie lipa; i żeby konstrukcja nabrała sensu potrzebujesz PWMa wpuścić na filtr dolnoprzepustowy (chociazby RC) a sygnał zza filtra na jakąś końcówkę 'mocy' (LM386?)
  • #13 16346055
    dirgon
    Poziom 9  
    nsvinc napisał:
    Jesli bzyczy, to twoj mechanizm odczytujący dane z karty nie działa.
    A jesli nie bzyczy, to PWM nie działa jak powinien...

    Na samym początku dziękuje za zaangażowanie :>. dioda działa tak jak powinna, bzyczy więc niby powinno być źle po stronie odczytu z karty, ale on działa bo jeśli użyję go w taki sposób (zakładając ze w pliku który odczytuje znajduje się jedna liczba np 7 ) :
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    to zadziała....
    Domyślasz się w czym może tkwić problem ?
  • #14 16346168
    nsvinc
    Poziom 35  
    zrob prosty test: wygeneruj plik w ktorym bedzie w kółko ta sama sekwencja:
    0,32,64,96,128,160,192,255,192,160,...,0,32,64,...,255,192,... i niech to sie powtorzy rowno 128 razy (=2 sektory na karcie)... i spróbuj odtwarzać to z karty. Powinno byc identyczne bzyczenie 500Hz.
    Nigdzie nie masz obsługi EOF. nie znam tej biblioteki do systemu plikow z ktorej korzystasz, ale musisz obslugiwac EOF, i jak na niego trafisz, to wracasz na poczatek pliku (cos w smaku fseek(0)?). pf_read() znając zycie zwraca ile bajtow z pliku odczytal, wiec fillfifo() powinna wygladac tak:
    Kod: text
    Zaloguj się, aby zobaczyć kod
REKLAMA