Files
scummvm-cursorfix/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py
2026-02-02 04:50:13 +01:00

228 lines
7.7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
ctypesLibFound = False
structLibFound = False
try:
import ctypes
except ImportError:
print ("[Error] ctypes python library is required to be installed!")
else:
ctypesLibFound = True
if (not ctypesLibFound):
sys.stdout.write("[Error] Errors were found when trying to import required python libraries\n")
sys.exit(1)
from struct import *
MY_MODULE_VERSION = "0.70"
MY_MODULE_NAME = "audFileDecode"
aud_ima_index_adjust_table = [-1, -1, -1, -1, 2, 4, 6, 8]
# aud_ima_step_table has 89 entries
aud_ima_step_table = [
7, 8, 9, 10, 11, 12, 13, 14, 16,
17, 19, 21, 23, 25, 28, 31, 34, 37,
41, 45, 50, 55, 60, 66, 73, 80, 88,
97, 107, 118, 130, 143, 157, 173, 190, 209,
230, 253, 279, 307, 337, 371, 408, 449, 494,
544, 598, 658, 724, 796, 876, 963, 1060, 1166,
1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749,
3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289,
16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 ]
aud_ws_step_table2 = [-2, -1, 0, 1]
aud_ws_step_table4 = [
-9, -8, -6, -5, -4, -3, -2, -1,
0, 1, 2, 3, 4, 5, 6, 8
]
# (const xccTHA::byte* audio_in, short* audio_out, int& index, int& sample, int cs_chunk)
# index and sample are passed by reference and changed here...
# audio_out is definitely affected!
def aud_decode_ima_chunk(audioBufferIn, index, sample, cs_chunk):
code = -1
delta = -1
step = -1
audioBufferOut = []
#for i in range(0, len(audioBufferIn)):
#if self.m_traceModeEnabled:
# print ("[Debug] %d: %d" % (i, int(audioBufferIn[i])))
for sample_index in range (0, cs_chunk):
try:
code = audioBufferIn[sample_index >> 1]
except:
code = 0xa9 # dummy workaround because the c code is accessing an out of bounds index sometimes due to this shift here
#print ("[Debug] cs_chunk: %d, sample_index: %d, shifted: %d, code: %d" % (cs_chunk, sample_index, sample_index >> 1, int(audioBufferIn[sample_index >> 1])))
#print ("[Debug] cs_chunk: %s, sample_index: %s, shifted: %s, code: %s" % \
# (''.join('{:04X}'.format(cs_chunk)), ''.join('{:02X}'.format(sample_index)), ''.join('{:02X}'.format(sample_index >> 1)), ''.join('{:04X}'.format(int(code)))))
code = code >> 4 if (sample_index & 1) else code & 0xf
step = aud_ima_step_table[index]
delta = step >> 3
if (code & 1):
delta += step >> 2
if (code & 2):
delta += step >> 1
if (code & 4):
delta += step
if (code & 8):
sample -= delta
if (sample < -32768):
sample = -32768
else:
sample += delta
if (sample > 32767):
sample = 32767
audioBufferOut.append(ctypes.c_short( sample ).value )
#audioBufferOut.append(sample) # it's not different from above... ctypes.c_short( sample ).value
#if self.m_traceModeEnabled:
# print ("[Debug] audio_out[%s]: %s" % (''.join('{:02X}'.format(sample_index)), ''.join('{:02X}'.format(audioBufferOut[sample_index]))))
index += aud_ima_index_adjust_table[code & 7]
if (index < 0):
index = 0
elif (index > 88):
index = 88
## output buffer of shorts
#binDataOut = struct.pack('h'*len(audioBufferOut), *audioBufferOut)
#return (binDataOut, index, sample)
return (audioBufferOut, index, sample)
#
#
#
def aud_decode_clip8(v):
if (v < 0):
return 0
return 0xff if (v > 0xff) else v
#
#
#
# (const xccTHA::byte* r, char* w, int cb_s, int cb_d)
def aud_decode_ws_chunk(inputChunkBuffer, cb_s, cb_d):
outputChunkBuffer = []
inpChBuffIter = 0
outChBuffIter = 0
if (cb_s == cb_d):
# outputChunkBuffer = inputChunkBuffer[:cb_s] # memcpy(w, r, cb_s) # FIX
for mcp in range(0, cb_s):
outputChunkBuffer.append(ctypes.c_char(inputChunkBuffer[inpChBuffIter + mcp]).value)
#binDataOut = struct.pack('b'*len(outputChunkBuffer), *outputChunkBuffer)
#return binDataOut
return outputChunkBuffer
# const xccTHA::byte* s_end = inputChunkBuffer + cb_s; # FIX
s_end = inpChBuffIter + cb_s
sample = ctypes.c_int(0x80).value #int sample
while (inpChBuffIter < s_end):
inpChBuffIter += 1
count = ctypes.c_char(inputChunkBuffer[inpChBuffIter] & 0x3f).value # char count
switchKey = inputChunkBuffer[inpChBuffIter - 1] >> 6 # inputChunkBuffer[-1] # b[-1] is *(b - 1)
if switchKey == 0:
count += 1
for iter0 in range (count, 0, -1):
inpChBuffIter += 1
code = ctypes.c_int(inputChunkBuffer[inpChBuffIter]).value # int code
# assignment in C was right to left so:
# *(outputChunkBuffer++) = sample = clip8(sample + aud_ws_step_table2[code & 3])
# is:
# *(outputChunkBuffer++) = (sample = clip8(sample + aud_ws_step_table2[code & 3]))
# which is equivalent to these two commands:
# sample = clip8(sample + aud_ws_step_table2[code & 3])
# *(outputChunkBuffer++) = sample
# SO:
sample = aud_decode_clip8(sample + aud_ws_step_table2[code & 3])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample = aud_decode_clip8(sample + aud_ws_step_table2[code >> 2 & 3])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample = aud_decode_clip8(sample + aud_ws_step_table2[code >> 4 & 3])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample = aud_decode_clip8(sample + aud_ws_step_table2[code >> 6])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
elif switchKey == 1:
count += 1
for iter0 in range (count, 0, -1):
inpChBuffIter += 1
code = inputChunkBuffer[inpChBuffIter] # int code
sample += aud_ws_step_table4[code & 0xf]
sample = aud_decode_clip8(sample)
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample += aud_ws_step_table4[code >> 4]
sample = aud_decode_clip8(sample)
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
elif switchKey == 2:
if (count & 0x20):
#sample += static_cast<char>(count << 3) >> 3
#*(outputChunkBuffer++) = sample
sample += ((count & 0xFF) << 3 ) >> 3
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
else:
count += 1
# memcpy(outputChunkBuffer, inputChunkBuffer, count) # FIX
for mcp in range(0, count):
outputChunkBuffer.append(ctypes.c_char(inputChunkBuffer[inpChBuffIter + mcp]).value)
inpChBuffIter += count
outChBuffIter += count
sample = inputChunkBuffer[inpChBuffIter - 1]
else:
count += 1
# memset(outputChunkBuffer, sample, ++count)
for mst in range(0, count):
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += count;
# output buffer of chars
#binDataOut = struct.pack('b'*len(outputChunkBuffer), *outputChunkBuffer)
#return binDataOut
return outputChunkBuffer
#
#
#
class audFileDecode(object):
m_index = -1
m_sample = -1
m_traceModeEnabled = False
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True, index = 0, sample = 0):
self.m_traceModeEnabled = traceModeEnabled
self.m_index = index;
self.m_sample = sample;
return
def index(self):
return self.m_index
# (const xccTHA::byte* audio_in, short* audio_out, int cs_chunk)
def decode_chunk(self, audio_in, cs_chunk):
(audio_Out, outIndex, outSample) = aud_decode_ima_chunk(audio_in, self.m_index, self.m_sample, cs_chunk)
self.m_index = outIndex
self.m_sample = outSample
return audio_Out
if __name__ == '__main__':
# main()
decodeInstance = audFileDecode()
if decodeInstance.m_traceModeEnabled:
print ("[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
else:
#debug
#print ("[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
pass