IMA ADPCM-Decoder funktioniert nicht

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

IMA ADPCM-Decoder funktioniert nicht

Beitrag von DarkSoul »

Hallo Forum,

ich habe versucht, einen IMA-ADPCM-Decoder zusammenzuschustern. Leider klappt das ganze nicht so, wie ich mir das vorstelle. Die Musik ist deutlich erkennbar, allerdings schwimmt die Lautstärke und ca. jede Sekunde ist ein Klickgeräusch zu hören. Die Tonschwingungen in Audacity betrachtet "torkeln" auch ziemlich und clippen an einigen Stellen. Also der Weg ist irgendwie richtig.

Achtung: Quick'n'Dirty (besonders das mit den Array-String-Zeug am Anfang und wie ich den WAV-Header "verarbeite") und ein wenig verbastelt durch meine Fehlersuche. So, wie er jetzt gerade ist. Es muss erstmal laufen. Verbessern kann man dann immer noch.

Die Daten können am Ende ohnehin headerless bleiben. Es ist ganz genau festgelegt, wie die IMA-ADPCM Dateien zu sein haben.

Zunächst 4Bit/11025Hz/Mono zum Testen.

Die Quelldaten liegen im RAW-Format vor (mit FFMPEG codiert). Hatte zuerst .WAV. Wollte ausschließen, dass es am Container liegt. Darum war ich auf RAW umgestiegen.

Für diesen einen Zweck möchte ich keine fette Lib nutzen, weil das Programm selbst eine DLL wird und ich die nicht von externen Dateien abhängig machen möchte.

Ich denke, es ist ein kleiner Fehler.

Ich muss zu meiner Schande gestehen, dass ich das aus einem meiner anderen Projekte hergenommen habe. Jedoch habe ich damals dieses andere Projekt in C geschrieben und ich versuche, dasselbe in PB zu erreichen. Ich hab das schon zig male abgeglichen und ich finde den Fehler nicht.

Das Portieren von C nach PB geht mir irgendwie immer nach hinten los... Da fluche ich jedes Mal :mrgreen:

PB finde ich persönlich schwieriger als C. Dafür gehts oft schneller, wenn es um so Kleinkram geht.

Code: Alles auswählen

Procedure DecodeADPCM(file.s)
  ;sorry dafür. Ich habe das PB-Gegenstück zu [1,2,3,4...] nicht gefunden. Sollte aber nicht die Ursache sein, weil die Arrays stimmen
