i have some limitations for samples for old Genesis\Mega Drive 2 games: mono, 8bit, 10.4 to 5khz, PCM. i mean some kind of database with that samples. and i have target - mono, 4bit, 6500mhz, DPCM.
i am trying to do this by this steps:
1. first is convert any other mhz exept 6500 - into that 6500. i am do this will bass.dll and it works fine (probably

)
2. then i try to encode this 6500 8bit PCM into 4bit DPCM.
i have some table, that decode original samples - it have 16 values. with decode no any problem. then i try to make same like table, but for back operation. and with original samples - no any problem. encode and decode work fine. but when i try to use another 8bit samples - it encode something wrong... and a few days i try to find all my mistake. and probably i found them and fix and looks like fine now, but anyway final quality is not very well.
is this some secret or trick exist? just remember what quality of sound with Mortal Kombat 3 for Genesis\Mega Drive 2 game. when imperor says some Finish Him, Flawless Victory, when says names of characters - quality is nice. it is same 4bit DPCM, but decoded into 8bit 6500mhz with that table for playing. can i get same quality? what i should do? table have a severe restrictions - so it cant be very high piks of wav. maybe for that high piks i need some procedure for a little cut values and then make encode?
white - original 8bit, blue - that was encoded and decoded back. it is not mk3 samples, it is not prepeared another game. just resampling into 6500mhz (from 10400mhz).

