Forum: Mikrocontroller und Digitale Elektronik ATmega328 und SPDIF 24 Bit digital Audio


von Jobst M. (jobstens-de)


Angehängte Dateien:

Lesenswert?

Guten Morgen!

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 ... ;-)

Gruß
Jobst

von Michael B. (laberkopp)


Lesenswert?

Irgendwie fehlt mir eine Software (in C auf dem PC?) die aus einer CD 
ein sehr kurzes Stück in Sampledaten umrechnet. Nur Sinustöne sind öde.

von Frank O. (frank_o)


Lesenswert?

Werde ich wohl nicht nutzen, aber sehr schön, dass du das eingestellt 
hast.
Was alles so geht, ist auch interessant zu sehen.

von Vanye R. (vanye_rijan)


Lesenswert?

> 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.

Vanye

von Michael B. (laberkopp)


Lesenswert?

Vanye R. schrieb:
> macht genau das.

Unwahrscheinlich dass die liefert:

"Eine Zeile = ein 24 Bit Sample - bereits als biphase mark code"

von Jobst M. (jobstens-de)


Angehängte Dateien:

Lesenswert?

Michael B. schrieb:
> Nur Sinustöne sind öde.

Du hast ja gar kein Her(t)z für Messtechnik ...

Hab' Dir da mal was angehängt, was Du entsprechend umbauen kannst.
Links in der Spalte 'Values' stehen die Werte. Bereich +/-1.

Gruß
Jobst

von Jobst M. (jobstens-de)



Lesenswert?

So, Update.

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.


Gruß
Jobst

von Frank O. (fop)


Lesenswert?

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.

von Frank O. (fop)


Lesenswert?

D'Oh : macht dann so ca. 123 ms Musik aus 32kB Flash.

von Frank O. (fop)


Angehängte Dateien:

Lesenswert?

Michael B. schrieb:
> Irgendwie fehlt mir eine Software (in C auf dem PC?) die aus einer CD
> ein sehr kurzes Stück in Sampledaten umrechnet. Nur Sinustöne sind öde.

So was ? Ist nur C# statt C geworden. Verdaut Raw-Dateien von Audacity.

von Jobst M. (jobstens-de)


Lesenswert?

Frank O. schrieb:
> Dann ist vermutlich das grösste Hindernis herauszufinden

Ach Frank, dazu gibt es doch schon etwas von mir.

Jobst M. schrieb:
> Angehängte Dateien:
> SinTable10kHz.ods (344 KB)

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.

1 wird zu 10 bzw. 01

Beispiel:
1
Aus den Datenbits
2
LSB                                              MSB
3
0 1 1 0  0 1 0 0  1 1 1 0  1 1 0 0  0 1 0 1  1 0 0 1
4
werden die Kanalbits
5
11010100 11010011 01010100 10101100 11010010 10110010
6
7
(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.


Gruß
Jobst

von Jobst M. (jobstens-de)


Angehängte Dateien:

Lesenswert?

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!

Gruß
Jobst

von Frank O. (fop)


Lesenswert?

Ja, frohes neues 2025 !

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 :
1
=RUNDEN(B2*((2^23)-1))

von Jobst M. (jobstens-de)


Lesenswert?

Frank O. schrieb:
> 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.

Frank O. schrieb:
> 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.

Frank O. schrieb:
> 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!

Frank O. schrieb:
> Wertebereich

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.


Gruß
Jobst

von Jobst M. (jobstens-de)


Angehängte Dateien:

Lesenswert?

Update.

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.


Gruß
Jobst

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
Noch kein Account? Hier anmelden.