From 4c07da91af118ef61380d9a2cd663a8059faebd8 Mon Sep 17 00:00:00 2001 From: Beshar <51468627+madderscientist@users.noreply.github.com> Date: Sat, 7 Dec 2024 02:57:41 +0800 Subject: [PATCH] enable midi -> audio (#83) --- fluidsynth.py | 26 +++++++++++++++++++++++++- test/test7.py | 17 +++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 test/test7.py diff --git a/fluidsynth.py b/fluidsynth.py index 157c6ed..043642c 100644 --- a/fluidsynth.py +++ b/fluidsynth.py @@ -618,6 +618,16 @@ class fluid_midi_router_t(Structure): ('rule', c_void_p, 1), ('type', c_int, 1)) +# fluid file renderer +new_fluid_file_renderer = cfunc('new_fluid_file_renderer', c_void_p, + ('synth', c_void_p, 1)) + +delete_fluid_file_renderer = cfunc('delete_fluid_file_renderer', None, + ('renderer', c_void_p, 1)) + +fluid_file_renderer_process_block = cfunc('fluid_file_renderer_process_block', c_int, + ('render', c_void_p, 1)) + # fluidsynth 2.x new_fluid_cmd_handler=cfunc('new_fluid_cmd_handler', c_void_p, ('synth', c_void_p, 1), @@ -693,6 +703,8 @@ def __init__(self, gain=0.2, samplerate=44100, channels=256, **kwargs): self.midi_driver = None self.router = None self.custom_router_callback = None + def __del__(self): + self.delete() def setting(self, opt, val): """change an arbitrary synth setting, type-smart""" if isinstance(val, (str, bytes)): @@ -1070,7 +1082,19 @@ def play_midi_stop(self): def player_set_tempo(self, tempo_type, tempo): return fluid_player_set_tempo(self.player, tempo_type, tempo) - + + def midi2audio(self, midifile, audiofile = "output.wav"): + """Convert a midi file to an audio file""" + self.setting("audio.file.name", audiofile) + player = new_fluid_player(self.synth) + fluid_player_add(player, midifile.encode()) + fluid_player_play(player) + renderer = new_fluid_file_renderer(self.synth) + while(fluid_player_get_status(player) == FLUID_PLAYER_PLAYING): + if(fluid_file_renderer_process_block(renderer) != FLUID_OK): + break + delete_fluid_file_renderer(renderer) + delete_fluid_player(player) class Sequencer: diff --git a/test/test7.py b/test/test7.py new file mode 100644 index 0000000..09b5a5c --- /dev/null +++ b/test/test7.py @@ -0,0 +1,17 @@ +import fluidsynth + + +def local_file_path(file_name: str) -> str: + """ + Return a file path to a file that is in the same directory as this file. + """ + from os.path import dirname, join + + return join(dirname(__file__), file_name) + +fs = fluidsynth.Synth() +sfid = fs.sfload(local_file_path("example.sf2")) +fs.midi2audio(local_file_path("1080-c01.mid"), local_file_path("1080-c01.wav")) +# A Synth object can synthesize multiple files. For example: +# fs.midi2audio(local_file_path("1080-c02.mid"), local_file_path("1080-c02.wav")) +# fs.midi2audio(local_file_path("1080-c03.mid"), local_file_path("1080-c03.wav"))