DataSection
datajim8bit:
;IncludeBinary "D:\Temp\MK3\sounddump.bin"
IncludeBinary "D:\Temp\MK3\GEMS1\030\sample_59.snd"
enddatajim8bit:
; for sound playing. winapi not wants to play 6500mhz sample. or maybe i am just make wrong wav header
; so i use another dll for play sample. can be kicked
StartOPNDLL:
IncludeBinary "F:\DISTR\SEREGASOFT\DUNE\DUE\DUEmodules\OPN_DLL.dll"
EndOPNDLL:
EndDataSection
Enumeration
#Window
#Canvas
#Button
#Button2
#TrackBar
#Progr
EndEnumeration
; can be kicked. needed for play button
XIncludeFile "F:\DISTR\SEREGASOFT\DUNE\DUE\DUEmodules\DllFromMememory.pbi"
XIncludeFile "F:\DISTR\SEREGASOFT\DUNE\DUE\DUEmodules\OPNDLLImport.pb"
; original decode table.
Global Dim pikarray.b(15) ;{
pikarray(0) = 0
pikarray(1) = 1
pikarray(2) = 3
pikarray(3) = 7
pikarray(4) = $D ; 13
pikarray(5) = $15 ; 21
pikarray(6) = $1F ; 31
pikarray(7) = $2B ; 43
pikarray(8) = 0
pikarray(9) = -1
pikarray(10) = -3
pikarray(11) = -7
pikarray(12) = -$D ; -13
pikarray(13) = -$15 ; -21
pikarray(14) = -$1F ; -31
pikarray(15) = -$2B ; -43
;}
;{ bits operations
Macro NumToBit(Num)
(1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
;}
; paint image on a window
Procedure CanvPaint(forot.l, fordo.l, box.a, xshif.a)
If StartDrawing(CanvasOutput(#Canvas))
If box
Box(0, 0, 880, 280, 0)
Line(0, $80, 880, 1, RGB(0, 200, 0))
color = RGB(240, 240, 240)
Else
color = RGB(80, 80, 250)
EndIf
x = 10
oldx = 0
oldy = $80
For m = forot To fordo
y = PeekA(m)
;If box : Debug y : EndIf
; count direction
; x always bigger oldx
If y <> oldy
height = oldy - y
Else
height = 1
EndIf
Line(x, y, oldx - x, height, color)
oldx = x
oldy = y
x + xshif
Next
StopDrawing()
EndIf
EndProcedure
; i try to make table for back operation
Procedure.a GetEncodeValue(value.w)
ret.a = 0
Select value
Case 0
ret = 0
Case 1 To 2
ret = 1
Case 3 To 6
ret = 2
Case 7 To 12
ret = 3
Case 13 To 20
ret = 4
Case 21 To 30
ret = 5
Case 31 To 42
ret = 6
Case 43 To 300
ret = 7
Case -2 To -1
ret = 9
Case -6 To -3
ret = 10
Case -12 To -7
ret = 11
Case -20 To -13
ret = 12
Case -30 To -21
ret = 13
Case -42 To -31
ret = 14
Case -300 To -43
ret = 15
EndSelect
ProcedureReturn ret
EndProcedure
; main encode procedure 8bit into 8bit
Procedure DPCMEncode(forstart.l, forend.l, memory.l)
Number.a
OldNumber.w
TestValue.w
FlagOrder.a
First.a
Second.a
MemShift.l
OldNumber = $80 ; 0x80
FlagOrder = 0
MemShift = 0
For m = forstart To forend ; 8bit memory cycle
If FlagOrder = 0
FlagOrder = 1
Number = PeekA(m) ; read from mem
TestValue = Number - OldNumber ; count value
First = GetEncodeValue(TestValue) ; get value from table
OldNumber = OldNumber + pikarray(First) ;Number
Else
FlagOrder = 0
Number = PeekA(m) ; read from mem
TestValue = Number - OldNumber ; count value
Second = GetEncodeValue(TestValue) ; get value from table
OldNumber = OldNumber + pikarray(Second) ;Number
PokeA(memory + MemShift, second << 4 + first) ; write into memory encoded byte
MemShift + 1 ; move memory pointer to next byte
EndIf
Next
EndProcedure
; decode 4bit into 8bit
Procedure DPCMDecode(forstart.l, size.l, memory.l)
Number.a
MemShift.l
MemWriteValue.b
MemShift = 0
MemWriteValue = $80
For m = forstart To forstart + size - 1 ; 4bit memory cycle
Number = PeekA(m)
; split 8bit value into two 4bit
DPCMfirst = GetBits(Number, 0, 3) ; get %0000xxxx
DPCMsecond = GetBits(Number, 4, 7) ; get %xxxx0000
MemWriteValue + pikarray(DPCMfirst)
PokeB(memory + MemShift, MemWriteValue)
MemShift + 1
MemWriteValue + pikarray(DPCMsecond)
PokeB(memory + MemShift, MemWriteValue)
MemShift + 1
Next
EndProcedure
Global OldTrackBarValue
Global oldposition
Global DecodedMem
Global DecodedMemSize
; scroll bar events. not accurate, but fine
Procedure ProgrProc()
tmp = GetGadgetState(#Progr)
If tmp <> oldposition
oldposition = tmp
startfrom = ?datajim8bit + oldposition
If startfrom > ?enddatajim8bit
startfrom = ?enddatajim8bit - (880 / OldTrackBarValue)
EndIf
; paint original 8bit
CanvPaint(startfrom, startfrom + (880 / OldTrackBarValue), 1, OldTrackBarValue)
startfrom = DecodedMem + oldposition
If startfrom > DecodedMem + DecodedMemSize
startfrom = DecodedMem + DecodedMemSize - (880 / OldTrackBarValue)
EndIf
; paint encoded and then decoded for compare
CanvPaint(startfrom, startfrom + DecodedMemSize - 1, 0, OldTrackBarValue)
EndIf
EndProcedure
; can be kicked. for playing
OpenOPNDriver(1)
OPN_Write(0, $2B, $80)
OldTrackBarValue = 5
If OpenWindow(#Window, 100, 100, 900, 340, "")
CanvasGadget(#Canvas, 10, 10, 880, 280)
ScrollBarGadget(#Progr, 10, 290, 880, 10, 1, 100, 10)
ButtonGadget(#Button, 10, 310, 50, 20, "play")
TrackBarGadget(#TrackBar, 100, 310, 100, 20, 1, 10)
SetGadgetState(#TrackBar, OldTrackBarValue)
ButtonGadget(#Button2, 400, 310, 50, 20, "dump")
CanvPaint(?datajim8bit, ?enddatajim8bit - 1, 1, OldTrackBarValue)
; encode
size = ?enddatajim8bit - ?datajim8bit ; count memory size, what need for encoded
size = size / 2
If size
EncodedMem = AllocateMemory(size)
If EncodedMem ; * 2 = for avoide odd-numbered
DPCMEncode(?datajim8bit, ?datajim8bit + (size * 2), EncodedMem)
Else
Debug "mem problem"
EndIf
EndIf
; decode
If EncodedMem
decodedsize = size * 2
DecodedMem = AllocateMemory(decodedsize)
If DecodedMem
DPCMDecode(EncodedMem, size, DecodedMem)
CanvPaint(DecodedMem, DecodedMem + decodedsize - 1, 0, OldTrackBarValue)
SetGadgetAttribute(#Progr, #PB_ScrollBar_Maximum, decodedsize)
DecodedMemSize = decodedsize
Else
Debug "mem problem"
EndIf
EndIf
BindGadgetEvent(#Progr, @ProgrProc())
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case #Button ; play
If EventType() = #PB_EventType_LeftClick
If DecodedMem
PlayDACSample(0, decodedsize, DecodedMem, 6500)
EndIf
EndIf
Case #Button2 ; dump
If EventType() = #PB_EventType_LeftClick
startfrom = ?datajim8bit + GetGadgetState(#Progr)
If CreateFile(0, "D:\sounddump.bin")
WriteData(0, startfrom, 880 / OldTrackBarValue)
CloseFile(0)
EndIf
EndIf
Case #TrackBar ; resolution of image
If EventType() = #PB_EventType_LeftClick
NewTrackBarValue = GetGadgetState(#TrackBar)
If NewTrackBarValue <> OldTrackBarValue
OldTrackBarValue = NewTrackBarValue
CanvPaint(?datajim8bit, ?enddatajim8bit - 1, 1, OldTrackBarValue)
If DecodedMem
CanvPaint(DecodedMem, DecodedMem + decodedsize - 1, 0, OldTrackBarValue)
EndIf
EndIf
EndIf
EndSelect
Case #PB_Event_CloseWindow
qiut = 1
EndSelect
Until qiut = 1
EndIf
End
this is one original mk3's sample. not seen white line, because blue exactly 100% on white. and it have high pik, but they reach for a few steps, not like before from low to high at one step. one step cant be bigger than 43 value.

any ideas how they are, at 90's, get some nice quality of phrases and how to get somelike quality with encoded-decoded? or i need not 6500 as input samples, but some high quality 16-32 bit 44100mhz samples to get same with output?