def write_preview_wav(wav_fp, note_beats_and_abs_times, wav_fs=11025.0):
wav_len = int(wav_fs * (note_beats_and_abs_times[-1][1] + 0.05))
dt = 1.0 / wav_fs
note_type_to_idx = {}
idx = 0
for _, beat, time, note_type in note_beats_and_abs_times:
if note_type == '0' * len(note_type):
continue
if note_type not in note_type_to_idx:
note_type_to_idx[note_type] = idx
idx += 1
num_note_types = len(note_type_to_idx)
pulse_f = np.zeros((num_note_types, wav_len))
for _, beat, time, note_type in note_beats_and_abs_times:
sample = int(time * wav_fs)
if sample > 0 and sample < wav_len and note_type in note_type_to_idx:
pulse_f[note_type_to_idx[note_type]][sample] = 1.0
scale = [440.0, 587.33, 659.25, 783.99]
freqs = [scale[i % 4] * math.pow(2.0, (i // 4) - 1) for i in xrange(num_note_types)]
metro_f = np.zeros(wav_len)
for idx in xrange(num_note_types):
click_len = 0.05
click_t = np.arange(0.0, click_len, dt)
click_atk = 0.02
click_sus = 0.5
click_rel = 0.2
click_env = _linterp(0.0, [(click_atk, 1.0), (click_sus, 1.0), (click_rel, 0.0)], len(click_t))
click_f = click_env * np.sin(2.0 * np.pi * freqs[idx] * click_t)
metro_f += fftconvolve(pulse_f[idx], click_f, mode='full')[:wav_len]
#metro_f += pulse_f[idx][:wav_len]
_wav_write(wav_fp, wav_fs, metro_f, normalize=True)
评论列表
文章目录