问题描述
我想尽快将 wav 文件编码为 IMA ADPCM。
但是当我尝试编码我的文件(1:39 长度,44100 采样率,16 位,立体声)时,编码它需要大约 8 秒...
有没有办法让它更快?因为 8 秒对我来说看起来很慢...
另外,我尝试使用 Python 的 audioop 模块,但它仍然很慢,而且我真的不需要 audioop 的东西,所以我编写了自己的示例编码器/解码器。
我的代码:
steps = [
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
]
step_indices = [-1,-1,2,4,6,8]
def clamp(value,lower,upper):
return lower if (value < lower) else upper if (value > upper) else value
def decode_sample(sample,state: tuple) -> tuple:
predicted_sample = state[0] if (state) else 0
step_index = state[1] if (state) else 0
step = steps[step_index]
diff = step >> 3
if sample & 1: diff += step >> 2
if sample & 2: diff += step >> 1
if sample & 4: diff += step
if sample & 8: diff = -diff
predicted_sample = clamp(predicted_sample + diff,-32768,32767)
step_index = clamp(step_index + step_indices[sample & 7],88)
return predicted_sample,step_index
def encode_sample(sample,state: tuple) -> tuple:
predicted_sample = state[0] if (state) else 0
step_index = state[1] if (state) else 0
step = steps[step_index]
sample_diff = sample - predicted_sample
encoded_sample = 8 if (sample_diff < 0) else 0
if encoded_sample:
sample_diff = -sample_diff
diff = step >> 3
if sample_diff >= step:
encoded_sample |= 4
sample_diff -= step
diff += step
step >>= 1
if sample_diff >= step:
encoded_sample |= 2
sample_diff -= step
diff += step
step >>= 1
if sample_diff >= step:
encoded_sample |= 1
diff += step
if encoded_sample & 8:
diff = -diff
predicted_sample = clamp(predicted_sample + diff,32767)
step_index = clamp(step_index + step_indices[encoded_sample & 7],88)
return encoded_sample,(predicted_sample,step_index)
import wave
def encode_stereo():
with wave.open('mario.wav','r') as wav_file:
raw_samples = wav_file.readframes(wav_file.getnframes())
samples = memoryview(raw_samples).cast('h')
left_channel,right_channel = samples[::2],samples[1::2]
encoded = bytearray()
left_state = None
right_state = None
for i in range(len(left_channel)):
left_sample,left_state = encode_sample(left_channel[i],left_state)
right_sample,right_state = encode_sample(right_channel[i],right_state)
encoded.append(right_sample << 4 | left_sample)
with open('mario.adpcm','wb') as adpcm_file:
adpcm_file.write(encoded)
encode_stereo()
解决方法
我想知道您是否见过 pyima
- 它似乎在做同样的事情。
如果要加快速度 - 您可以并行运行几个文件的编码 - 如果批量工作,这是您可以做的最简单的事情。但是对于单个文件编码 - 我建议使用一些优化良好的 C++ 库,它具有 Python 接口来进行编码。