[Music related Libraries]#1 midi2audio(mp3)

Clay Ryu's sound lab·2023년 8월 29일
0

Framework

목록 보기
28/49

If you utilize a MIDI format for a certain task, it is important to change the format into audio, and also in the opposite way.

official page : https://github.com/bzamecnik/midi2audio

requirements

Musescore(optional)

https://ourcodeworld.com/articles/read/1408/how-to-install-musescore-3-in-ubuntu-2004

converting midi from muspy could raise following errors related to soundfont settings. so I tried no to use muspy, rather using midi2audio instead because the library doesn't require muspy.

'fluidsynth', '-ni', '-F', 'wandb/debug/checkpoints/23-08-28/valid_out/midi_decoded_99_seed_0.wav', '-T', 'auto', '-r', '44100', '-g', '3', '/home/clay/.muspy/musescore-general/MuseScore_General.sf3', '/tmp/tmpofk5icpi/temp.mid']

fluidsynth

apt-get install fluid synth
pip install pyfluidsynth

use gain

I added gain parameter, which the original soundfont can use, but midi2audio doesn't utilize.

def save_wav_from_midi_fluidsynth(midi_fn, file_name, gain=3):
  assert isinstance(midi_fn, str)
  fs = FluidSynth(gain=gain)
  fs.midi_to_audio(midi_fn, file_name)
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
        subprocess.call(
            ['fluidsynth', '-ni', '-g', str(self.gain), self.sound_font, midi_file, '-F', audio_file, '-r', str(self.sample_rate)], 
            stdout=stdout, 
        )

    def play_midi(self, midi_file):
        subprocess.call(['fluidsynth', '-i', '-g', str(self.gain), self.sound_font, midi_file, '-r', str(self.sample_rate)])

To mp3

Converting wav file into mp3 file is important, especially when your disk is running our of memory. As midi2audio don't support mp3 format. Create the wav file first, and then convert it into mp3.

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 = '~/.fluidsynth/default_sound_font.sf2'
DEFAULT_SAMPLE_RATE = 44100
DEFAULT_GAIN = 0.2

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)])
profile
chords & code // harmony with structure

0개의 댓글