Tag zusammen, hab mal eine Frage- Vorgeschichte: Ich habe ein mini Sampler für einen Atmega32 geschrieben. Dazu habe ich mit audio-converter 8 Samples in (8 bit Mono 8000Hz) konvertiert und diese auf den atmega in den flash geschrieben. Ein kleine Routine verarbeitet dann einen ganz einfach gehalten Sequenzer der die Samples abspielt. Ein 12 bit Widerstandsnetzwerk sorgt für die DA-Umwandlung. Ich habe also an einer Stelle acht byte-werte (jedes für ein Sample) die ich mischen möchte. Bis dato gehe ich einfach hin und addiere alle acht werte und gebe sie auf dem DA-Wandler aus. OUT = S1 + S2 + S3 + S4 + S5 + S6 + S7 + S8 8 * 255 = 2040 als maximalen Wert der ausgegeben werden muss Das sollte also mit dem 12bit wandler kein problem sein. Las ich nun einzelne Samples abspielen geht alles gut, klingt "sauber" solange man das bei 8 bit sagen kann. Wobei die Basedrums und Toms gar nicht so schlecht klingen. Meine Frage: Gibt es eine bessere / richtige Möglichkeit die Samplewerte zu mischen? Die Lautstärke könnte ich so regeln, oder? Wobei Vn ein Wert zwischen 0 und 1 sein sollte. OUT = (S1*V1) + (S2*V2) + (S2*V2) + ... Ideen, Kritik alles erwünscht. Danke schonmal.
Hallo Jonas, um mehrere Samples zu mischen erst mal etwas Mathe. Wenn du mehrere Samples mit 8 Bit Auflösung mischst ist auch das Ergebnis nur in 8 Bit aufgelöst. In deiner Rechnung fehlt der Teiler durch die Anzahl der gemischten Samples : Out = ( In1 + In2 + ... + InX ) /X Da du eine 32 Bit CPU benutzt solltest du im Programm Code darauf achten, das du keine Rechenfehler (durch falsche Rundung ) bekommst durch 8 Bit Variablen ( das Ergebnis der Addition von 2 8 Bit Variablen muss in einer 16 Bit Variablen gespeichert werden. Das Selbe gilt bei der Division : Das teilen einer 16 Bit Variablen durch eine 8 Bit Variablen hat muss als Ziel eine 16 Bit Variable haben. Der Compiler rundet und wandelt zwischen den Variablengrössen gerne mal anders als man erwartet. Zum Test der Software ist es praktisch, 2 Samples mit einem Sinus mit der Frequenz 1 kHz und 2 kHz abzuspielen und die Ausgabe sich auf dem Oszilloskop anzuschauen. Zusammengemischt sollten die Peak Werte nicht höher sein als ein Peak wert eines einzelnen Samples. Wenn dein DA Wandler nur positive Spannungen erzeugt, kann die Tonqualität auf einen Audio Verstärker noch besser werden, wenn du mit einem Kondensator den Gleichstromanteil ausfilterst. Perfekt wird es erst wenn du in Software mit vorzeichenbehafteten Werten rechnest und die Wandlung ebenso erfolgt. Gruß, dasrotemopped.
dasrotemopped schrieb: Mit dem meisten bin ich einverstanden. Aber ein paar Punkte lassen mir dann doch die Haare zu Berge stehen. > Da du eine 32 Bit CPU benutzt Prust. Nö, auch ein Mega32 ist nur eine 8 Bit CPU. Das 32 im Namen bezieht sich auf die Größe des Flash > solltest du im Programm Code > darauf achten, das du keine Rechenfehler (durch falsche Rundung ) > bekommst durch 8 Bit Variablen ( das Ergebnis der Addition von 2 > 8 Bit Variablen muss in einer 16 Bit Variablen gespeichert werden. Soweit, so gut > Das Selbe gilt bei der Division : Das teilen einer 16 Bit > Variablen durch eine 8 Bit Variablen hat muss als Ziel eine 16 Bit > Variable haben. > Der Compiler rundet Nö > und wandelt zwischen den > Variablengrössen gerne mal anders als man erwartet. Auch das nicht. Je nachdem was genau du unter "Compiler" verstehst. Ich geh mal von einem C Compiler und Integer Rechnung aus. Die Regeln, wie die Operationen ausgeführt werden, sind eindeutig festgelegt. Wenn da also nicht das passiert, was du erwartest, dann ist deine Erwartung falsch. Ein Blick in die nächstbeste C-Literatur kann das aber beheben. Und nein: Bei Integer-Rechnungen wird überhaupt nicht gerundet. Die Berechnung wird so durchgeführt, als ob entstehende Kommastellen einfach abgeschnitten werden würden. Das ist sogar so etwas wie ein allgemeines Prinzip, da es auch dann zur Anwendung kommt, wenn ein Floating Point Ergebnis an einen Integer zugewiesen wird.
Ich denke, das Wort "mischen" ist nichtssagend, denn der konkr. Algorithm. ist entscheidend. Und da gibt es viele....
Mea culpa,
Hat sich ein Tippfehler schwer ausgewirkt :
> Da du eine 32 Bit CPU benutzt
korrigiert : Da du >k<eine 32 Bit CPU benutzt
Warum sollte ich mir Gedanken um 8 oder 16 Bit machen wenn ich als
default 32 Bit zur Verfügung habe ?
Und mit Rundung meinte ich Über/Unterlauf bei einer Rechenoperation.
Der C Kompiler mag nach Definition immer richtig arbeiten, nur hat man
nicht immer alle Definitionen auswendig im Kopf oder beachtet nicht alle
beim Programmieren.
Daher auch mein Tip, die Rechenergebnisse per Oszilloskop zu
"überprüfen".
@MCUA
Welchen Mischalgorithmus würdest du Jonas denn bei seiner Frage
empfehlen ?
Gruß,
dasrotemopped
dasrotemopped schrieb: > Mea culpa, > > Hat sich ein Tippfehler schwer ausgewirkt : > >> Da du eine 32 Bit CPU benutzt > korrigiert : Da du >k<eine 32 Bit CPU benutzt Bamm! (das war die Stirn, die auf der Tischplatte aufschlägt) Jetzt ergibt auch der komplette Satz auf einmal Sinn. Und ich hab mich schon gefragt: Was will uns der Dichter eigentlich sagen. Aber auf ein fehlendes 'k' bin ich nicht gekommen. > Und mit Rundung meinte ich Über/Unterlauf bei einer Rechenoperation. > Der C Kompiler mag nach Definition immer richtig arbeiten, nur hat man > nicht immer alle Definitionen auswendig im Kopf oder beachtet nicht alle > beim Programmieren. Na ja Die sollte man aber eigentlich schon im Kopf haben. Das man nicht immer darauf achtet, gestehe ich gerne zu. Nichts desto trotz sollte das so selbstverständlich sein, wie 'Punkt vor Strich'-Rechnen in der Mathematik.
dasrotemopped schrieb: > um mehrere Samples zu mischen erst mal etwas Mathe. > Wenn du mehrere Samples mit 8 Bit Auflösung mischst > ist auch das Ergebnis nur in 8 Bit aufgelöst. Ich denke da hat MCUA schon recht, das ist eine Definitionsfrage. Das Ergebnis muss doch keineswegs wieder in den gleichen Wertebereich gezwängt werden. Da er den Hardwareaufwand offenbar nicht scheut, ist Jonas' Lösung doch durchaus besser. Bei den 12-bit mit R2R stellt sich mir aber die Frage, ob das an den Ausgängen eines 8-bit µC so einfach geht. Irgendwo habe ich mal eine Lösung mit zwei 8-bit D-Flipflops gesehen, die erst mit je einem Byte eines 16-Bit-Samples geladen wurden um das dann gleichzeitig auf das Wiederstandsnetz loszulassen. Wenn man direkt die Ausgänge des AVR nimmt, dann hat man doch das Problem, dass der Wert zwischen zwei Kopieraktionen mal nicht stimmt, oder geht das irgendwie einfacher? Mich würde das Projekt durchaus mal näher interessieren, einen Drumcomputer möchte ich auch irgendwann mal bauen. Mirko
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.