Python - смешайте два аудио блока - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть два байтовых объекта. Одним из них является использование модуля Wave для чтения «порции» данных:

def get_wave_from_file(filename):
    import wave
    original_wave = wave.open(filename, 'rb')
    return original_wave

Другой использует информацию MIDI и модуль синтезатора (fluidsynth)

def create_wave_from_midi_info(sound_font_path, notes):
    import fluidsynth
    s = []
    fl = fluidsynth.Synth()
    sfid = fl.sfload(sound_font_path) # Loads a soundfont
    fl.program_select(track=0, soundfontid=sfid, banknum=0, presetnum=0) # Selects the soundfont

    for n in notes:
        fl.noteon(0, n['midi_num'], n['velocity'])
         s = np.append(s, fl.get_samples(int(44100 * n['duration']))) # Gives the note the correct duration, based on a sample rate of 44.1Khz
        fl.noteoff(0, n['midi_num'])
    fl.delete()
    samps = fluidsynth.raw_audio_string(s)
    return samps

Два файла имеют разную длину. Я хочу объединить две волны, чтобы обе были услышаны одновременно. В частности, я хотел бы сделать это "один кусок за раз".

Вот мои настройки:

def get_a_chunk_from_each(wave_object, bytes_from_midi, chunk_size=1024, starting_sample=0)):
    from_wav_data  = wave_object.readframes(chunk_size)
    from_midi_data = bytes_from_midi[starting_sample:starting_sample + chunk_size]
    return from_wav_data, from_midi_data

Информация о возврате из get_a_chunk_from_each (): тип (from_wav_data), тип (from_midi_data) len (from_wav_data), тип (from_midi_data) 4096 1024

Во-первых, меня смущает, почему длины различаются (длина, сгенерированная из wave_object.readframes (1024), ровно в 4 раза длиннее длины, сгенерированной вручную путем нарезки bytes_from_midi [0: 1024]. Это может быть частью причины, по которой я потерпел неудачу.

Во-вторых, я хочу создать функцию, которая объединяет два блока. Следующий «псевдокод» иллюстрирует то, что я хочу, чтобы произошло:

def combine_chunks(chunk1, chunk2):
    mixed = chunk1 + chunk2
    # OR, probably more like:
    mixed = (chunk1 + chunk2) / 2
    # To prevent clipping?
    return mixed

1 Ответ

0 голосов
/ 27 ноября 2018

Оказывается, есть очень, очень простое решение. Я просто использовал библиотеку audioop:

https://docs.python.org/3/library/audioop.html

и использовал их функцию «добавления» («ширина» - это ширина выборки в байтах. Поскольку это 16-битный звук, то это 16/8 = 2 байта):

    audioop.add(chunk1, chunk2, width=2)
...