pop2piano / utils /dsp.py
sweetcocoa's picture
initial test
88490a8
raw
history blame
2.16 kB
import numpy as np
from scipy.interpolate import interp1d
def normalize(audio, min_y=-1.0, max_y=1.0, eps=1e-8):
assert len(audio.shape) == 1
max_y -= eps
min_y += eps
amax = audio.max()
amin = audio.min()
audio = (max_y - min_y) * (audio - amin) / (amax - amin) + min_y
return audio
def get_stereo(pop_y, midi_y, pop_scale=0.99):
if len(pop_y) > len(midi_y):
midi_y = np.pad(midi_y, (0, len(pop_y) - len(midi_y)))
elif len(pop_y) < len(midi_y):
pop_y = np.pad(pop_y, (0, -len(pop_y) + len(midi_y)))
stereo = np.stack((midi_y, pop_y * pop_scale))
return stereo
def generate_variable_f0_sine_wave(f0, len_y, sr):
"""
integrate instant frequencies to get pure tone sine wave
"""
x_sample = np.arange(len(f0))
intp = interp1d(x_sample, f0, kind="linear")
f0_audiorate = intp(np.linspace(0, len(f0) - 1, len_y))
pitch_wave = np.sin((np.nan_to_num(f0_audiorate) / sr * 2 * np.pi).cumsum())
return pitch_wave
def fluidsynth_without_normalize(self, fs=44100, sf2_path=None):
"""Synthesize using fluidsynth. without signal normalize
Parameters
----------
fs : int
Sampling rate to synthesize at.
sf2_path : str
Path to a .sf2 file.
Default ``None``, which uses the TimGM6mb.sf2 file included with
``pretty_midi``.
Returns
-------
synthesized : np.ndarray
Waveform of the MIDI data, synthesized at ``fs``.
"""
# If there are no instruments, or all instruments have no notes, return
# an empty array
if len(self.instruments) == 0 or all(len(i.notes) == 0 for i in self.instruments):
return np.array([])
# Get synthesized waveform for each instrument
waveforms = [i.fluidsynth(fs=fs, sf2_path=sf2_path) for i in self.instruments]
# Allocate output waveform, with #sample = max length of all waveforms
synthesized = np.zeros(np.max([w.shape[0] for w in waveforms]))
# Sum all waveforms in
for waveform in waveforms:
synthesized[: waveform.shape[0]] += waveform
# Normalize
# synthesized /= np.abs(synthesized).max()
return synthesized