OpenDCC AniMat MP3-Software

    Hier finden sich Erläuterung zum Erzeugen und Dekodieren von mp3-Dateien (nicht die Kodierungstheorie, sondern wie das in der Praxis in Zusammenhang mit VS1011 und AVR auf dem AniMat funktioniert).

Editieren von Tonvorlagen und Erzeugen von mp3

    Hierzu gibt es ein gutes Open Source Programm, welches sowohl für Linux, Windows und Mac verfügbar ist: Audacity
    Die so erzeugte Datei liegt nun auf dem PC vor, wie kommt das auf den Lautsprecher?
  • Abspeichern der Datei auf einer microSD Speicherkarte. Diese wird am Dekoder eingesteckt und die Daten werden von der Karte zum Dekoderchip kopiert.
  • Umwandeln in ein C-File und Eincompilieren in den AVR-Code. Das geht wegen der Beschränkung des Flash-Speichers nur für kurze Dateien.

Konvertieren eines mp3-Files zu C-Source Code

    Wenn kurze Tonsequenzen direkt in den Flash des Atmels abgelegt werden sollen, dann muß man das vorhandene mp3-file als Array in den C-Code einfügen. Hierzu wird xxd.exe verwendet, welches als Tool beim Editor VIM dabei ist (verfügbar unter Linux und PC).

    Vorgehensweise:
  • Das gewünschte Tonstück als beispiel.mp3 abspeichern. Der Name beispiel ist willkürlich gewählt und dient nur zur Veranschaulichung.
  • Nun mit der Eingabeaufforderung das mp3-file konvertieren:
        xxd -i beispiel.mp3 beispiel.c
    xxd liest aus dem Inputfile beispiel.mp3 alle Daten binär aus und erzeugt ein Outputfile (beispiel.c-Datei), welche wie folgt aussieht:
        unsigned char beispiel_mp3[] = {
           0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x50, 0x52,
           0x49, 0x56, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x50, 0x65, 0x61, 0x6b,
           0x56, 0x61, 0x6c, 0x75, 0x65, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x50, 0x52,
           ...
           };
        unsigned int beispiel_mp3_len = 16224;
    Bevor diese Datei in das Projekt eingebunden werden kann, muß man diese Daten dem Flash zuweisen. Dies geschieht durch Einfügen der Anweisung PROGMEM. Außerdem kann die Länge fallweise den Datenbereich einer Integer des AVR überschreiten. Hierbei ist das Speichermodell des verwendeten AVR zu beachten (Unterscheidung near <-> far). Im Falle far wird aus unsigned int also unsigned long. OpenDecoder4 verwendet eine Struktur von Typ t_flash_record.
        typedef struct
          {
            uint16_t  size;         // depending on memory we use int or long
            uint8_t  data[];        // array of mp3 data
          } t_flash_record;
    Die Daten müssen nun dieser Struktur zugewiesen werden. Die Datei muß nun so aussehen:
        t_flash_record PROGMEM entry1 =
          {
           16224,
           { 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x50, 0x52,
             0x49, 0x56, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x50, 0x65, 0x61, 0x6b,
             0x56, 0x61, 0x6c, 0x75, 0x65, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x50, 0x52,
             ...
           }
         };

Tipps zum VS1011e

    OpenDecoder4 benutzt den VS1011e als Dekoder. Ich habe eine Reihe Codebespiele für Atmel im Netz gefunden, aber leider nichts qualitativ Optimales. Performance (also maximaler Durchsatz am SPI) und Fehlerabsicherung scheinen bei Bastelprojekten nicht unbedingt höchste Priorität zu geniesen. Deswegen hier ein paar Hinweise zur Ansteuerung des VS1011:
  • Zugriffe: Der VS1011 wird über zwei verschiedene CS-Signale angesprochen:
    • XCS für Kommandos (Lautstärke ändern, Reset, ...)
    • XDCS für MP3 Stream-Daten, die unmittelbar dekodiert werden (bzw. f. Testsequenzen)
    • Jeder Kontrollzugriff muß vorher DREQ prüfen, damit man hier nicht in einer Endlosschleife landen kann, muß die DREQ Abfrage mit timeout abgesichert sein. Bei Datenzugriffen dürfen nach einen DREQ bis zu 32 Byte ohne weitere Nachfrage an den Chip gesendet werden.
      Die SPI-Geschwindigkeit darf nicht höher als VS_QuarzFreq/6 (beim Lesen) sein, beispielsweise bei 10 MHz also F_CPU/4 = 2,5MHz. Besonderer Hinweis: wenn im VS1011e Clockdoubler verwendet wird (also nur 12MHz zu Beginn), dann gilt diese reduzierte Geschwindigkeit bis zum Einstellen des Clockdoublers.
      Es gibt auch noch einen "alten" Kompatibilitätsmodus (für den VS1001) mit speziellen Signalleitungen (BSYNC, ..), der aber nicht mehr empfohlen wird.
  • Chip-Version: Vor dem Zugriff auf den VS1011 sollte man die Version abfragen und einen internen Speichertest durchführen lassen.
  • RESET Pin: dieser muß mit Pullup auf VCC gezogen werden - offenlassen genügt nicht. Das SPI Interface funktioniert dann zwar, Status ist aber nicht korrekt auslesbar. Zudem hat der Reset-Pin keine saubere Threshold bzw. liegt diese sehr weit unten: kurzeitiges Abschalten der VCC führt zu undefinierten Zuständen, wenn nicht nach Power-On definiert ein Resetpuls angelegt wird.
  • Wechsel der mp3 Datei: damit es nicht zu unschönen Knacksern und Störgeräuschen kommt, muß man sicherstellen, dass der alte mp3-Frame sicher zu Ende ist. Hierzu beim Abbruch eines mp3-Files noch 32 Null-Bytes an den vs1011e senden.

Unterlagen / Links