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 partDecompmainloop: ; ; 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 DecompcalcDifferenceAnd my attempted reinterpretationdef 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 0xffGiven 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?
>>1566207I'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 identicalFWIW, 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 thereSo 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 downThen there's what I'm doing to "save" the decoded bytesdef 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 ASMDecompnoUnderflow: 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 factorsI had to fix how eax and ax related to one anotherdef 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 maskingdef 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