forked from vgmstream/vgmstream
-
Notifications
You must be signed in to change notification settings - Fork 0
bnnm edited this page Feb 17, 2024
·
1 revision
Collection of decomps used to figure out random codecs before being added to vgmstream.
Mostly useless but kept for historical(?) reasons and maybe to inspire neophytes.
You probably want to use IDA/Ghidra's decompiled pseudo-code rather than raw assembly, but sometimes it's good to double check.
* decode N frames, mono version (there is another for stereo, basically the same)
sub_26E02269
arg_0 = dword ptr 8
arg_4 = dword ptr 0Ch
arg_8 = dword ptr 10h
push ebp #prepare procedure stuff
mov ebp, esp
push ebp
push esi
push edi
push edx
push ecx
push ebx
push eax
mov eax, [ebp+arg_8] #prepare data pointer stuff
mov dword_26E071E0, eax
mov esi, [ebp+arg_4]
mov edi, [ebp+arg_0]
loc_26E02281:
movzx ecx, byte ptr [esi] #header = load unsigned from frame
inc esi #*data += 1 //skip header
mov ebx, ecx #mode = header
and ebx, 4 #mode &= 4 // 0 or 1, used below to select the function
shr ecx, 4 #shift = header >>= 4
#off_26E071D8[2] = { mode0, mode4 } function pointers
add ebx, offset off_26E071D8 #get function pointer +0/1 depending on mode
call dword ptr [ebx] #enter function to process all frame nibbles
dec dword_26E071E0 #decrease num_frames, probably?
jnz short loc_26E02281 #keep processing frames
pop eax #clean procedure stuff
pop ebx
pop ecx
pop edx
pop edi
pop esi
pop ebp
leave
retn 0Ch
sub_26E02269 endp
**************************************
* Parse left/mono frame, mode0
(there is another function for right block, loading ch1 hist)
sub_26E022A8
add ecx, 2 #shift += 2
movsx eax, word ptr [edi-4] #hist1 = load signed ch0-hist1 from buffer
shl eax, 6 #hist1 <<= 6
movsx edx, byte ptr [esi] #byte = load signed nibbles
and edx, 0FFFFFFF0h #sample = (byte & 0xFFFFFFF0) //get high nibble (signed)
shl edx, cl #sample <<= (shift & 0xFF)
add eax, edx #sample += hist1
sar eax, 6 #sample >>= 6
mov [edi], ax #write (int16)sample (cast instead of clamp16)
add edi, 4 #move sample buffer pointer
#implicit: hist1 = sample, still in eax
shl eax, 6 #hist1 <<= 6
movzx edx, byte ptr [esi] #byte = load unsigned nibbles
and edx, 0Fh #sample = (byte & 0x0F) //get low nibble (unsigned)
shl edx, 4 #sample <<= 4 //low nibble to high nibble
movsx edx, dl #sample = (int8)sample //move and sign-extend 8b into itself
shl edx, cl #sample <<= (shift & 0xFF)
add eax, edx #sample += hist1
sar eax, 6 #sample >>= 6
mov [edi], ax #write (int16)sample (cast instead of clamp16)
add edi, 4 #move sample buffer pointer
... #same for all other nibbles
**************************************
* Parse left/mono frame, mode4
(there is another function for right block, loading ch1 hist)
sub_26E025E0
add ecx, 2 #shift += 2
movsx eax, word ptr [edi-4] #hist1 = load signed ch0-hist1 from buffer
shl eax, 7 #hist1 <<= 7
mov ebx, eax #(move hist1 around)
movsx eax, word ptr [edi-8] #hist2 = load signed ch0-hist2 from buffer
neg eax #hist2 = -hist2
shl eax, 6 #hist2 <<= 6
movsx edx, byte ptr [esi] #byte = load signed nibbles
and edx, 0FFFFFFF0h #sample = (byte & 0xFFFFFFF0) //get high nibble (signed)
shl edx, cl #sample <<= (shift & 0xFF)
add eax, edx #sample += hist2 //hist2 is negative here, thus sample - hist2
adc eax, ebx #sample += hist1
sar eax, 6 #sample >>= 6
mov [edi], ax #write (int16)sample (cast instead of clamp16)
add edi, 4 #move sample buffer pointer
#implicit: hist1 = sample, still in eax
shl eax, 7 #hist1 <<= 7
mov ebx, eax #(move hist1 around)
movsx eax, word ptr [edi-8] #hist2 = load signed ch0-hist2 from buffer
neg eax #hist2 = -hist2
shl eax, 6 #hist2 <<= 6
movzx edx, byte ptr [esi] #byte = load signed nibbles
and edx, 0Fh #sample = (byte & 0x0F) //get low nibble (unsigned)
shl edx, 4 #sample <<= 4 //low nibble to high nibble
movsx edx, dl #sample = (int8)sample //move and sign-extend 8b into itself
shl edx, cl #sample <<= (shift & 0xFF)
add eax, edx #sample += hist2 //hist2 is negative here, thus sample - hist2
adc eax, ebx #sample += hist1
sar eax, 6 #sample >>= 6
mov [edi], ax #write (int16)sample (cast instead of clamp16)
add edi, 4 #move sample buffer pointer
... #same for all other nibbles
# MSADPCM with changed nibble and hist order, other stuff seems the same
sub_4125A0 proc near ; CODE XREF: sub_4016F0+81↑p
var_1C = dword ptr -1Ch
var_18 = dword ptr -18h
var_14 = dword ptr -14h
var_10 = dword ptr -10h
var_C = dword ptr -0Ch
var_8 = dword ptr -8
var_4 = dword ptr -4
arg_0 = dword ptr 8
arg_4 = dword ptr 0Ch
arg_8 = dword ptr 10h
arg_C = dword ptr 14h
* push edi # ? save ?
push esi # ? save ?
push ebp #
mov ebp, esp #
sub esp, 1Ch # ? samples_left -= 28
mov edx, [ebp+arg_0] # load p_frame
mov eax, [ebp+arg_4] # load p_next_frame //value: frame_size = 0x18
add eax, edx # p_next_frame += p_frame //
push ebx # ? save p_buffer
mov esi, [ebp+arg_8] # ? load p_buffer?
mov [ebp+var_8], eax # save p_next_frame
mov al, [edx] # coef_index = (uint8)*p_frame[0]
mov di, [edx+1] # scale = (uint16)*p_frame[1]
mov cx, [edx+3] # hist2 = (uint16)*p_frame[3] //msadpcm does hist1 first (ex: BGM_Drum_LP writes fff0,fe62 in header order)
mov bx, [edx+5] # hist1 = (uint16)*p_frame[5]
add edx, 5 # p_frame += 5
mov [ebp+arg_0], edx # (save p_frame)
mov edx, [ebp+arg_C] # channels = 2
mov [esi], cx # *p_buffer = hist2
mov [ebp+var_1C], esi # ? save p_buffer
lea esi, [esi+edx*2] # p_buffer += channels*2 //move buffer depending on channels
add edx, edx # channels += channels //channels*2
mov [esi], bx # *p_buffer = hist1
add esi, edx # p_buffer += channels //
movzx eax, al # (coef_index &= 0xFF)
mov edx, [ebp+arg_0] # (load p_frame)
add edx, 2 # p_frame += 2 //AKA: p_frame at nibbles start
mov [ebp+arg_8], esi # ? save p_buffer
mov [ebp+arg_0], edx # ? save p_frame
mov esi, dword_463084[eax*8] # coef1 = msadpcm_table[coef_index*8+0]
mov eax, dword_463088[eax*8] # coef2 = msadpcm_table[coef_index*8+1]
mov [ebp+var_14], esi # (save coef1)
mov [ebp+var_18], eax # (save coef2)
cmp edx, [ebp+var_8] # if (p_frame > p_next_frame)
jnb loc_412709 # TRUE: end frame
lea ebx, [ebx+0] # FALS: nop???
loc_412610: #(loop A)
mov [ebp+var_4], 0 # scale = 0
loc_412617: #(loop B)
movsx ecx, cx # hist2 = signed(hist2)
imul ecx, eax # predicted = hist2 * coef2
movsx eax, bx # hist1 = signed(hist1)
imul eax, esi # predicted += hist1 * coef1
add eax, ecx # sample = hist1 + hist2
mov cl, byte ptr [ebp+var_4] # ? load nibble_shift //(low first)
cdq # sign extend eax into edx
and edx, 0FFh # ?
shl cl, 2 # nibble_shift <<= 2
lea esi, [edx+eax] # ? predicted = ? + predicted
sar esi, 8 # predicted >>= 8
* mov eax, [ebp+arg_0] # (load p_frame)
movzx edx, byte ptr [eax] # load (uint8)byte
shr edx, cl # nibble >>= nibble_shift
and edx, 0Fh # nibble &= 0xf
movsx ecx, di # scale = signed(scale)
mov [ebp+arg_4], edx # (save nibble)
test dl, 8 # if (nibble is ???)
jz short loc_412656 #
lea eax, [edx-10h] # load scale
imul eax, ecx # nibble *= scale
jmp short loc_41265B #
loc_412656: ; CODE XREF: sub_4125A0+AC↑j
mov eax, ecx # ?
imul eax, edx # ?
#(clamp16)
loc_41265B:
add esi, eax # predicted += nibble
cmp esi, 0FFFF8000h # if (predicted < -32768)
jge short loc_41266C # T: ignore
mov esi, 0FFFF8000h # F: predicted = -32768
jmp short loc_41267A #
loc_41266C:
cmp esi, 7FFFh # if (predicted > 32767)
mov eax, 7FFFh # (prepare)
cmovg esi, eax # F: predicted = 32767
loc_41267A:
mov edi, [ebp+arg_8] # (load p_buffer)
mov edx, [ebp+arg_C] # (load channels)
mov [edi], si # *p_buffer = predicted
lea edi, [edi+edx*2] # p_buffer += channels*2
* mov [ebp+arg_8], edi # (save p_buffer)
mov edx, [ebp+arg_4] # (load nibble)
mov eax, ds:dword_43BC38[edx*4] # step = msadpcm_steps[nibble]
imul eax, ecx # step *= scale
cdq # ? copy sign to edx
and edx, 0FFh # ?
add eax, edx # step += ?
mov edx, 10h #
sar eax, 8 # step >> 8
movzx eax, ax # ? adjust new scale to 0x10
cmp ax, 10h #
mov [ebp+arg_4], eax #
cmovl eax, edx #
mov [ebp+arg_4], eax #
movzx eax, bx #
mov [ebp+var_10], eax #
movzx eax, si #
mov [ebp+var_C], eax #
mov eax, [ebp+var_4] #
inc eax #
mov [ebp+var_4], eax #
cmp eax, 2 #
jge short loc_4126E6 #
mov di, word ptr [ebp+arg_4] #
mov bx, word ptr [ebp+var_C] #
mov cx, word ptr [ebp+var_10] #
mov esi, [ebp+var_14] # (restore coef1)
mov eax, [ebp+var_18] # (restore coef2)
jmp loc_412617 # loopB next byte
; ---------------------------------------------------------------------------
loc_4126E6: ; CODE XREF: sub_4125A0+12D↑j
mov eax, [ebp+arg_0] #
inc eax #
mov [ebp+arg_0], eax #
cmp eax, [ebp+var_8] #
jnb short loc_41270C #
mov di, word ptr [ebp+arg_4] #
mov bx, word ptr [ebp+var_C] #
mov cx, word ptr [ebp+var_10] #
mov esi, [ebp+var_14] # (restore coef1)
mov eax, [ebp+var_18] # (restore coef2)
jmp loc_412610 # loopB next byte
; ---------------------------------------------------------------------------
loc_412709: ; CODE XREF: sub_4125A0+64↑j
mov edi, [ebp+arg_8] #
loc_41270C: ; CODE XREF: sub_4125A0+150↑j
sub edi, [ebp+var_1C] #
sar edi, 1 #
mov eax, edi #
pop edi #
cdq #
idiv [ebp+arg_C] #
pop esi #
pop ebx # restore
mov esp, ebp #
pop ebp #
retn #
sub_4125A0 endp #
sub_4F14C0 proc near ; CODE XREF: sub_4F1800+3D↓p
; sub_4F1800+69↓p ...
arg_0 = dword ptr 4
arg_4 = dword ptr 8
arg_8 = dword ptr 0Ch
arg_C = dword ptr 10h
mov edx, [esp+arg_C] #
test edx, edx #
jz locret_4F17D8 #
mov eax, [esp+arg_4] #
shr edx, 1 #
mov [ecx+10h], edx #
mov edx, [esp+arg_8] #
push ebx #
shr edx, 1 #
push ebp #
mov [ecx+4], eax #
add eax, edx #
push esi #
mov esi, [esp+0Ch+arg_0] #
xor edx, edx #
cmp [ecx+28h], dl #
push edi #
mov [ecx], esi #
mov [ecx+18h], eax #
mov [ecx+1Ch], esi #
mov edi, 7 #
jz loc_4F15AF #
mov [ecx+28h], dl #
xor edx, edx #
mov dl, [eax] #
and edx, 0Fh #
inc eax #
mov [ecx+18h], eax #
mov eax, edx #
mov [ecx+14h], edx #
sar eax, 2 #
* mov ebp, 2 #
and eax, ebp # sample &=2
mov edx, 1 #
sub edx, eax #
mov eax, [ecx+14h] #
and eax, edi #
mov [ecx+20h], edx #
mov edx, [ecx+8] #
mov [ecx+14h], eax #
mov edx, [ecx+edx*4+2Ch] #
imul edx, eax #
mov eax, edx #
sar eax, 3 #
sar edx, 2 #
add eax, edx #
imul eax, [ecx+20h] #
mov edx, [ecx+0Ch] #
add edx, eax # sample += sample
mov [ecx+24h], eax
mov eax, edx # (copy sample)
# (clamp)
* mov ebx, 7FFFh # (test = 32767)
cmp eax, ebx # if(sample > 32767)
mov [ecx+0Ch], edx # (save sample)
jle short loc_4F1562 # FALS: goto -32768
mov [ecx+0Ch], ebx # TRUE: sample = 32767
jmp short loc_4F1570 #
; ---------------------------------------------------------------------------
loc_4F1562: ; CODE XREF: sub_4F14C0+9B↑j
cmp eax, 0FFFF8000h # if(sample <= -32768)
jge short loc_4F1570 #
mov dword ptr [ecx+0Ch], 0FFFF8000h # sample = -32768
loc_4F1570: ; CODE XREF: sub_4F14C0+A0↑j
; sub_4F14C0+A7↑j
mov ax, [ecx+0Ch] # ? load sample
mov [esi], ax # ? save sample
mov eax, [ecx+1Ch] # ? table stuff
mov esi, [ecx+8] #
add eax, ebp #
mov [ecx+1Ch], eax #
mov eax, [ecx+14h] #
mov eax, [ecx+eax*4+190h] #
add esi, eax # step_index += table
mov edx, 1 #
mov [ecx+8], esi # (save step_index)
mov eax, esi #
jns short loc_4F15A3 # if(step_index < 0)
mov dword ptr [ecx+8], 0 # step_index = 0
jmp short loc_4F15AF #
loc_4F15A3: ; CODE XREF: sub_4F14C0+D8↑j
cmp eax, 58h # if(step_index > 88)
jle short loc_4F15AF # FALS: ignore
mov dword ptr [ecx+8], 58h # TRUE: step_index = 88
#
loc_4F15AF: ; CODE XREF: sub_4F14C0+44↑j
; sub_4F14C0+E1↑j ...
mov eax, [ecx+10h] #
mov esi, [esp+10h+arg_C] #
lea edx, [edx+eax*2] #
cmp edx, esi #
mov [esp+10h+arg_0], edx #
jbe short loc_4F15CB #
sub edx, ebp #
dec eax #
mov [esp+10h+arg_0], edx #
mov [ecx+10h], eax #
loc_4F15CB: ; CODE XREF: sub_4F14C0+FF↑j
mov eax, [ecx+10h]
test eax, eax
jz loc_4F1727
# upper nibble
loc_4F15D6: ; CODE XREF: sub_4F14C0+25D↓j
mov edx, [ecx+18h] # load? p_frame
movzx eax, byte ptr [edx] # byte = (uint8)*p_frame
shr eax, 4 # byte >>= 4 //upper nibble
mov [ecx+14h], eax # save unsigned nibble
#(bizarro get sign)
sar eax, 2 # nibble >>= 2
and eax, ebp # nibble &= 2
mov edx, 1 # sign = 1
sub edx, eax # sign -= nibble //should get sign
* mov [ecx+20h], edx # save sign
mov eax, [ecx+14h] # load unsigned nibble
and eax, edi # nibble &= 7
mov edx, [ecx+8] # ? load step_index?
mov [ecx+14h], eax # save nibble
mov edx, [ecx+edx*4+2Ch] # ? load step
imul edx, eax # step *= nibble
mov eax, edx # delta = step
sar eax, 3 # delta >>= 3
sar edx, 2 # step >>= 2
add eax, edx # delta += step
imul eax, [ecx+20h] # delta *= sign
# AKA: (signed)(nibble*step>>3 + nibble*step>>2)
* mov esi, [ecx+0Ch] # load hist1
add esi, eax # hist1 += delta
mov [ecx+24h], eax # (save delta? useless)
mov eax, esi # sample = hist
cmp eax, ebx # clamp sample
mov [ecx+0Ch], esi
jle short loc_4F1627
mov [ecx+0Ch], ebx
jmp short loc_4F1635
; ---------------------------------------------------------------------------
loc_4F1627: ; CODE XREF: sub_4F14C0+160↑j
cmp eax, 0FFFF8000h
jge short loc_4F1635
mov dword ptr [ecx+0Ch], 0FFFF8000h
loc_4F1635: ; CODE XREF: sub_4F14C0+165↑j
; sub_4F14C0+16C↑j
mov eax, [ecx+1Ch]
mov dx, [ecx+0Ch]
mov [eax], dx
mov edx, [ecx+1Ch]
mov eax, [ecx+14h]
add edx, ebp
mov [ecx+1Ch], edx
mov esi, edx
mov edx, [ecx+eax*4+190h]
mov eax, [ecx+8]
add eax, edx
mov [ecx+8], eax
jns short loc_4F1666
mov dword ptr [ecx+8], 0
jmp short loc_4F1672
; ---------------------------------------------------------------------------
loc_4F1666: ; CODE XREF: sub_4F14C0+19B↑j
cmp eax, 58h
jle short loc_4F1672
mov dword ptr [ecx+8], 58h
loc_4F1672: ; CODE XREF: sub_4F14C0+1A4↑j
; sub_4F14C0+1A9↑j
mov eax, [ecx+18h]
xor edx, edx
mov dl, [eax]
and edx, 0Fh
inc eax
mov [ecx+18h], eax
mov eax, edx
mov [ecx+14h], edx
sar eax, 2
and eax, ebp
mov edx, 1
sub edx, eax
mov eax, [ecx+14h]
and eax, edi
mov [ecx+20h], edx
mov edx, [ecx+8]
mov [ecx+14h], eax
mov edx, [ecx+edx*4+2Ch]
imul edx, eax
mov eax, edx
sar eax, 3
sar edx, 2
add eax, edx
imul eax, [ecx+20h]
mov edx, [ecx+0Ch]
add edx, eax
mov [ecx+24h], eax
mov eax, edx
cmp eax, ebx
mov [ecx+0Ch], edx
jle short loc_4F16CA
mov [ecx+0Ch], ebx
jmp short loc_4F16D8
; ---------------------------------------------------------------------------
loc_4F16CA: ; CODE XREF: sub_4F14C0+203↑j
cmp eax, 0FFFF8000h
jge short loc_4F16D8
mov dword ptr [ecx+0Ch], 0FFFF8000h
loc_4F16D8: ; CODE XREF: sub_4F14C0+208↑j
; sub_4F14C0+20F↑j
mov ax, [ecx+0Ch]
mov [esi], ax
mov esi, [ecx+1Ch]
mov edx, [ecx+14h]
add esi, ebp
mov [ecx+1Ch], esi
mov eax, [ecx+edx*4+190h]
mov edx, [ecx+8]
add edx, eax
mov [ecx+8], edx
mov eax, edx
jns short loc_4F1706
mov dword ptr [ecx+8], 0
jmp short loc_4F1712
; ---------------------------------------------------------------------------
loc_4F1706: ; CODE XREF: sub_4F14C0+23B↑j
cmp eax, 58h
jle short loc_4F1712
mov dword ptr [ecx+8], 58h
loc_4F1712: ; CODE XREF: sub_4F14C0+244↑j
; sub_4F14C0+249↑j
mov edx, [ecx+10h]
dec edx
mov eax, edx
test eax, eax
mov [ecx+10h], edx
jnz loc_4F15D6
mov edx, [esp+10h+arg_0]
loc_4F1727: ; CODE XREF: sub_4F14C0+110↑j
cmp edx, [esp+10h+arg_C]
jnb loc_4F17D4
mov edx, [ecx+18h]
mov byte ptr [ecx+28h], 1
movzx eax, byte ptr [edx]
shr eax, 4
mov [ecx+14h], eax
sar eax, 2
and eax, ebp
mov edx, 1
sub edx, eax
mov eax, [ecx+14h]
and eax, edi
mov [ecx+20h], edx
mov edx, [ecx+8]
mov [ecx+14h], eax
mov edx, [ecx+edx*4+2Ch]
mov esi, [ecx+0Ch]
imul edx, eax
mov eax, edx
sar eax, 3
sar edx, 2
add eax, edx
imul eax, [ecx+20h]
add esi, eax
mov [ecx+24h], eax
mov eax, esi
cmp eax, ebx
mov [ecx+0Ch], esi
jle short loc_4F1786
mov [ecx+0Ch], ebx
jmp short loc_4F1794
; ---------------------------------------------------------------------------
loc_4F1786: ; CODE XREF: sub_4F14C0+2BF↑j
cmp eax, 0FFFF8000h
jge short loc_4F1794
mov dword ptr [ecx+0Ch], 0FFFF8000h
loc_4F1794: ; CODE XREF: sub_4F14C0+2C4↑j
; sub_4F14C0+2CB↑j
mov eax, [ecx+1Ch]
mov dx, [ecx+0Ch]
mov [eax], dx
mov edx, [ecx+1Ch]
mov eax, [ecx+14h]
add edx, ebp
mov [ecx+1Ch], edx
mov edx, [ecx+eax*4+190h]
mov eax, [ecx+8]
add eax, edx
mov [ecx+8], eax
jns short loc_4F17C8
pop edi
pop esi
pop ebp
mov dword ptr [ecx+8], 0
pop ebx
retn 10h
; ---------------------------------------------------------------------------
loc_4F17C8: ; CODE XREF: sub_4F14C0+2F8↑j
cmp eax, 58h
jle short loc_4F17D4
mov dword ptr [ecx+8], 58h
loc_4F17D4: ; CODE XREF: sub_4F14C0+26B↑j
; sub_4F14C0+30B↑j
pop edi
pop esi
pop ebp
pop ebx
locret_4F17D8: ; CODE XREF: sub_4F14C0+6↑j
retn 10h
sub_4F14C0 endp
sub_17AE0
var_8 = dword ptr -8
var_1 = byte ptr -1
arg_0 = dword ptr 8
arg_4 = dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 8
push ebx
mov [ebp+var_1], 7
mov eax, [ebp+arg_4]
mov ebx, [ebp+arg_0]
mov cl, [eax]
mov [ebx], cl
inc eax
inc ebx
mov ch, [eax]
mov [ebx], ch
inc eax
inc ebx
mov dl, [eax]
mov [ebx], dl
inc eax
inc ebx
mov dh, [eax]
mov [ebx], dh
inc eax
inc ebx
push dx
push cx
mov ecx, 0 # scale = 0
mov cx, [eax] # load
add eax, 2 # p_frame += 2 //skip scale
shl ecx, 0Eh # scale <<= 14
mov [ebp+var_8], ecx # save scale
loc_17B1E: #(loop: next byte)
mov ecx, [ebp+var_8] # (reload scale after loop)
mov dl, [eax] # byte = (uint8)*p_frame
shl edx, 1Ch # (sign extend low nibble, pt1)
sar edx, 1Ch # (sign extend low nibble, pt2)
imul ecx, edx # sample *= scale
pop dx # load hist2
shl edx, 10h # (sign extend hist2, pt1)
sar edx, 10h # (sign extend hist2, pt2)
imul edx, 3350h # hist2 *= coef2
sub ecx, edx # sample -= hist2
pop dx # ? save hist2 as hist1
push dx # load hist1
shl edx, 10h # (sign extend hist1, pt1)
sar edx, 10h # (sign extend hist2, pt1)
imul edx, 7298h # hist1 *= coef1
add ecx, edx # sample += hist1
sar ecx, 0Eh # sample >>= 14
mov [ebx], cl # save sample, low byte
inc ebx # p_buffer += 1
mov [ebx], ch # save sample, high byte
inc ebx # p_buffer += 1
pop dx # save hist1/2 and repeat for high nibble
push cx
push dx
mov ecx, [ebp+var_8]
mov dl, [eax]
shl edx, 18h
sar edx, 1Ch
imul ecx, edx
inc eax
pop dx
shl edx, 10h
sar edx, 10h
imul edx, 3350h
sub ecx, edx
pop dx
push dx
shl edx, 10h
sar edx, 10h
imul edx, 7298h
add ecx, edx
sar ecx, 0Eh
mov [ebx], cl
inc ebx
mov [ebx], ch
inc ebx
pop dx
push cx
push dx
dec [ebp+var_1]
jnz loc_17B1E #jump next byte
pop dx
pop dx
pop ebx
mov esp, ebp
pop ebp
retn 8
sub_17AE0 endp
# from xmddecode.dll (sh_sounds_explorer_1.7)
# some parts (*) where reordered to simplify logic
sub_10006F50
arg_0 = dword ptr 4
arg_4 = dword ptr 8
arg_8 = dword ptr 0Ch
arg_C = dword ptr 10h
arg_10 = dword ptr 14h
# esp: pointer table?
* push ebp # (save external value)
* push edi # (save external value)
* push ebx # (save external value)
* push esi # (save external value)
* xor ebp, ebp # (scale = 0)
mov eax, [esp+arg_C] # load p_hist1
mov edx, [esp+arg_10] # load p_hist2
* movsx ecx, word ptr [eax] # hist1 = (int16)*p_hist1
* movsx eax, word ptr [edx] # hist2 = (int16)*p_hist2
# (frame hist2/1 is already consumed)
mov edi, [esp+8+arg_4] # load p_frame
mov bp, [edi] # scale = (uint16)*p_frame
* shl ebp, 0Eh # scale <<= 14
mov edx, [esp+8+arg_8] # load bytes_left
test edx, edx # check if bytes_left == 0
jle loc_10007007 # end if true
* add edi, 2 # p_frame += 2 //skip scale
mov esi, [esp+10h+arg_0] # load p_buffer
mov [esp+10h+arg_C], edx # save bytes_left
loc_10006F85: # (loop location)
****** nibble1 ******
mov dl, [edi] # byte = (uint8)*p_frame
and edx, 0Fh # byte &= 0xF //get lower nibble
test dl, 8 # check sign
jz short loc_10006F92 # JUMP: not signed
or edx, 0FFFFFFF0h # NOJM: signed, sign extend
loc_10006F92:
mov ebx, ebp # (copy scale)
add esi, 2 # p_buffer += 2
imul ebx, edx # sample *= scale
mov edx, ecx # (copy hist1)
imul edx, 7298h # hist1 *= 0x7298 //coef1
add ebx, edx # sample += hist1
lea edx, [eax+eax*4] # hist2b = hist2 + hist2*4
lea edx, [eax+edx*8] # hist2b = hist2 + hist2b*8
lea edx, [edx+edx*4] # hist2b = hist2b + hist2b*4
lea eax, [eax+edx*4] # hist2 = hist2 + hist2b*4
shl eax, 4 # hist2 <<= 4
# AKA: (hist2 + (((hist2*5 + hist2)*8)*5)*4) << 4
# AKA: (hist2 + ((5*8+1)*5*4+1)) << 4 = hist2 * 0x335*10
# hist2 *= 0x3350 //coef2
sub ebx, eax # sample -= hist2
sar ebx, 0Eh # sample >>= 14
mov eax, ebx # (copy sample)
mov [esi-2], ax # *p_buffer-2 = (int16)sample
* xor edx, edx # byte = 0 //clean upper bits
****** nibble2 ******
mov dl, [edi] # byte = *p_frame
shr edx, 4 # byte >> 4 //get upper nibble
test dl, 8 # (check sign)
jz short loc_10006FCD # JUMP: not signed
or edx, 0FFFFFFF0h # NOJM: signed, sign extend
loc_10006FCD:
mov ebx, ebp # (copy scale)
add esi, 2 # p_buffer += 2
imul ebx, edx # sample *= scale
mov edx, eax # (copy hist1 = sample)
imul edx, 7298h # hist1 *= 0x7298
add ebx, edx # sample += hist1
lea edx, [ecx+ecx*4] # hist2b = hist2 + hist2*4
lea edx, [ecx+edx*8] # hist2b = hist2 + hist2b*8
lea edx, [edx+edx*4] # hist2b = hist2b + hist2b*4
lea ecx, [ecx+edx*4] # hist2 = hist2 + hist2b*4
# AKA: hist2 + (((hist2*5 + hist2)*8)*5)*4
# AKA: hist2 * ((5*8+1)*5*4+1) = hist2 * 0x335
shl ecx, 4 # hist2 <<= 4
# AKA: hist2 * 0x3350
sub ebx, ecx # sample -= hist2
sar ebx, 0Eh # sample >>= 14
mov ecx, ebx # (copy sample)
mov [esi-2], cx # *p_buffer-2 = (int16)sample
* inc edi # p_frame += 1
* mov edx, [esp+10h+arg_C] # load bytes_left
dec edx # bytes_left--
mov [esp+10h+arg_C], edx # save bytes_left
jnz short loc_10006F85 # JUMP (process next byte)
***
loc_10007007:
* pop esi # (restore external value)
* pop ebx # (restore external value)
pop edi # (restore external value)
pop ebp # (restore external value)
retn
endp