Hi! Mir hat der Thread Xmega Soundcheck von Kai ziemlich viel geholfen bei einem kleinen Sound Projekt an dem ich derzeit arbeite ( Xmega1A Xplained Board ) . Jetzt bin ich allerdings an einer Stelle angelangt an der mein Gehirn einfach nur aussetzt. Wenn ich jetzt 2 Sound-Dateien als C-arrays habe und diese mixen will, wie gehe ich da am besten vor? ich weiss nicht ob das hier richtig ist: (soundbyte-A / 2) + (soundbyte-B /2) Wichtig ist auch noch. Der erste Sound der läuft ist im Grunde ein Dauerloop eines Motoren-Geräuschs darüber möchte ich aber nun z.b noch ein Horn oder ne Glocke spielen lassen , welche im Grunde jederzeit starten können sollen. Ich bin mir nicht sicher wie man hierbei vorgehen muss, daher wäre ich für Rat sehr dankbar ! gruß Dominik
Da gibt es verschiedene Varianten. Z.B. beide 8-Bit-Samples addieren (Übertrag landet im Carry) und dann einmal nach rechts rotieren (durch 2 teilen, incl. Carry). Wenn ich mehr Stimmen brauche, summiere ich die Sounds mit Übertrag in zwei Register (16-Bit-Variable) und teile sie anschließend durch die Anzahl der Stimmen (Kanäle). Dabei achte ich darauf, dass die Anzahl eine Zweierpotenz ist. (M)ein Dampflokgeräusch mit Tiny85 hat z.B. 4 Stimmen. Davon ist eine für die Glocke reserviert, drei für die Dampfstöße. Alle Sounds enden im Loop für das Grundrauschen (Sieden). Die Dampfstöße werden von einem Radsensor ausgelöst, dabei wird die Spur hochgezählt und die Adressdaten (Anfang, Ende) in ein Array gelegt. Die Ausgaberoutine gibt den Sound aus, bis die Endadresse erreicht ist und fälscht den Zeiger dann auf den Siedeloop, der bei Erreichen der Siede-Endadresse wieder auf Siede-Anfang gesetzt wird. Durch den Einsatz von 3 Spuren für Dampfausstöße können zwei vorherige Dampfausstöße gemütlich zu Ende laufen, während der dritte gestartet wird. Das klingt irgendwie besser als wenn der vorherige Dampfstoß abgewürgt wird. Der Platz im Tiny85 reicht allerdings nicht mehr für eine Dampf-Pfeife, die kommt dann auf ein Soundrecorder-Modul und wird in den NF-Pfad zum LM386 eingekoppelt. Bei der Diesel-Version passen Anlasser, Diesel, Glocke und Horn in einen Tiny85. Bei der Dampf-Version Glocke, Sieden und zwei verschiedene Dampfstöße. Letztere deshalb, um jedes vierte (oder sechste bei Verbund-Lok) mal einen anderen Sample zu benutzen, damit es nicht wie ein Maschinengewehr klingt. Das Tiny85-Soundmodul sieht dann so aus: http://www.hanneslux.de/planet5b/Harzkamel/DSCN0003.JPG ...
>> Alle Sounds enden im Loop für das Grundrauschen (Sieden).
Das heißt im Grunde genommen werden die anderen Sounds nur in das
Grund-Rauschen "eingekoppelt" mathematisch? also in den jeweiligen
Buffer?
Dominik Walter schrieb: >>> Alle Sounds enden im Loop für das Grundrauschen (Sieden). > > Das heißt im Grunde genommen werden die anderen Sounds nur in das > Grund-Rauschen "eingekoppelt" Naja, eher "ersetzt"... Das gilt aber nur für die Dampf-Variante. Beim Diesel hat jedes Geräusch seine eigene "Spur", der Motor (und Anlasser) auch noch seinen eigenen Timer-Interrupt wegen der Drehzahländerung (Änderung der Ausgaberate). > mathematisch? also in den jeweiligen > Buffer? Es laufen (beim Dampf) 4 Spuren. Jede Spur gibt das Grundrauschen (sehr geringe Lautstärke, also Werte um die 128) aus, solange sie nichts "zu tun" hat. Die Zeiger auf die Streams (laufende Adresse und Endadresse) liegen in einem Array. Dies ermöglicht Gleichbehandlung aller Spuren (durch Unterprogramm, das nur den Index übergeben bekommt) bei der Ausgabe, reduziert also den Programmcode. Erreicht die (im Array gehaltene) laufende Adresse einer Spur die (auch im Array liegende) Endadresse, so wird die laufende Adresse auf Anfang des Grundrauschens "gefälscht". Um einen Sound zu starten, wird nur Anfangs- und Endadresse (Flash) des entsprechenden Sounds in das Array geschrieben. Den Rest macht die Ausgaberoutine dann selbst. Der Start wird über Steuerleitungen ausgelöst, die softwaremäßig entprellt werden. Für die Glocke läuft ein eigener Zähler, der über die Steuerleitung auf Startwert gesetzt wird. Bei Auslösung durch Fernsteuerung (DCC, Funk) wird dieser auf 1 gesetzt. Soll die Glocke über einen am Gleis "vergrabenen" Magneten ausgelöst werden, wird der Zähler auf die Anzahl der gewünschten Glockenschläge gesetzt. Ich habe vor, das Ganze irgendwann noch mal mit einem Mega1284 umzusetzen, um mit höherer Samplerate und mehr (und längeren) Sounds arbeiten zu können. Mich stört dabei aber etwas, dass es keine PLL für Timer gibt, die PWM-Frequenz des als DAC genutzten Timers also begrenzt ist. Ein externer DAC macht die Sache ja wieder komplizierter. Mit dem Tiny85 erreicht man ja ohne Klimmzüge 250 kHz PWM-Frequenz, was die Ansprüche an den Tiefpass erheblich reduziert. Ideal dafür wäre ein Tiny25 mit 1 oder 16 MB internem EEP (der auch gut als Datenlogger geeignet wäre). Aber den haben wir leider nicht... 8-( ...
Dominik Walter schrieb: > (soundbyte-A / 2) + (soundbyte-B /2) Wichtig ist halt, dass Du die Division nicht nur durchführst, wenn beide Sounds ertönen, weil Du sonst den Loop immer in der Lautstärke veränderst, wenn was anderes dazu kommt (gern gemachter Anfängerfehler :). Wenn es immer nur um die zwei Sounds geht, kannst Du die Werte auch von vornherein auf 7 Bit reduzieren, dann sparst Du Dir die Division. Mirko
Ich habe es jetzt so weit das ich insgesamt 8 Kanäle gleichzeitig abspielen kann. Insgesamt auf einige Timer verteilt (Motor / Anlasser/gas-geben ist Pitch-bar). Ich bin jetzt allerdings an der stelle angelangt wo der interne Flash Speicher nicht mehr ausreicht. Im Augenblick arbeite ich mit 11khz bei 8bit , ich würde aber gerne wieder auf 22khz oder 44khz hoch , weil der 11khz sound doch sehr .. naja dürftig ist ;) Ich würde daher gerne auf SD karte als Sound speicher gehen. Ich weis wie ich die SD-Lese-Routinen einbinden muss. allerdings ist mir das Konzept nicht ganz schlüssig wie ich es schaffe mehrere Sounds gleichzeitig von der SD karte abzuspielen. (sofern das überhaupt geht!) Der XmegaA1 auf dem ich arbeite hat zwar einen Externen RAM mit so weit ich weis 64Mbit (Xplained Board) , aber wie ich das genau in der Software anspreche weis ich noch nicht. Auch hatte ich in einem anderen Forum gelesen das es mit solch großen Ram-Bausteinen und AVR-GCC ein Problem gibt mit den 16bit Pointer und damit verbundenen maximal Adressierbaren speicher von 64k? der Logik halber nach müsste ich (korrigiert mich wenn ich falsch liege) zu Anfang bei Programmstart von der SD karte die Sounds in den Externen RAM laden und dann den externen RAM in meine Abspiel-Routinen füttern , anstelle wie im Augenblick einfach auf Arrays im Programmspeicher zu verweisen. Falls irgend jemand das schon gemacht hat und mir helfen kann ich bin für jeden Rat dankbar, da ich nun nach mehrmaligem suchen keine einfach verständliche Anleitung gefunden habe. PS: Eine Sache die ich nicht ganz verstehe... wieso kann ich eigentlich bei meinem Xmega128 nur die ersten 64Kb für Progmem Daten verwenden?..
Dominik Walter schrieb: > wieso kann ich > eigentlich bei meinem Xmega128 nur die ersten 64Kb für Progmem Daten > verwenden?.. Ich habe zwar noch keinen Xmega eingesetzt, aber eigentlich sollte er das können. Das Register RAMPZ ist vorhanden und der Befehl ELPM wird auch unterstützt. ...
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.