Python - 混合两个音频块
Python - Mix two audio chunks
我有两个字节对象。
一个来自使用 Wave 模块读取 "chunk" 数据:
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
两个文件的长度不同。
我想将这两个波结合起来,以便同时听到两者。
具体来说,我想这样做 "one chunk at a time".
这是我的设置:
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
关于 return 来自 get_a_chunk_from_each() 的信息:
类型(from_wav_data),类型(from_midi_data)
长度(from_wav_data),类型(from_midi_data)
4096 1024
首先,我很困惑为什么长度不同(从wave_object.readframes(1024)生成的长度恰好是手动切片生成的长度的4倍bytes_from_midi[0 :1024]。这可能是我没有成功的部分原因。
其次,我想创建结合这两个块的函数。以下 "pseudocode" 说明了我想要发生的事情:
def combine_chunks(chunk1, chunk2):
mixed = chunk1 + chunk2
# OR, probably more like:
mixed = (chunk1 + chunk2) / 2
# To prevent clipping?
return mixed
原来有一个非常非常简单的解决方案。
我只是使用了库 audioop:
https://docs.python.org/3/library/audioop.html
并使用了他们的 "add" 函数("width" 是以字节为单位的样本宽度。因为这是 16 位音频,所以 16 / 8 = 2 字节):
audioop.add(chunk1, chunk2, width=2)
我有两个字节对象。 一个来自使用 Wave 模块读取 "chunk" 数据:
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
两个文件的长度不同。 我想将这两个波结合起来,以便同时听到两者。 具体来说,我想这样做 "one chunk at a time".
这是我的设置:
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
关于 return 来自 get_a_chunk_from_each() 的信息: 类型(from_wav_data),类型(from_midi_data) 长度(from_wav_data),类型(from_midi_data) 4096 1024
首先,我很困惑为什么长度不同(从wave_object.readframes(1024)生成的长度恰好是手动切片生成的长度的4倍bytes_from_midi[0 :1024]。这可能是我没有成功的部分原因。
其次,我想创建结合这两个块的函数。以下 "pseudocode" 说明了我想要发生的事情:
def combine_chunks(chunk1, chunk2):
mixed = chunk1 + chunk2
# OR, probably more like:
mixed = (chunk1 + chunk2) / 2
# To prevent clipping?
return mixed
原来有一个非常非常简单的解决方案。 我只是使用了库 audioop:
https://docs.python.org/3/library/audioop.html
并使用了他们的 "add" 函数("width" 是以字节为单位的样本宽度。因为这是 16 位音频,所以 16 / 8 = 2 字节):
audioop.add(chunk1, chunk2, width=2)