Adaptive Differential Pulse Code Modulation
Adaptive Differential Pulse Code Modulation
Hi.
ADPCM uses 4 Bit to store adapted delta values. This leaves hiss in the audio compressed.
Is there maybe an 8 bit ADPCM codec out there to store the signal in better quality?
Regards,
es_91.
ADPCM uses 4 Bit to store adapted delta values. This leaves hiss in the audio compressed.
Is there maybe an 8 bit ADPCM codec out there to store the signal in better quality?
Regards,
es_91.
-
- Enthusiast
- Posts: 617
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Adaptive Differential Pulse Code Modulation
who knows this format and know what do for playng this ADPCM? or like ADPCM?
i have some samples from console's game and probably i have table with values (ValleyBell or maybe it's just 0xF0 bytes and begins at 0x200):
its look like table for ADPCM?
i am not understand this process... how to make it play? how to make some memory convert to PCM 8bit mono?
archive with samples: https://www.dropbox.com/s/aqqwzp3c91uoj ... e.zip?dl=1
they lay at 038, 039 and etc folders - .snd files. it is nohead data. and theory it is some kind of 4bit ADPCM. and probably 8700kbs.
if samples is 4bit - so data need to be read back to forward:
%0000xxxx - as first value
%xxxx0000 - as second value
so what formula for getting sound is? i am not understand. for DPCM this table have only 16 values, as 4bit - so every 4bit it was array index. but this case table is more bigger than 16 as 4 bit. how to know this formula?
i have some samples from console's game and probably i have table with values (ValleyBell or maybe it's just 0xF0 bytes and begins at 0x200):
Code: Select all
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000200 00 F9 FA FB FC FD FE FF 00 01 02 03 04 05 06 07 щъыьэюя
00000210 00 F6 F8 FA FB FD FE FF 00 01 02 03 05 06 08 0A цшъыэюя
00000220 00 F0 F3 F6 F8 FA FC FE 00 02 04 06 08 0A 0D 10 руцшъью
00000230 00 E9 ED F1 F5 F8 FB FE 00 02 05 08 0B 0F 13 17 йнсхшыю
00000240 00 E2 E8 ED F1 F6 F9 FD 00 03 07 0A 0F 13 18 1E винсцщэ
00000250 00 DA E1 E8 EE F3 F8 FC 00 04 08 0D 12 18 1F 26 Ъбиоушь &
00000260 00 D2 DB E3 EA F0 F6 FB 00 05 0A 10 16 1D 25 2E ТЫгкрцы %.
00000270 00 CA D4 DD E6 ED F4 FA 00 06 0C 13 1A 23 2C 36 КФЭжнфъ #,6
00000280 00 C1 CD D8 E1 EA F2 F9 00 07 0E 16 1F 28 33 3F БНШбктщ (3?
00000290 00 B7 C5 D1 DD E7 F0 F8 00 07 10 19 23 2E 3A 48 ·ЕСЭзрш #.:H
000002A0 00 AD BD CB D8 E3 EE F7 00 09 12 1C 28 35 43 52 ЅЛШгоч (5CR
000002B0 00 A3 B5 C4 D3 E0 EC F6 00 0A 14 20 2D 3B 4B 5C ЈµДУамц -;K\
000002C0 00 98 AC BD CD DC E9 F5 00 0B 17 24 32 42 54 67 ¬ЅНЬйх $2BTg
000002D0 00 8C A2 B6 C8 D8 E7 F4 00 0C 19 28 38 4A 5D 73 Њў¶ИШзф (8J]s
000002E0 00 80 98 AE C2 D4 E4 F3 00 0D 1C 2C 3E 51 67 7F Ђ®ВФду ,>Qg
i am not understand this process... how to make it play? how to make some memory convert to PCM 8bit mono?
archive with samples: https://www.dropbox.com/s/aqqwzp3c91uoj ... e.zip?dl=1
they lay at 038, 039 and etc folders - .snd files. it is nohead data. and theory it is some kind of 4bit ADPCM. and probably 8700kbs.
if samples is 4bit - so data need to be read back to forward:
%0000xxxx - as first value
%xxxx0000 - as second value
so what formula for getting sound is? i am not understand. for DPCM this table have only 16 values, as 4bit - so every 4bit it was array index. but this case table is more bigger than 16 as 4 bit. how to know this formula?
-
- Enthusiast
- Posts: 617
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Adaptive Differential Pulse Code Modulation
thanks, but too not understandible for me
i am solve my problem as last Terminator - by long way Comix Zone have same system, that Ooze have. Comix Zone not have test sfx sounds in options, but Ooze have. so idea was: take ADPCM samples, play it in that options of Ooze game and record VGM file from emulator (Fusion). then i am parse this VGM file and get from that normal 8bit sample. by this method i can extract all Ooze samples. then time is come of Comix Zone. idea was: find where lays longest sample of Ooze in a rom file. find him size value in a header. then take Comix Zone samples and copy it over original sample of Ooze and set new size in a header. then start emulator, play sample, record VGM, parse... by this way i am make this "decrypting" and finaly add this two games into my Online GEMS Database now this base can use by 2 games - Dune and Zombie Ate My Neighbors. i want to add for this Zero Tolerance too, but this game a little another, becouse it have probably 2 GEMS banks, not 1 as most of GEMS games. and i am cant to find this second.
i am solve my problem as last Terminator - by long way Comix Zone have same system, that Ooze have. Comix Zone not have test sfx sounds in options, but Ooze have. so idea was: take ADPCM samples, play it in that options of Ooze game and record VGM file from emulator (Fusion). then i am parse this VGM file and get from that normal 8bit sample. by this method i can extract all Ooze samples. then time is come of Comix Zone. idea was: find where lays longest sample of Ooze in a rom file. find him size value in a header. then take Comix Zone samples and copy it over original sample of Ooze and set new size in a header. then start emulator, play sample, record VGM, parse... by this way i am make this "decrypting" and finaly add this two games into my Online GEMS Database now this base can use by 2 games - Dune and Zombie Ate My Neighbors. i want to add for this Zero Tolerance too, but this game a little another, becouse it have probably 2 GEMS banks, not 1 as most of GEMS games. and i am cant to find this second.
Re: Adaptive Differential Pulse Code Modulation
This explain how to convert :
ADPCM --> PCM
Although you want to convert :
PCM --> ADPCM
I recommand you to study the 1st flow (from ADPCM to PCM) to get then ability to create the 2nd flow process (from PCM to ADPCM).
I do not know what is your level in PUREBASIC. In example : do you usually use arithmetic optimizing, or not? Et caetera...
I suggest you publish a source code in the 'coding questions' section.
In the 2 ways, such a converting consists in dispatching datas blocks to a large quantity of sub-blocks.
The reason for which I recommand you to study from ADPCM to PCM first is, it is a lightly simpler to extract ADPCM datas and use current sub-block tables to get PCM datas.
In the other way (from PCM to ADPCM) you have to create current sub-block tables. What is a lightly harder work.
- calculate (see URL above)
- clamp
- point in the following table identifyed on the process above.
ADPCM --> PCM
Although you want to convert :
PCM --> ADPCM
I recommand you to study the 1st flow (from ADPCM to PCM) to get then ability to create the 2nd flow process (from PCM to ADPCM).
I do not know what is your level in PUREBASIC. In example : do you usually use arithmetic optimizing, or not? Et caetera...
I suggest you publish a source code in the 'coding questions' section.
In the 2 ways, such a converting consists in dispatching datas blocks to a large quantity of sub-blocks.
The reason for which I recommand you to study from ADPCM to PCM first is, it is a lightly simpler to extract ADPCM datas and use current sub-block tables to get PCM datas.
In the other way (from PCM to ADPCM) you have to create current sub-block tables. What is a lightly harder work.
Here "pointing" means :ADPCM to PCM process wrote: [4bits data] pointing [16values table] pointing [88values table]
- calculate (see URL above)
- clamp
- point in the following table identifyed on the process above.
Re: Adaptive Differential Pulse Code Modulation
This http://www.cs.columbia.edu/~hgs/audio/dvi/ is more understandable ?
-
- Enthusiast
- Posts: 617
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Adaptive Differential Pulse Code Modulation
this two games have two types of samples - this ADPCM and normal PCM. it sets by some flags for samples in a header. so creators of this games in 90s have a very small place for sound, that is why (i think) some of samples is ADPCM, some is usual PCM. now i have no this limit for size. so i can replace all ADPCM to PCM. emulators can play any size of rom-file. hardware probably will not play... but i have no flash... how it names... cartrige for check it. so i think PCM -> ADPCM not realy need for my case. now even we have no Ooze or Comix Zone builder for making romhacks. so now it have no sound-switching problem yet. maybe somewhen in a future and if size of file rom will be critical - i will start to dig this ADPCM more deeper.
about my level - it is a very low i am still not understand many things. and many of my ideas still didnt come true in a ready code for my Dune editor i want to map editor part, GEMS-tracker part, grafic editor part (mentats, herbs, units, buildings). now for editing need a lot of manualy work with hex editor, some not very userfriendly YY-Chr programm, some tyle map editors... and etc software. i want to make all in one and very simple. and in a progress of it - i am a little growup and i am like it - to know something new.
about my level - it is a very low i am still not understand many things. and many of my ideas still didnt come true in a ready code for my Dune editor i want to map editor part, GEMS-tracker part, grafic editor part (mentats, herbs, units, buildings). now for editing need a lot of manualy work with hex editor, some not very userfriendly YY-Chr programm, some tyle map editors... and etc software. i want to make all in one and very simple. and in a progress of it - i am a little growup and i am like it - to know something new.
Re: Adaptive Differential Pulse Code Modulation
Ok... You give a second life to very old consoles games...
These links I give are my answer for ADPCM. Its coding is simple containing lists of pre-calculated constants.
I find this subject interesting and will request in the 'coding questions'.
These links I give are my answer for ADPCM. Its coding is simple containing lists of pre-calculated constants.
I find this subject interesting and will request in the 'coding questions'.
Re: Adaptive Differential Pulse Code Modulation
if you need to reverse bits or swap nibbles on a byte.SeregaZ wrote: if samples is 4bit - so data need to be read back to forward:
%0000xxxx - as first value
%xxxx0000 - as second value
so what formula for getting sound is? i am not understand. for DPCM this table have only 16 values, as 4bit - so every 4bit it was array index. but this case table is more bigger than 16 as 4 bit. how to know this formula?
Code: Select all
Macro ReverseBitsByte(v)
v = ((v >> 1) & $55) | ((v & $55) << 1);
v = ((v >> 2) & $33) | ((v & $33) << 2);
v = ((v >> 4) & $0F) | ((v & $0F) << 4);
EndMacro
Macro SwapNibbles(v)
v = ((v >> 4) & $0F) | ((v & $0F) << 4)
EndMacro
Global a.a = %10110110
ReverseBitsByte(a)
Debug RSet(Bin(a,#PB_Unicode),8,"0") ; result 01101101
SwapNibbles(a)
Debug RSet(Bin(a,#PB_Unicode),8,"0") ;result 11010110
Windows 11, Manjaro, Raspberry Pi OS
-
- Enthusiast
- Posts: 617
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Adaptive Differential Pulse Code Modulation
on our forum for bits operation used this code:
about reverse - i dont know for DPCM case it was more understandible, then that this ADPCM case. DPCM is used for Mortal Combat 3 game and MK3 Ultimate and Punisher.
original sample:
https://www.dropbox.com/s/xb5mukysib6wx ... 9.snd?dl=1
Code: Select all
Macro SetBit(Var, Bit)
Var | (Bit)
EndMacro
Macro ClearBit(Var, Bit)
Var & (~(Bit))
EndMacro
Macro TestBit(Var, Bit)
Bool(Var & (Bit))
EndMacro
Macro NumToBit(Num)
(1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
Code: Select all
Enumeration
#SNDCFGFile
#SNDSFXFile
#SNDSampleImage
EndEnumeration
;{
Macro SetBit(Var, Bit)
Var | (Bit)
EndMacro
Macro ClearBit(Var, Bit)
Var & (~(Bit))
EndMacro
Macro TestBit(Var, Bit)
Bool(Var & (Bit))
EndMacro
Macro NumToBit(Num)
(1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
;}
;dc.b 00H, 01H, 03H, 07H, 0DH, 15H, 1FH, 2BH
;dc.b -00H,-01H,-03H,-07H,-0DH,-15H,-1FH,-2BH
Global Dim pikarray.b(15)
pikarray(0) = 0
pikarray(1) = 1
pikarray(2) = 3
pikarray(3) = 7
pikarray(4) = $D
pikarray(5) = $15
pikarray(6) = $1F
pikarray(7) = $2B
pikarray(8) = 0
pikarray(9) = -1
pikarray(10) = -3
pikarray(11) = -7
pikarray(12) = -$D
pikarray(13) = -$15
pikarray(14) = -$1F
pikarray(15) = -$2B
Procedure WavHeaderCreation(*memst)
;RIFF
PokeB(*memst, $52):PokeB(*memst+1, $49):PokeB(*memst+2,$46):PokeB(*memst+3, $46)
;WAVE
PokeB(*memst+8, $57):PokeB(*memst+9, $41):PokeB(*memst+10,$56):PokeB(*memst+11, $45)
;fmt
PokeB(*memst+12, $66):PokeB(*memst+13, $6d):PokeB(*memst+14,$74):PokeB(*memst+15, $20)
;header size
PokeB(*memst+16, $10)
;PCM 01
PokeB(*memst+20, $01)
;mono stereo
PokeB(*memst+22, $01)
;1
PokeB(*memst+32, $01)
;bit
PokeB(*memst+34, $08)
;data
PokeB(*memst+36, $64)
PokeB(*memst+37, $61)
PokeB(*memst+38, $74)
PokeB(*memst+39, $61)
EndProcedure
If ReadFile(0, "D:\sample_49.snd")
length = Lof(0)
*sndsource = AllocateMemory(length)
If *sndsource
ReadData(0, *sndsource, length)
EndIf
CloseFile(0)
EndIf
If *sndsource
*snddest = AllocateMemory(length*2+44)
If *snddest
WavHeaderCreation(*snddest)
;size
PokeL(*snddest + 4, length*2+40)
PokeL(*snddest + 40, length*2)
;kbs
PokeL(*snddest + 24, 6500)
PokeL(*snddest + 28, 6500)
DPCMforwrite = $80 ; starting value
For i = 0 To length - 1 ; -1 it is end of file? i dont remember
inpval = PeekA(*sndsource+i)
first = GetBits(inpval, 0, 3) ; get %0000xxxx
second = GetBits(inpval, 4, 7) ; get %xxxx0000
DPCMforwrite + pikarray(first)
PokeB(*snddest + 44 + (i*2), DPCMforwrite)
DPCMforwrite + pikarray(second)
PokeB(*snddest + 44 + (i*2) + 1, DPCMforwrite)
Next
EndIf
EndIf
sndPlaySound_(*snddest,#SND_MEMORY | #SND_ASYNC | #SND_NODEFAULT)
Delay(2000)
;If CreateFile(0, "D:\demo.wav")
; WriteData(0, *snddest, length*2+44)
; CloseFile(0)
;EndIf
https://www.dropbox.com/s/xb5mukysib6wx ... 9.snd?dl=1
Re: Adaptive Differential Pulse Code Modulation
Good this code.
SND file format is an other format too.
What I am sure for ADPCM is replace this above with :
That is not a big code actually I give...
SND file format is an other format too.
Code: Select all
;PCM 01
PokeB(*memst+20, $01)
Code: Select all
;ADPCM 17
PokeB(*memst+20, $11)
-
- Enthusiast
- Posts: 617
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Adaptive Differential Pulse Code Modulation
.snd just custom extention for GEMS unpacked files. it have .raw - FM and PSG data for instruments, .sfx - header for sample with size and frequency flag, and etc values. .code - sequences data - notes, loops, pauses, durations.
this .snd can be normal 8bit mono, but same .snd can be this DPCM or ADPCM 4bit. frequency can be max quality as 10.4k.
in this code - DPCM sample converts into normal PCM, that is why PokeB(*memst+20, $01) for playing with winapi. but for my ugly-player i am not make this wav header. i am play it with special dll's procedure (this dll need to be fixed and it is not PB and i dont know where it have one small mistake). but this dll plays only normal PCM. if sample is DPCM or ADPCM - it need to be convert before. with DPCM i have formula, but for ADPCM is not. but, as i am say before - i am convert it by game it self and unpack normal PCM from VGM file. and now i am no need this ADPCM converting yet. but anyway this converting interesting things. i will study it too... someday... probably... maybe...
and this ADPCM, i think, not same as standart ADPCM. i think this table of values is custom case, not some windows standart, or wich one it is standart ADPCM. i think switching header flag will not help.
this .snd can be normal 8bit mono, but same .snd can be this DPCM or ADPCM 4bit. frequency can be max quality as 10.4k.
in this code - DPCM sample converts into normal PCM, that is why PokeB(*memst+20, $01) for playing with winapi. but for my ugly-player i am not make this wav header. i am play it with special dll's procedure (this dll need to be fixed and it is not PB and i dont know where it have one small mistake). but this dll plays only normal PCM. if sample is DPCM or ADPCM - it need to be convert before. with DPCM i have formula, but for ADPCM is not. but, as i am say before - i am convert it by game it self and unpack normal PCM from VGM file. and now i am no need this ADPCM converting yet. but anyway this converting interesting things. i will study it too... someday... probably... maybe...
and this ADPCM, i think, not same as standart ADPCM. i think this table of values is custom case, not some windows standart, or wich one it is standart ADPCM. i think switching header flag will not help.
Re: Adaptive Differential Pulse Code Modulation
There is 3 versions of ADPCM
1) reversed : read B before A
2) read A before B
3) read A and point it in a 16 pre-calculated values array, then read B and point it in the same 16 values array (telephony)
I think what, it interest us is the 2nd version. Maybe the 1st, but it is not very different.
http://www.cs.columbia.edu/~hgs/audio/dvi/
There are near 40 pages : could you read them, or not ? The image format can prevent you to have a good translating.
Page 34 gives an algo to convert 4 bits ADPCM to 16 bits PCM.
This can be inserted in your code. Note the 2 arrays to store earlier.
1) 16 values array is 'step index table'
2) 89 values array is 'step size table'
Note that, for each converting unit, the 16-bits final value is calculated as you writed above :
more accurately:
Excepted $11 format code instead of $1, the file header does not have more datas whatever we have PCM or ADPCM sound.
Code: Select all
a byte containing 2 quartets A B
7 6 5 4 3 2 1 0
a a a a b b b b
A B
2) read A before B
3) read A and point it in a 16 pre-calculated values array, then read B and point it in the same 16 values array (telephony)
I think what, it interest us is the 2nd version. Maybe the 1st, but it is not very different.
http://www.cs.columbia.edu/~hgs/audio/dvi/
There are near 40 pages : could you read them, or not ? The image format can prevent you to have a good translating.
Page 34 gives an algo to convert 4 bits ADPCM to 16 bits PCM.
This can be inserted in your code. Note the 2 arrays to store earlier.
1) 16 values array is 'step index table'
2) 89 values array is 'step size table'
Note that, for each converting unit, the 16-bits final value is calculated as you writed above :
Code: Select all
final+stepSize
Code: Select all
For each ADPCM 4-bits value...
x = BitOp(x, ADPCM) ; procedure
step+stepIndex(x + ADPCM) ; 16 values array
step = saturate(step, 0, 15) ; procedure
Final+Stepsize(step) ; 89 values array
Final = saturate(Final, -32768, 32767)
PCM = final
next ADPCM value...
-
- Enthusiast
- Posts: 617
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Adaptive Differential Pulse Code Modulation
i think final result must be 8bit, not 16. about documents - english not very mine language. and even worse - technical info. translate not very help.
original 4 bit data:
converted 8 bit data
not clear for me, how to use that table with $F0 values from sound driver.
original 4 bit data:
Code: Select all
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 01 9A BB 39 87 69 68 36 A4 88 4A BE EC 5D A7 94
Code: Select all
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 80 81 83 86 89 83 84 84 83 81 82 80 80 7A 78 7A
00000010 75 75 75 70 72 75 7D 85 8A 87 8D 8F 8E 8F 8A 84
Re: Adaptive Differential Pulse Code Modulation
We have a similar problem here : our english neighbours drive on the left in the road, as we drive in the right in the road in France...i think final result must be 8bit, not 16
You have 8 bits PCM certainly due to the age of the standard. That s all. And I forget to tell you this option must be set in the file header too.
But if we want to listen a sound on a recent hardware, we must consider first ADPCM provides 16 bits linear digit, and is provided by 16 bits linear digit.
ADPCM (4 bits) ---> PCM (16 bits)
PCM (16 bits) ---> ADPCM (4 bits)
It is only after these first flow converting you do a second converting level to transform 16 bits PCM to 8 bits PCM.
It is an other process to add.
Synthesis :
4 bits ADPCM <----> 16 bits PCM <----> 8 bits PCM
Algo references :
ADPCM (4 bits) ---> PCM (16 bits)
PCM (16 bits) ---> ADPCM (4 bits) (1/2)
PCM (16 bits) ---> ADPCM (4 bits) (2/2)
PCM (8 bits) ---> PCM (16 bits)
PCM (16 bits) ---> PCM (8 bits)