Man nehme einen ATmega328 (oder auch einen anderen mit ausreichend Speicher), setze einen 11,2896MHz (=256fs) Quarz oder Oszillator dran, schalte die DIV8 Fuse aus und setze eine Buchse an TxD (siehe Bild). Dann noch beigefügte Software aufgeflasht und dem Hörvergnügen der 4 beigefügten süßen Melodien (...) über den Digitaleingang des Verstärkers steht nichts mehr im Wege.
Stereo kommt später ...
Auf dem ATmega88 ist vermutlich nur Platz für eine der Darbietungen.
Viel Spaß zum Jahresende!
... Vielleicht kanns ja jemand gebrauchen ... ;-)
Irgendwie fehlt mir eine Software (in C auf dem PC?) die aus einer CD
ein sehr kurzes Stück in Sampledaten umrechnet.
eine CD hat nur Sampledaten. Jede Software die eine CD rippen kann und sie als WAV ablegt, also nicht noch mit extra Aufwand danach einen MP3 Encoder drueber laufen laesst, macht genau das. Ausser vielleicht einem kleinen Dateiheader den du entfernen musst.
Die Samples wurden nun ausgelagert und werden am Ende des Codes eingebunden. Bzw. wird. - ein Sample.
Außerdem ist die Länge des Samples nun variabel, bis das Flash voll ist.
Samplerate ist nun konfigurierbar. (Was vor allem den Subcode betrifft)
Subcode ist einfacher einstellbar.
Next Steps:
DDS?
Ich bin mittlerweile davon überzeugt, dass auch die BMC-Modulation dort noch mit hinein passt. Dann könnte der ADC des AVR als Quelle dienen.
Bei der HW-SPI des AVRs gibt es keinen Buffer. Den gibt es nur bei der USART. Bei Chips mit 2. USART könnte man dann auch per I²S Daten empfangen.
Ich werde das demnächst mal ausprobieren ...
Außerdem hänge ich noch ein Samplefile mit an, in dem folgende Frequenzen enthalten sind:
20Hz, 50Hz, 100Hz, 200Hz, 500Hz, 1kHz, 2kHz, 5kHz, 10kHz, 20kHz
Siehe auch FFT vom Scope. Allerdings ist dort alles unter 500Hz nur Brei.
Ich würde versuchen Audacity zu benutzen, um aus den Audiodaten, einspurige, 24-bitige, vermutlich vorzeichenbehaftete Daten in eine unkomprimierte RAW-Datei ohne Kopf zu exportieren. Vorher noch gewünschten Bereich freistellen und normalisieren.
Dann ist vermutlich das grösste Hindernis herauszufinden, in welcher Reihenfolge (little endian / big endian) die Bytes wo stehen, bzw. stehen müssen.
Aus einem Bit 2 zu machen ist da eher einfach. Daraus einen Text für den Assembler zu generieren bestimmt auch machbar.
Der kann man das alles entnehmen, links auch eigene Werte eintragen und ganz rechts steht der fertige Quelltext, den man nur noch ausschneiden muss.
Ich speichere nach meiner Änderung immer die komplette Datei als .csv und schneide dann den Quelltext mit
cat Datei.csv | cut -d"Q" -f2 >Datei.asm
ab. Oben und unten editiere ich dann noch kurz von Hand.
Um aber auch das Format selbst darzulegen:
Die Daten sind der fertige BMC Kanalcode, der einfach nur noch auf die Schnittstelle gekippt wird.
Eine 0 (Datenbit) sind zwei gleiche Kanalbits, eine 1 (Datenbit) sind zwei unterschiedliche Kanalbits.
Zwischen den Datenbits befindet sich ebenfalls eine Flanke.
Nach der Preamble folgt bei SPDIF das LSB des 24-Bit Samples. Bei 16-Bit Audio kommen hier zunächst 8 0-en. MSB ist immer ganz rechts vor dem Subcode.
Meine Preamble startet (auf der Schnittstelle) mit 1 und endet mit 0, so dass das Sample auch mit 1 beginnen muss.
0 wird also zu 11
1 wird zu 10
im nächsten Bit
0 wird zu 11, wenn letztes Kanalbit 0 ist und 00, wenn letztes Kanalbit 1 ist.
(Es dürfen nie 3 Kanalbits (oder mehr) hintereinander den selben Pegel besitzen. Dies ist der Preamble vorbehalten.)
8
9
Die Schnittstelle ist auf LSB-First eingestellt, also wird daraus:
10
.db 0x2B, 0xCB, 0x2A, 0x35, 0x4B, 0x4D
Die anschließenden Subcodebits werden wie in diesem Beispiel, bei einer 0 als letztem Kanalbit, unverändert ausgegeben, bei einer 1 wird das bereits fertige Byte invertiert. Das Parity-Bit wird automatisch angepasst. Es muss immer auf 0 enden, da die Preamble wieder mit 1 startet.
Das passiert hier:
1
ANDI VUCP, 0x7F ; Parity immer richtig
Wie schon erwähnt, möchte ich diese Konvertierung noch mit in den Code packen, dann können einfache Samples verwendet werden. Ich überlege auch, dann 16-Bit Samples ebenfalls zuzulassen. All dies würde die 'Spieldauer' verdreifachen.
Alle Bilder:
Die beiden Marker rahmen die 24Bit Audio ein.
Links des linken Marker befindet sich die Preamble,
rechts des rechten Markers der Subcode.
Erst Validity, User-Bit, Channelstatus, Parity.
Ganz rechts sieht man noch den Anfang der nächsten Preample.
Die hier gezeigten Beispiele sind invertiert zum Code.
Die Polarität des Signals ist jedoch völlig egal, es interessieren nur die Flanken.
File12:
Ruhe. Alle 24 Audio-Bits sind auf 0
Validity ist 1 und bedeutet, dass das Sample nicht genutzt werden sollte.
Außerdem ist das C-Bit gesetzt.
Parity ist 0 und hinterlässt damit die Voraussetzung für die nächste Preamble mit der selben Polarität wie die vorhergehende Preamble zu beginnen.
File13:
Ein Audiosample.
Validity ist auf 0 und besagt damit, dass das Sample benutzt werden kann.
Parity ist 1 hinterlässt aber wieder die Voraussetzung für die Polarität der nächsten Preamble.
File14:
Laufende Audiowiedergabe, aber nicht nur ein Sample, sondern getriggert auf Type "Pulse"
When "-->--" (negativer Puls, länger als ...)
Setting 500ns
Es sind 2 unterschiedliche Preamblen erkennbar. Und ganz dünn erkennt man auch noch die 'B' Preamble, welche nur 1x alle 384 Subframes auftaucht.
Die 8 LSBs sind 0, da 16-Bit Audio wiedergegeben wird. Dieses besteht selbst recht zufällig aus 0 und 1.
Validity ist immer 0, UserBit auch.
Beim C-Bit sieht man wieder eine ganz dünne '1' in dem Bit, da von den 192 Channelstatus-Bits nur 3 oder 4 Bit '1' sind, der Rest '0'.
Am Ende sieht man wieder Parity, welche sich immer so dreht, dass der Pegel zum Schluss immer identisch ist.
Wünsche im Übrigen allen auch noch ein Frohes neues Jahr!
Für den C# Code habe ich in der Tat Deine Tabelle seziert. Bevor noch wer fragt, wie er eine .mp3-Datei in seine Tabellenkalkulation laden kann...
Aber um Liedschnipsel mit Wiedererkennungseffekt ausgeben zu können, muss die Spielzeit länger werden. Kann man den Code für einen Mega2560 umschreiben, oder ist das Timing schon so straff, dass mehr als 16 Bit Adresszähler nicht drin sind ?
Und ja, 16 Bit per Sample hatte ich mir auch schon gedacht. Konnte mich aber nicht dazu überwinden nachzuschauen, was dafür alles geändert werden müsste.
PS : einen winzigen Bug denke ich in Deiner Tabelle noch gefunden zu haben :
In Spalte C :
1
=RUNDEN(B2*2^23)
Vorzeichenbehaftete 24-bitige Zahlen haben nur einen Wertebereich von -(2^23) ... (2^23)-1
Glücklicherweise triffst Du in der Tabelle nicht den Winkel, an dem der Sinus +1 ergibt. Daraus würde die Tabelle nämlich -(2^23) machen, also den Wert für -1.
Damit 0 auch 0 bleibt, würde ich folgende Änderung vorschlagen :
Aber um Liedschnipsel mit Wiedererkennungseffekt ausgeben zu können
War nun auch überhaupt nicht meine Idee dabei.
Der Grund für die Entwicklung war es, spezielle Testsignale erzeugen zu können. Und die Herausforderung, ob das wohl ginge.
ist das Timing schon so straff, dass mehr als 16 Bit
Adresszähler nicht drin sind ?
Das könnte man sicherlich bewerkstelligen. Derzeit wird vor jedem schreiben in das TX-Register geprüft, ob dort Platz ist. Dieser Vorgang kostet jedes Mal 5 Takte. Das könnte man bei genauerer Taktauszählung auch seltener machen.
Und ja, 16 Bit per Sample hatte ich mir auch schon gedacht. Konnte mich
aber nicht dazu überwinden nachzuschauen, was dafür alles geändert
werden müsste.
Die beiden Zeilen
1
LPM r2, Z+ ; GET_SAMPLE
2
LPM r3, Z+ ; GET_SAMPLE
entfallen und r2 und r3 müssen dafür beide mit 0x33 vor der loop geladen werden.
Wenn Du das selbe mit r4 machst, gehen 12 Bit Daten und
wenn Du das selbe mit r5 machst, kannst Du 8 Bit Daten benutzen.
Sogar 4 Bit gehen, wenn auch mit r6 so verfahren wird.
Dann hast Du ein Byte an Daten pro 4-Bit Sample.
Knorke!
Ja, stimmt. Aber ich habe das mit vollem Bewustsein so gemacht, da mir klar war, dass ich dort nicht hin komme.
Natürlich KANN man diese Änderung machen und ist dann auf der sicheren Seite, wenn man damit spielt.
BMC-Modulator nun integriert.
Datenbreite lässt sich von 24 auf 16 Bit einschränken (Zeile 76).
Weitere Version nutzt den internen ADC des AVR. Habe ich bislang nur insoweit getestet, dass ein Brummen aus meinem DAC kommt, welches bei Näherung an PC5 (der Eingang) lauter wird.
Vielleicht mag das ja mal wer richtig testen?
Entweder füge ich beide Versionen noch zusammen oder ich entrümple die ADC Version von der Möglichkeit Daten als Tabelle abzulegen.
Mal schauen.