Hallo, es gibt zwar viele ähnlich Projekte aber keine haben mich weiter gebracht. Ich lese mit meinem STM32(wird bei jedem uC mit DAC ähnlich sein) ein 16bit wave (RAW) file ein. Der DMA übergibt 12 MSBit in das DAC Register und mittels Timer trigger welcher auf 48kHz läuft wird der 12bit Wert in das Ausgaberegister gegeben. Alles wie im Handbuch, aber es klingt eher nach Weltraumgeräuschen, als nach meinem Audiofile... Jetzt meine Fragen: - ist es Richtig den Trigger timer, welcher die 12bit in das Ausgaberegister schiebt auf der Samplingrate der Audiofiles laufen zu lassen, also 48kHz in diesem Fall - Kann man überhaupt den Lautsprecher, von eine Audiogrußkarte, direkt an den DAC und die andere Seite auf GND anschließen - hat das 16bit wave file, welches ich mit audacity exportiert habe, plus und minus? - kann ich das wavefile in ein uint16 array einlesen oder muss es in ein int16?
Gendo I. schrieb: > - Kann man überhaupt den Lautsprecher, von eine Audiogrußkarte, direkt > an den DAC und die andere Seite auf GND anschließen man kann fast ALLES überall anschliessen, ob ein Ton rauskommt steht auf einem anderen Blatt. https://etel-tuning.eu/486-thickbox_default/adapter-drehstrom-auf-gardena.jpg Gendo I. schrieb: > - hat das 16bit wave file, welches ich mit audacity exportiert habe, > plus und minus? schau mit einem HEXmonitor rein, bzw dekodiere die Werte denn deine Einstellungen kenne ich nicht. https://www2.ak.tu-berlin.de/~fhein/Alias/Studio/ProTools/audio-formate/wav/overview.html
Gendo I. schrieb: > - Kann man überhaupt den Lautsprecher, von eine Audiogrußkarte, direkt > an den DAC und die andere Seite auf GND anschließen Witzbold!
Gendo I. schrieb: > hat das 16bit wave file, welches ich mit audacity exportiert habe, plus > und minus? - kann ich das wavefile in ein uint16 array einlesen oder > muss es in ein int16? Es hat Plus und Minus, daher signed. Für die Ausgabe muss es noch nach oben geschoben werden. int16_t array[LAENGE] ausgabe = ((int32_t)array[position] + 32768L) >> 4 mfg mf
minifloat schrieb: > Es hat Plus und Minus, daher signed. ich habe auch schon anderes gesehen, OK hat dann einen DC Pegel der aber oft durch Koppelkondensatoren auch getrennt wird, nur eben nicht überall.
Gendo I. schrieb: > - Kann man überhaupt den Lautsprecher, von eine Audiogrußkarte, direkt > an den DAC und die andere Seite auf GND anschließen Ja. Wobei ein Kondensator als DC-Blocker und ggf. ein kleiner Vorwiderstand (ca. 10 bis 50 Ohm) nicht schaden: http://elm-chan.org/works/sd8p/rc/sd8p_mo.png http://elm-chan.org/works/mxb/mg.png
Es gibt einen Unterschied zwischen einem DAC-Ausgang und einem Attiny Port Pin. Finde Ihn!
Gendo I. schrieb: > Jetzt meine Fragen: > > - ist es Richtig den Trigger timer, welcher die 12bit in das > Ausgaberegister schiebt auf der Samplingrate der Audiofiles laufen zu > lassen, also 48kHz in diesem Fall Ja. > - Kann man überhaupt den Lautsprecher, von eine Audiogrußkarte, direkt > an den DAC und die andere Seite auf GND anschließen Wird halt nicht laut. > - hat das 16bit wave file, welches ich mit audacity exportiert habe, > plus und minus? - kann ich das wavefile in ein uint16 array einlesen > oder muss es in ein int16? Ja. Es muss 2048 addiert werden nach der Umwandlung in 12 bit.
Gendo I. schrieb: > Der DMA übergibt 12 MSBit in das DAC Register > und mittels Timer trigger welcher auf 48kHz läuft wird der 12bit Wert in > das Ausgaberegister gegeben. wundert mich auch was der Tiny da soll!
Pass aber auf das beim 16bit auf 12bit wandeln das vorzeigen noch passt, sonst klingt das nicht so gut.
Gendo I. schrieb: > - hat das 16bit wave file, welches ich mit audacity exportiert habe, > plus und minus? Ja, mein Lieber, da bist du bereits auf der richtigen Spur. Also wirf mal nen Blick in die Definitionen zu .wav Dateien und dann ins Manual zu dem DAC in deinem µC. +/-32 K versus (0..4095)<<irgendwas. Du müßtest deiner DMA das Rechnen mit Offsets beibringen.. ;-) W.S.
Hallo Gendo, das Problem hatte ich auch schon. Zwar mit einem anderen Controller, aber gleiche Anwendung. Das Problem ist, dass die Byteorder von deinen 16bit Werten im File anders ist, als du das für deinen DAC vielleicht erwartest. Du musst das High- und Lowbyte drehen. Natürlich zusätzlich zu den signed- und unsigned-, Offset- usw Geschichten. Grüße, Jens
Bevor man durch falsche Umwandlungen auf 12 Bit die lustigsten Fehler erzeugt, sollte man mal die Hardware testen. Vorschlag: erzeuge ein Sinussignal mit z.B. 400Hz und schau mal mit dem Oszi, ob das Signal auch so aus dem DAC Ausgang kommt. Danach teste deinen High End Woofer und erst dann lass dein Wavefile auf die arme CPU los. Grüsse
Falls du *.wav Dateien verwendest: Das sind keine RAW Files, sondern Container in denen alles Mögliche drin sein kann, genauer gesagt RIFF Streams.
Mark S. schrieb: > Es gibt einen Unterschied zwischen einem DAC-Ausgang und einem Attiny > Port Pin. Finde Ihn! Beim Tiny wird in den verlinkten Schaltplänen die High-Speed-PWM (64 MHz) genommen. Von der Taktfrequenz bleiben am Ausgang 250 kHz über. Ob ich den DAC-Ausgang des STM32 oder den schnellen PWM-Ausgang des Tiny verwende, spielt für einen Lautsprecher kein Rolle. Ich muß dafür sorgen, das mit dem Sampletakt die Daten an der richtigen Stelle abgeladen werden, um am Ausgang eine 'analoge' Waveform zu bekommen. Wo ist jetzt für die eigentliche Anwendung (=Soundausgabe) der Unterschied? Gebhard R. schrieb: > Vorschlag: erzeuge ein > Sinussignal mit z.B. 400Hz und schau mal mit dem Oszi, ob das Signal > auch so aus dem DAC Ausgang kommt. Gute Idee! Man kann sich auch direkt im Controller einen Sägezahn erzeugen (einfacher Zähler). Damit kann man feststellen, ob die Soundausgabe oder Byteorder bzw. Offset das Problem sind.
Hallo Hobbys und Profis, LOL Troll.. und dann noch als Gast einloggen. Ja wie jeder hier mit Arbeit und Familie komme ich zu meinem Hobby nur ab und zu am Wochenende. Schade, dass du das nicht kennst. Zum zweiten. Ich weis sehr wohl, dass ein DAC keine Push/Pull Stufe ist. Die Frage bezog sich eher darauf, ob man vielleicht ein Spannungsteiler braucht. Laut genug für einen Testaufbau ist es, wenn es mal gehen sollte natürlich dann an einen Vorverstärker und an eine Endstufe. Na gut. An alle anderen vielen Dank für die Ideen. Ich habe mir eine Schleife programmiert, da es aber immer noch nicht richtig funktioniert. Alle Varianten hier rumprobiert, leider ohne Erfolg. :( Ein Sinusarray etc. hab ich alles schon ausgegeben und mit dem Oszi aufgenommen, dass geht ja alles. Das ist ja extrem einfach. const uint16_t sine_wave_array[32] = {2047, 1648, 1264, 910, 600, 345, 156, 39, 0, 39, 156, 345, 600, 910, 1264, 1648, 2048, 2447, 2831, 3185, 3495, 3750, 3939, 4056, 4095, 4056, 3939, 3750, 3495, 3185, 2831, 2447}; HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*) sine_wave_array, 32, DAC_ALIGN_12B_R ); HAL_TIM_Base_Start(&htim6); Deshalb verstehe ich das Problem mit dem wave file nicht. int16_t DAC_Buff[512]; // Der array 512 /* ##### Hier die der Ausschnitt wo ich eure ganzen Ideen und Vorschläge ausprobiert habe #### */ f_read (&file,&DAC_Buff[0],512,&cnt); //beider 256 Buffer befüllen for(uint16_t n=0; n<512;n++) { temp=((int32_t)DAC_Buff[n]+2048)>>4; // offset auf array /* ##### high und low byte tauschen #### */ t1=temp&0xff00; t2=temp&0xff; temp=(t2<<8)+(t1>>8); DAC_Buff[n]=temp; // Berechneten Wert zurück in Array schreiben temp=0; // temporären Variable löschen } Dann nur noch den DAC DMA und den Trigger Timer starten und los geht's. HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*) DAC_Buff, 512, DAC_ALIGN_12B_R ); HAL_TIM_Base_Start(&htim6);
Jens W. schrieb: > Hallo Gendo, > > das Problem hatte ich auch schon. > Zwar mit einem anderen Controller, aber gleiche Anwendung. > > Das Problem ist, dass die Byteorder von deinen 16bit Werten im File > anders ist, als du das für deinen DAC vielleicht erwartest. > Du musst das High- und Lowbyte drehen. > > Natürlich zusätzlich zu den signed- und unsigned-, Offset- usw > Geschichten. > > Grüße, Jens Das mit High- und Lowbyte drehen hab ich jetzt mal probiert, nur wir das mit dem signed- und unsigned-, Offset- usw noch nicht richtig sein. Klingt immer noch komisch :D
Im Anhang mal 1 Sekunde 600 Hz mit -1 dB ohne stoerende Header. Viel Spass.
Vielen Dank :) Da kann ich das schon mal als Fehlerquelle ausschließen und noch mal die Register prüfen.
Dummbeutel schrieb: > Im Anhang mal 1 Sekunde 600 Hz mit -1 dB ohne stoerende Header. > > Viel Spass. Um den DMA auszuschließen und debuggen zu können, habe ich jetzt mal das RAW File manuell in das DAC hold Register geschoben. Die oberen 12bit landen auch wie gewollt mit TIM6 trigger im DOR1 Register. Leider klingt es immer noch nicht. Daher habe ich mit das ganze mal im Oszi angeschaut. Es kommen immer nur 8 Werte und dann immer low, dann wieder 8 Werte. Siehe Anhang. Woher könnte das kommen? Ist mein DMA zu langsam der den File Stream bedient? res = f_open( &file, FileName, FA_READ ); //file oeffnen if(res) return 1; TIM6->CR1 |= TIM_CR1_CEN; while(1) { f_read (&file,&DAC_Buff[0],512,&cnt); //beider 256 Buffer befüllen if(cnt<256)break; for(uint16_t n=0; n<512;n++) { // temp=((uint32_t)DAC_Buff[n]+0xFF); // // t1=temp&0xff00; // t2=temp&0xff; // temp=(t2<<8)+(t1>>8); // // DAC_Buff[n]=temp; // temp=0; DAC1->DHR12L1 = (DAC_Buff[n]); while(0== LL_TIM_IsActiveFlag_UPDATE(TIM6)); } } TIM6->CR1 &= ~TIM_CR1_CEN; f_close(&file);
Hab es noch mal mit der normalen DMA Funktion probiert. Jetzt habe ich ein 600MH z Funktion, aber in 4x 128byte Blöcken und aller 3Blöcken fehlt einer und die 3 die kommen sind unter einander vertauscht. Also 1 und 3 gehören zusammen. Das kann man an dem Signalverlauf sehen. Siehe Anhang. Ich weiß nicht wo das mit den 128byte her kommt.
Kann ein Moderator vielleicht bitte mal den Titel korrigieren? Das ist ja widerlich.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.