#ima_step_table="7,8,9,10,11,12,13,14,  16,17,19,21,23,25,28,31, 34,37,41,45,50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230, 253,279,307,337,371,408,449, 494,544,598,658,724 ,796,876,963,1060 ,1166,1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,3327,3660,4026 ,4428,4871,5358, 5894,6484,7132,7845,8630,9493, 10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794, 32767"
  #ima_index_table="-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8"
  
  Dim imaStepTable(89)
  For a = 0 To 88
    imaStepTable(a) = Val(StringField(#ima_step_table, a + 1, ","))
    Debug imaStepTable(a)
  Next a
  
  Dim imaIndexTable(16)
  For a = 0 To 15
    imaIndexTable(a) = Val(StringField(#ima_index_table, a + 1, ","))
  Next a
  
  If ReadFile(0,file) ;raw-Datei öffnen
    OpenFile(1,file + ".pcm.wav") ;Debug-Ausgabe-Datei öffnen (ist eine raw! .wav steht da nur, damit Audacity die leichter aufkriegt)
    ;string.s
    ;Repeat
    ;  string + Chr(ReadAsciiCharacter(0))
    ;  If Len(string) > 4
    ;    string = Right(string,4)
    ;  EndIf
    ;  ;Debug string
    ;Until Eof(0) Or string = "data"
    ReadByte(0) ;zwei crappy bytes am Anfang, die für Glitches sorgen? Liegt hier das Geheimnis begraben?
    ReadByte(0)

   ;decoder
    Dim n(2) 
    diff = 0
    stp = 0
    index = 0
    pred = 0
    While Eof(0) = 0
      a = ReadByte(0)
      n(0) = a & $0f  ;geht sicher einfacher, ein .b auf zwei nibble aufzuspalten
      n(1) = (a & $f0) >> 4
      For i = 0 To 1
        
        code = n(i) & $0f ;dirty conversion signed->unsigned. Wie geht das in PB? xD

        stp = imaStepTable(index)
        
        diff = stp >> 3
        If ((code & 4) <> 0) : diff + stp : EndIf
        If ((code & 2) <> 0) : diff + (stp >> 1) : EndIf
        If ((code & 1) <> 0) : diff + (stp >> 2) : EndIf
        If ((code & 8) <> 0) : diff = 0-diff : EndIf

        pred + diff
        If (pred > 32767) : pred = 32767 : EndIf    ;hard-limiter
        If (pred < -32768) : pred = -32768 : EndIf

        index + imaIndexTable(code);
        If (index < 0) : index = 0 : EndIf
        If (index > 88) : index = 88 : EndIf

        WriteByte(1, pred / 256)  ;conversion auf 8bit mono
        
        
        
      Next i
    Wend
    CloseFile(1)
    CloseFile(0)
  EndIf  
EndProcedure

DecodeADPCM("adpcm.raw")
Eine .PBI oder eine Fertig-Methode würde mir auch reichen. Ich konnte über Google nichts finden.

Alternativ kann ich auch MS-ADPCM verwenden.

Hauptsache, das funktioniert. Decodieren reicht aus.

Dass er in eine Datei decodiert, ist nur zum Testen, damit ich mit Audacity reingucken kann. Am Ende soll mit richtigem Header usw. in den Speicher hineindecodiert werden und dann mit PlaySound() oder was auch immer abgespielt werden.

Vielleicht kann hier jemand helfen. 8)

Eine adpcm.raw kann ich bei Bedarf nachliefern.

Compiler:Windows, 5.31, 32Bit
Zuletzt geändert von DarkSoul am 19.06.2016 20:06, insgesamt 1-mal geändert.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von ts-soft »

Du solltest in der dritten Zeile des Codes, Datazeile, mal ein paar Leerzeichen einfügen, ansonsten wird es schwierig Deinen Beitrag zu
lesen, da das Forum nicht umbrechen kann.

Danke,
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von DarkSoul »

Das sollte so richtig sein. Die nachfolgenden Zeilen parsen ja den String als Zahlenwerte in das Array. Das Einfügen von Leerzeichen würde zu noch mehr Fehlern führen.
Das Array stimmt am Ende. Das habe ich bereits überprüft.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von ts-soft »

Es geht nicht um die Richtigkeit des Codes, der bleibt ja erhalten, es geht um das Umbrechen des Textes im Forum. Ich werde auf jeden
Fall nicht Stundenlang nach rechts scrollen, um etwas Lesen zu können /:->
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von DarkSoul »

Hä? Was meinst du genau?

Bei mir wird der Source Code richtig angezeigt.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von ts-soft »

Der SourceCode wird ja richtig angezeigt, aber es wird nicht umgebrochen, und das gilt für Deinen gesamten Text!
Statt:

Code: Alles auswählen

#ima_step_table="7,8,9,10,...
mal:

Code: Alles auswählen

#ima_step_table="7, 8,  9,  10, ...
musst ja nicht hinter jedem komma ein Leerzeichen einfügen, aber ab und zu!
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von DarkSoul »

Meinst du so, wie es jetzt ist?

Irgendwie ist die Einrückung jetzt ein bisschen kaputt. Das bekomme ich nicht anders hin. :|
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von ts-soft »

DarkSoul hat geschrieben:Meinst du so, wie es jetzt ist?
Genau!
DarkSoul hat geschrieben:Irgendwie ist die Einrückung jetzt ein bisschen kaputt. Das bekomme ich nicht anders hin. :|
Da ist nichts kaputt, mit Copy und Paste und alles ist normal formatiert in der IDE :D

Aber das wichtigste, Du brauchst nicht mehr nach rechts scrollen um Deinen Text zu lesen! So findet sich auch schneller,
jemand der Hilft. Ich bin da für Sound nicht so der Richtige.

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: IMA ADPCM-Decoder funktioniert nicht

Beitrag von DarkSoul »

Habe es nun doch noch hinbekommen.

Im Code hätte man noch lange suchen können... Das aktuelle FFMPEG erzeugt nämlich fehlerhafte Raw-ADPCM-Dateien. :freak: :freak: Ich habe mich darauf verlassen, dass der Encoder bewährt und bugfrei ist.

Wenn ich nämlich die Vorversion benutze und das Ergebnis an meinen Decoder verfüttere, funktionierts bestens. :allright:

Habe den Code nun nochmal ins reine geschrieben und mir ein .pbi von basteln können.

Trotzdem Danke.


Falls es wen interessiert, wieso ich es haben wollte:
Ich wollte Gamesound haben, wie er früher war (mono, 22050Hz ADPCM). Aus diesem Grunde habe ich dem Ding zusätzlich noch einen billigen Nearest-Neighbour-Resampler gebastelt, der der Soundkarte ein wenig Arbeit abnimmt. :bounce:
Da konnte ich mit .ogg nicht so viel anfangen. :roll:
Bild
Antworten