Skip to content
This repository was archived by the owner on Feb 1, 2024. It is now read-only.

Commit a978929

Browse files
authored
Merge pull request #39 from lukewys/main
Upgrade command-line to support saving synthesis parameters. Bump up version to 0.2.0.
2 parents 6291504 + 6f9a312 commit a978929

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

midi_ddsp/midi_ddsp_synthesize.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from midi_ddsp.utils.audio_io import save_wav
3535
from midi_ddsp.utils.training_utils import get_hp
3636
from midi_ddsp.utils.inference_utils import ensure_same_length
37+
from midi_ddsp.utils.file_utils import pickle_dump
3738
from midi_ddsp.hparams_synthesis_generator import hparams as hp
3839
from midi_ddsp.modules.get_synthesis_generator import get_synthesis_generator, \
3940
get_fake_data_synthesis_generator
@@ -92,7 +93,8 @@ def synthesize_midi(synthesis_generator, expression_generator, midi_file,
9293
use_fluidsynth=False,
9394
sf2_path='/usr/share/sounds/sf2/FluidR3_GM.sf2',
9495
display_progressbar=True,
95-
skip_existing_files=False):
96+
skip_existing_files=False,
97+
save_synth_params=False):
9698
"""
9799
Synthesize a midi file using MIDI-DDSP.
98100
Args:
@@ -101,13 +103,15 @@ def synthesize_midi(synthesis_generator, expression_generator, midi_file,
101103
midi_file: The path to the MIDI file.
102104
pitch_offset: Pitch in semitone to transpose.
103105
speed_rate: The speed to synthesize the MIDI file.
104-
output_dir: The directory for output audio.
106+
output_dir: The directory for saving outputs.
107+
If output_dir is None, outputs will not be written to disk.
105108
use_fluidsynth: Whether to use FluidSynth for synthesizing instruments
106109
that are not available in MIDI-DDSP.
107110
sf2_path: The path to a sf2 soundfont file used for FluidSynth.
108111
display_progressbar: Whether to display progress bar.
109112
skip_existing_files: Skip synthesizing MIDI files if already exist
110113
output folders.
114+
save_synth_params: also save synthesis parameters.
111115
112116
Returns: A dict of output:
113117
'mix_audio': mix audio,
@@ -134,6 +138,8 @@ def synthesize_midi(synthesis_generator, expression_generator, midi_file,
134138
conditioning_df_all = []
135139
part_synth_by_model = []
136140
midi_audio_all = {}
141+
midi_synth_params_all = {}
142+
midi_control_params_all = {}
137143

138144
# For each part, predict expressions using MIDI-DDSP,
139145
# or synthesize using FluidSynth.
@@ -173,12 +179,27 @@ def synthesize_midi(synthesis_generator, expression_generator, midi_file,
173179
instrument_id_all,
174180
display_progressbar=display_progressbar)
175181

182+
midi_synth_params = midi_synth_params['inputs']
176183
for i in range(midi_audio.shape[0]):
177184
part_number = part_synth_by_model[i]
185+
186+
# align audio with part number
178187
midi_audio_all[part_number] = midi_audio[i].numpy()
179-
else:
180-
midi_control_params = None
181-
midi_synth_params = None
188+
189+
# align synthesis parameters with part number
190+
# get the midi synth parameters
191+
midi_synth_params_all[part_number] = {
192+
k: v[i].numpy() for k, v in midi_synth_params.items()}
193+
194+
# align control parameters with part number
195+
# (yusongwu) sorry for mis-aligned variable names between
196+
# synth_params and control_params due to historical issues
197+
midi_control_params_all[part_number] = {
198+
'amplitudes': midi_control_params[1][i].numpy(),
199+
'harmonic_distribution': midi_control_params[2][i].numpy(),
200+
'noise_magnitudes': midi_control_params[3][i].numpy(),
201+
'f0_hz': midi_control_params[0][i].numpy(),
202+
}
182203

183204
# Sorting out and save the wav.
184205
if output_dir is not None:
@@ -205,17 +226,20 @@ def synthesize_midi(synthesis_generator, expression_generator, midi_file,
205226
if midi_audio_all:
206227
midi_audio_mix = np.sum(
207228
np.stack(ensure_same_length(
208-
[a.astype(np.float) for a in midi_audio_all.values()], axis=0),
229+
[a.astype(np.float64) for a in midi_audio_all.values()], axis=0),
209230
axis=-1),
210231
axis=-1)
211232
if output_dir is not None:
212233
save_wav(midi_audio_mix, os.path.join(output_dir, 'mix.wav'), 16000)
234+
if save_synth_params:
235+
pickle_dump(midi_synth_params_all,
236+
os.path.join(output_dir, 'synth_params.pickle'))
213237
output = {
214238
'mix_audio': midi_audio_mix,
215239
'stem_audio': midi_audio_all,
216240
'part_synth_by_model': part_synth_by_model,
217-
'midi_control_params': midi_control_params,
218-
'midi_synth_params': midi_synth_params,
241+
'midi_control_params': midi_control_params_all,
242+
'midi_synth_params': midi_synth_params_all,
219243
'conditioning_df': conditioning_df_all,
220244
}
221245
else:
@@ -259,6 +283,10 @@ def main():
259283
action='store_true',
260284
help='Skip synthesizing MIDI files if already exist '
261285
'output folders.')
286+
parser.add_argument('--save_synth_params', dest='save_synth_params',
287+
action='store_true',
288+
help='Save synthesis parameters generated by MIDI-DDSP.')
289+
262290
args = parser.parse_args()
263291

264292
synthesis_generator, expression_generator = load_pretrained_model(
@@ -304,7 +332,8 @@ def main():
304332
sf2_path=args.sf2_path,
305333
use_fluidsynth=args.use_fluidsynth,
306334
display_progressbar=True,
307-
skip_existing_files=args.skip_existing_files
335+
skip_existing_files=args.skip_existing_files,
336+
save_synth_params=args.save_synth_params
308337
)
309338

310339

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
setuptools.setup(
2323
name='midi-ddsp',
24-
version='0.1.5',
24+
version='0.2.0',
2525
description='Synthesis of MIDI with DDSP',
2626
long_description=long_description,
2727
long_description_content_type='text/markdown',

0 commit comments

Comments
 (0)