Hallo, ich möchte diverse Audiosamples über den internen DAC des XMEGA auf Lautsprecher ausgeben lassen. Dies funktioniert grundlegend auch Problemlos, die Ausgabe erfolgt durch einen doubleduffered DMA-Transfer aus zwei 256 Bytes großen Buffern. Potentiell mehrere gleichzeitig abzuspielende Samples werden einfach addiert, da ich ledichglich 8 Bit Unsigned 1 kHz WAV Daten vorliegen habe ist dies kein Problem. Leider habe ich am Anfang und am Ende von Samples immer ein "ploppen". Ich vermutete dies liegt daran, dass ich, sobald keine Samples mehr abgespielt werden sollen auf den Wert 0 wechselte. Mittlerweile halte ich den letzten Datenwert welcher gesendet wurde um keinen Impuls auf den Lautsprecher zu geben, das "ploppen" ist jedoch immernoch da. Hat jemand eine Idee woran das liegen könnte? An hilfreichen anderen Threads habe ich nur Beitrag "Mischen von digitalen Sounds" gefunden. Dies nutzt mir allerdings auch nichts, da das digitale Mischen meiner Meinung nach nicht das Problem darstellt bzw meine Methode dort auch genannt wird. Grüße Fridolin
Wenn du den Wert hältst, würde theoretisch eine Gleichspannung am Lautsprecher stehen, was aber von der Endstufe verhindert wird. Die zieht dann also den Ausgangspegel auch auf Null, was möglicherweise der Grund dafür ist, warum es immer noch "ploppt". Abgesehen davon nutzt dir deine Methode für den Sprung am Beginn des Samples auch nichts. Versuch doch mal, eine Art Rampe von Null auf den ersten Wert bzw. vom letzten Wert auf Null zurück zu fahren (sprich: eine Art Fade-In bzw. Fade-Out).
So etwas ähnliches hatte ich tatsächlich schon probiert, allerdings war die Abstufung gelinde gesagt ziemlich schwach. Ich habe den vorangehenden Wert immer weiter halbiert. Möglicherweise war dies deutlich zu schnell, ich werde dies morgen erneut versuchen mit einer schwächeren Abstufung. Für das Fade-In hatte ich mir ausgerechnet, dass dies etwa 20 Milisekunden dauern kann im Worst-Case was negativ jedoch wäre jedoch noch möglich wenn nötig. Dieses Faden habe ich nicht weiters verfolgt, da ich dasselbe Problem auch habe wenn ich Sample A spiele und direkt danach Sample B abspiele; müsste ich hier logisch gesehen dann auch ein Crossfade machen? Beziehungsweise müsste ich korrekterweise eigentlich jedes Sample von 0 bis Anfangswert einfaden und dann von Endwert bis 0 wieder ausfaden?
schalte mal den DAC nach dem sample auf den halben wert also 127
Klar. :) Fade-In bzw. Fade-Out von/nach 127, das ist ja auch logisch. Man muss nur erstmal drauf kommen.
Die Audiosamples sollten in einem Format vorliegen, in dem kein Signal der halben DAC-Auflösung entspricht. Wird also nichts wiedergegeben, soll der DAC VRef/2 ausgeben. Dies muss auch beim Addieren/Subtrahieren von Signalen berücksichtigt werden. Beim Einschalten des Controllers wird der DAC über eine Rampe auf VRef/2 gefahren, um den Einschaltplopp zu minimieren. Das ausgegebene Signal wird letztendlich über einen Tiefpass und einen (ungepolten) Kondensator ausgekoppelt, um mit Verstärkern weiterverarbeitet werden zu können.
Oh mir fällt gerade auf, dass ich im Eingangspost einen Fehler habe; anstatt 1kHz nutze ich 11 kHz. Das Fade-In/Out nach 127 habe ich bereits probiert und es hat leider nicht zum Erfolg geführt. Seltsamerweise wird das "ploppen" übrigens dann verzögert, wenn ich den letzten Wert des Soundsamples noch eine Weile "halte". Dieser Wert ist z.B. 0x82 (130) hat also eine Abweichung von 3 zu 127. Meine Fade-Out Implementierung muss einen Fehler haben, hier mal der Quellcode davon:
1 | #define FADEVAL 1100 |
2 | #define NOTHINGVAL 0x82//127//2048 |
3 | |
4 | if (cnt > 0) { |
5 | /*val /=cnt;*/ |
6 | fadedown = FADEVAL; |
7 | } else { |
8 | #if 0 |
9 | if (fadedown > 0) { |
10 | fadedown--; |
11 | } else { |
12 | if (lastval > NOTHINGVAL) lastval--; else if (lastval < NOTHINGVAL) lastval++; |
13 | fadedown=FADEVAL; |
14 | } |
15 | val = lastval; |
16 | #else |
17 | val = 0x82; |
18 | #endif |
19 | } |
20 | lastval = val; |
fadedown, lastval und val sind alles uint16_t. lastval und fadedown sind static. Der Buffer wird in der Mainloop gefüttert, weshalb ein volatile nicht nötig ist. FADEVAL ist der Verzögerungswert in Samples für die Fade-Funktion. lastval ist immer der zuletzt gesetzte Wert für den DAC, val ist der Wert welcher genau nach diesem Code in den Buffer für den DAC geschrieben wird. NOTHINGVAL ist der Wert für die Stille, also wenn kein Sound abgespielt werden soll; diesem wird sich langsam angenähert. Das if/else/endif vom Preprozessor ist die Stelle die mich stutzig machte: bei if 1 "ploppt" es, bei if 0 nicht. Eigentlich sollte bei if 1 ja aber auch nichts passieren, da lastval ja bereits == NOTHINGVAL ist. @travelrec: der DAV hat 12 Bit, also müsste ich dann die 2048 nehmen anstatt der 127? Des weiteren zu deiner Ausgangsbeschaltung: bisher habe ich nichts weiter als direkt den Klinkenstecker der Aktiv-Boxen beschaltet. Wozu benötige ich den Tiefpass und was für Werte sollten die Kondensatoren und der Widerstand haben? Eim weiterer eventuell systematischer Fehler ist mir aufgefallen, was daran liegt, dass mir nicht ganz klar ist, was diese 8bit unsigned PCM Daten genau bededeuten. Wenn diese, wovon ich ausgehe, die "Wellenform sind, wobei 127 der Nullwert ist, so ist meine schlichte Addition insofern problematisch, da Werte < 127 sich beim addieren vergrößern und nicht verkleinern. Ist diese Annahme korrekt?
vielleicht zeigst du uns auch deine beschaltung?
@xxx-gast: hab keine wirkliche Beschaltung. Wie bereits geschrieben: > Des weiteren zu deiner Ausgangsbeschaltung: bisher habe ich nichts > weiter als direkt den Klinkenstecker der Aktiv-Boxen beschaltet. Nebenbei: Im Codebeispiel ist cnt die Anzahl der zu mischenden Samples
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.