0

できるだけ早く 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, -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], 0, 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, -32768, 32767)
    step_index = clamp(step_index + step_indices[encoded_sample & 7], 0, 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()
4

1 に答える 1

0

あなたが見たことがあるかどうか疑問に思っていますpyima-それはまったく同じことをしているようです。

処理を高速化する場合 - いくつかのファイルのエンコードを並行して実行できます - これは、大量に作業する場合に実行できる最も簡単な方法です。ただし、個々のファイルのエンコーディングについては、エンコーディングを行うための Python インターフェイスを持つ、適切に最適化された C++ ライブラリを使用することをお勧めします。

于 2021-01-16T20:58:50.733 に答える