Skip to content

Commit

Permalink
Add normalize parameter to synthesize and fluidsynth methods (#243)
Browse files Browse the repository at this point in the history
* Add normalize parameter to synthesize and fluidsynth methods

* Change normalize parameter to True in synthesize and fluidsynth methods
  • Loading branch information
yawjalik authored Feb 23, 2024
1 parent 07f4174 commit 8f70108
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions pretty_midi/pretty_midi.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ def get_chroma(self, fs=100, times=None, pedal_threshold=64):
chroma_matrix[note, :] = np.sum(piano_roll[note::12], axis=0)
return chroma_matrix

def synthesize(self, fs=44100, wave=np.sin):
def synthesize(self, fs=44100, wave=np.sin, normalize=True):
"""Synthesize the pattern using some waveshape. Ignores drum track.
Parameters
Expand All @@ -944,6 +944,10 @@ def synthesize(self, fs=44100, wave=np.sin):
wave : function
Function which returns a periodic waveform,
e.g. ``np.sin``, ``scipy.signal.square``, etc.
normalize : bool
Default ``True``, which normalizes the output wave to the range [-1, 1].
Otherwise, divides the output by the maximum value of a 16-bit integer
multiplied by the number of instruments, and lets the user handle accordingly.
Returns
-------
Expand All @@ -961,11 +965,19 @@ def synthesize(self, fs=44100, wave=np.sin):
# Sum all waveforms in
for waveform in waveforms:
synthesized[:waveform.shape[0]] += waveform
# Normalize
synthesized /= np.abs(synthesized).max()

if normalize:
# Hard normalize to [-1, 1]
synthesized /= np.abs(synthesized).max()
else:
# Normalize by the maximum absolute value of a 16-bit integer
# to prevent clipping
synthesized /= (len(self.instruments) * 2 ** 15)

return synthesized

def fluidsynth(self, fs=None, synthesizer=None, sfid=0, sf2_path=None):
def fluidsynth(self, fs=None, synthesizer=None, sfid=0, sf2_path=None,
normalize=True):
"""Synthesize using fluidsynth.
Parameters
Expand All @@ -988,6 +1000,10 @@ def fluidsynth(self, fs=None, synthesizer=None, sfid=0, sf2_path=None):
``pretty_midi``.
.. deprecated:: 0.2.11
Use :param:`synthesizer` instead.
normalize : bool
Default ``True``, which normalizes the output wave to the range [-1, 1].
Otherwise, divides the output by the maximum value of a 16-bit integer
multiplied by the number of instruments, and lets the user handle accordingly.
Returns
-------
Expand Down Expand Up @@ -1026,8 +1042,15 @@ def fluidsynth(self, fs=None, synthesizer=None, sfid=0, sf2_path=None):
# Sum all waveforms in
for waveform in waveforms:
synthesized[:waveform.shape[0]] += waveform
# Normalize
synthesized /= np.abs(synthesized).max()

if normalize:
# Hard normalize to [-1, 1]
synthesized /= np.abs(synthesized).max()
else:
# Normalize by the maximum absolute value of a 16-bit integer
# to prevent clipping
synthesized /= (len(self.instruments) * 2 ** 15)

return synthesized

def tick_to_time(self, tick):
Expand Down

0 comments on commit 8f70108

Please sign in to comment.