78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
import argparse
|
|
import os
|
|
import subprocess
|
|
from pydub import AudioSegment
|
|
|
|
'''
|
|
This file is a modified version of midi2audio.py from https://github.com/bzamecnik/midi2audio
|
|
Author: Bohumír Zámečník (@bzamecnik)
|
|
License: MIT, see the LICENSE file
|
|
'''
|
|
|
|
__all__ = ['FluidSynth']
|
|
|
|
DEFAULT_SOUND_FONT = '/data2/suhongju/research/music-generation/sound_file/CrisisGeneralMidi3.01.sf2'
|
|
DEFAULT_SAMPLE_RATE = 48000
|
|
DEFAULT_GAIN = 0.05
|
|
# DEFAULT_SOUND_FONT = "/data2/suhongju/research/music-generation/sound_file/Advent GM 7.sf2"
|
|
# DEFAULT_SOUND_FONT = '~/.fluidsynth/default_sound_font.sf2'
|
|
# DEFAULT_SAMPLE_RATE = 16000
|
|
# DEFAULT_GAIN = 0.20
|
|
|
|
class FluidSynth():
|
|
def __init__(self, sound_font=DEFAULT_SOUND_FONT, sample_rate=DEFAULT_SAMPLE_RATE, gain=DEFAULT_GAIN):
|
|
self.sample_rate = sample_rate
|
|
self.sound_font = os.path.expanduser(sound_font)
|
|
self.gain = gain
|
|
|
|
def midi_to_audio(self, midi_file: str, audio_file: str, verbose=True):
|
|
if verbose:
|
|
stdout = None
|
|
else:
|
|
stdout = subprocess.DEVNULL
|
|
|
|
# Convert MIDI to WAV
|
|
subprocess.call(
|
|
['fluidsynth', '-ni', '-g', str(self.gain), self.sound_font, midi_file, '-F', audio_file, '-r', str(self.sample_rate)],
|
|
stdout=stdout
|
|
)
|
|
|
|
# Convert WAV to MP3
|
|
# mp3_path = audio_file.replace('.wav', '.mp3')
|
|
# AudioSegment.from_wav(audio_file).export(mp3_path, format="mp3")
|
|
|
|
# # Delete the temporary WAV file
|
|
# os.remove(audio_file)
|
|
|
|
def play_midi(self, midi_file):
|
|
subprocess.call(['fluidsynth', '-i', '-g', str(self.gain), self.sound_font, midi_file, '-r', str(self.sample_rate)])
|
|
|
|
def parse_args(allow_synth=True):
|
|
parser = argparse.ArgumentParser(description='Convert MIDI to audio via FluidSynth')
|
|
parser.add_argument('midi_file', metavar='MIDI', type=str)
|
|
if allow_synth:
|
|
parser.add_argument('audio_file', metavar='AUDIO', type=str, nargs='?')
|
|
parser.add_argument('-s', '--sound-font', type=str,
|
|
default=DEFAULT_SOUND_FONT,
|
|
help='path to a SF2 sound font (default: %s)' % DEFAULT_SOUND_FONT)
|
|
parser.add_argument('-r', '--sample-rate', type=int, nargs='?',
|
|
default=DEFAULT_SAMPLE_RATE,
|
|
help='sample rate in Hz (default: %s)' % DEFAULT_SAMPLE_RATE)
|
|
return parser.parse_args()
|
|
|
|
def main(allow_synth=True):
|
|
args = parse_args(allow_synth)
|
|
fs = FluidSynth(args.sound_font, args.sample_rate)
|
|
if allow_synth and args.audio_file:
|
|
fs.midi_to_audio(args.midi_file, args.audio_file)
|
|
else:
|
|
fs.play_midi(args.midi_file)
|
|
|
|
def main_play():
|
|
"""
|
|
A method for the `midiplay` entry point. It omits the audio file from args.
|
|
"""
|
|
main(allow_synth=False)
|
|
|
|
if __name__ == '__main__':
|
|
main() |