[a / b / c / d / e / f / g / gif / h / hr / k / m / o / p / s / t / u / v / vg / vm / vmg / vr / vrpg / vst / w / wg] [i / ic] [r9k / s4s / vip] [cm / hm / lgbt / y] [3 / aco / adv / an / bant / biz / cgl / ck / co / diy / fa / fit / gd / hc / his / int / jp / lit / mlp / mu / n / news / out / po / pol / pw / qst / sci / soc / sp / tg / toy / trv / tv / vp / vt / wsg / wsr / x / xs] [Settings] [Search] [Mobile] [Home]
Board
Settings Mobile Home
/wsr/ - Worksafe Requests

Name
Options
Comment
Verification
4chan Pass users can bypass this verification. [Learn More] [Login]
File
  • Please read the Rules and FAQ before posting.

08/21/20New boards added: /vrpg/, /vmg/, /vst/ and /vm/
05/04/17New trial board added: /bant/ - International/Random
10/04/16New board for 4chan Pass users: /vip/ - Very Important Posts
[Hide] [Show All]


Janitor applications are now open. Apply here!


[Advertise on 4chan]


Trying to adapt an audio ADPCM decompression codec from Assembly to Python and I'm second guessing myself on things.

For starters, to make sure I'm doing this right, the plan, as insane as it is, is to mimic the assembly logic as literally as possible, then use the output from that as a baseline while I refactor and hopefully keep the output identical. That's the only way I know of to make sure there aren't any goofs in the ripping process.

For example, the original assembly code for one part

Decompmainloop:
;
; determine if sample index is even
; or odd. this will determine if we
; need to get a new token or not.
;
test dword ptr [ ebx ].dwSampleIndex, 1
je short DecompfetchToken

;
; get token
;
movzx eax, word ptr [ ebx ].wCodeBuf
shr eax, 4
and eax, 000fh
mov word ptr [ ebx ].wCode, ax
jmp short DecompcalcDifference

And my attempted reinterpretation

def decomp_main_loop():
nonlocal eax
if (compression_info["sample_index"] & 1) == 0:
decomp_fetch_token()
else:
eax = (compression_info["code_buffer"] >> 4) & 0x0F

ax = eax & 0xffff
compression_info["code"] = ax

decomp_calc_difference()

Problem is, the result sounds staticy, and looking at the converted byte layout, I'm seeing spurts of 0xff

Given a structure like this, are there any high level or low level things I should be looking out for when trying to copy the assembly logic?
>>
>>1566207
I'm not sure it applies to this (I'm in no state to try and figure out ASM right now), but I had a staticky result when I tried implementing ADPCM before, and it turned out I just unpacked the samples within a byte in the wrong order. I wouldn't be surprised if it's something simple like that.
A literal translation to something high level like this is the approach I would do, and have done before.
>>
>>1566213
>A literal translation to something high level like this is the approach I would do, and have done before.
That's basically what I'm trying to do. Copy the assembly logic as literally as possible (hence using eax and similar registers as variables and attempting to derive the upper and lower bits thereof), then once I nail that, use the output from that as a baseline while I refactor, hopefully keeping the outputs bit-for-bit identical

FWIW, I literally asked AI to write me Python code based on the ASM, and it worked, in the sense that there wasn't any static. However, one sound didn't sound quite there, which is what led me to believe the AI's output is quite there

So I sought out to work on something "from scratch", which has led me to discover that AI seems to be a pretty crappy debugger at times.

By "unpacking sample in the wrong order", you mean seeing whether the sample index is even or odd? Because I think I got that down

Then there's what I'm doing to "save" the decoded bytes

def decomp_no_underflow():
nonlocal edi, converted_bytes, eax, ecx, prev_decomp_byte
compression_info["predicted"] = eax

ax = eax & 0xFFFF
ah = (ax >> 8) & 0xff
ah ^= 0x80
al = ah

converted_bytes[edi] = al
edi += 1
[...]

Compared to the original ASM

DecompnoUnderflow:
mov dword ptr [ ebx ].dwPredicted, eax

;
; output 8 bit sample
;
xor ah, 80h
mov al, ah
stosb
>>
Well it turns out my issues were mostly down to two factors

I had to fix how eax and ax related to one another

def decomp_fetch_token():
# nonlocal current_source
nonlocal esi, eax, audio_bytes
eax = 0
al = audio_bytes[esi] & 0xff
eax = al
ax = eax & 0xffff
compression_info["code_buffer"] = ax
esi += 1
eax &= 0x000f
ax = eax & 0xffff
compression_info["code"] = ax

decomp_calc_difference()

And I had to fix bungled check against the index table in regards to masking

def decomp_check_overflow():
compression_info["index"] = compression_info["index"] & 0xFFFF

if compression_info["index"] <= 88:
decomp_adjust_step()
else:
compression_info["index"] = 88
decomp_adjust_step()

That one sound still has a small "pop" and now I'm starting to wonder if it's "supposed" to be there



[Advertise on 4chan]

Delete Post: [File Only] Style:
[Disable Mobile View / Use Desktop Site]

[Enable Mobile View / Use Mobile Site]

All trademarks and copyrights on this page are owned by their respective parties. Images uploaded are the responsibility of the Poster. Comments are owned by the Poster.