Skip to content

Rendering

These functions provide a simple interface to render audio files from MIDI representations.

midi_to_mp3(midi, mp3_path=None)

Converts a MIDI file to an MP3 file.

This function takes a MIDI object, either as a MidiFile object or a MidiPiece object, and first converts it to a WAV file. It then converts this WAV file to an MP3 file.

Parameters:

Name Type Description Default
midi Union[MidiFile, MidiPiece]

The MIDI file to convert. Can be either a ff.MidiFile object or a MidiPiece object.

required
mp3_path str

The path where the converted MP3 file will be saved. If not specified, a temporary file is created.

None

Returns:

Name Type Description
mp3_path str

The path to the created MP3 file.

Note

If a MidiPiece object is provided, it is first converted to a MidiFile object before proceeding with the WAV and then MP3 conversion.

Examples:

>>> some_midi = ff.MidiPiece(midi_df)
>>> mp3_path = midi_to_mp3(some_midi, "test.mp3")
>>> print("MP3 file created at:", mp3_path)
Source code in fortepyan/audio/render.py
def midi_to_mp3(midi: Union[structures.MidiFile, structures.MidiPiece], mp3_path: str = None):
    """
    Converts a MIDI file to an MP3 file.

    This function takes a MIDI object, either as a `MidiFile` object or a `MidiPiece` object,
    and first converts it to a WAV file. It then converts this WAV file to an MP3 file.

    Args:
        midi (Union[MidiFile, MidiPiece]):
            The MIDI file to convert. Can be either a `ff.MidiFile` object or a `MidiPiece` object.
        mp3_path (str, optional):
            The path where the converted MP3 file will be saved. If not specified, a temporary file is created.

    Returns:
        mp3_path (str): The path to the created MP3 file.

    Note:
        If a `MidiPiece` object is provided, it is first converted to a `MidiFile` object
        before proceeding with the WAV and then MP3 conversion.


    Examples:
        >>> some_midi = ff.MidiPiece(midi_df)
        >>> mp3_path = midi_to_mp3(some_midi, "test.mp3")
        >>> print("MP3 file created at:", mp3_path)
    """
    if isinstance(midi, structures.MidiPiece):
        midi = midi.to_midi()

    # This will be deleted
    tmp_wav_path = tempfile.mkstemp(suffix=".wav")[1]
    midi_to_wav(midi=midi, wavpath=tmp_wav_path)

    # Wav to mp3
    if not mp3_path:
        mp3_path = tempfile.mkstemp(suffix=".mp3")[1]

    print("Rendering audio to file:", mp3_path)
    AudioSegment.from_wav(tmp_wav_path).export(mp3_path, format="mp3")

    return mp3_path

midi_to_wav(midi, wavpath)

Converts a MIDI file to a WAV file.

This function takes a MIDI object, either as a ff.MidiFile object or a MidiPiece object, and converts it to a WAV file. The conversion uses the FluidSynth synthesizer with a downloaded sound font. The function also adds a silent event at the end of the MIDI sequence to ensure that the final notes have time to ring out properly.

Parameters:

Name Type Description Default
midi Union[MidiFile, MidiPiece]

The MIDI file to convert. Can be either a MidiFile object or a MidiPiece object.

required
wavpath str

The path where the converted WAV file will be saved.

required
Note

If a MidiPiece object is provided, it is first converted to a MidiFile object before proceeding with the WAV conversion.

Examples:

>>> some_midi = ff.MidiPiece(midi_df)
>>> midi_to_wav(some_midi, "test.wav")
Source code in fortepyan/audio/render.py
def midi_to_wav(midi: Union[structures.MidiFile, structures.MidiPiece], wavpath: str):
    """
    Converts a MIDI file to a WAV file.

    This function takes a MIDI object, either as a `ff.MidiFile` object or a `MidiPiece` object,
    and converts it to a WAV file. The conversion uses the FluidSynth synthesizer with a downloaded sound font.
    The function also adds a silent event at the end of the MIDI sequence to ensure that the final notes have time
    to ring out properly.

    Args:
        midi (Union[MidiFile, MidiPiece]):
            The MIDI file to convert. Can be either a `MidiFile` object or a `MidiPiece` object.
        wavpath (str):
            The path where the converted WAV file will be saved.

    Note:
        If a `MidiPiece` object is provided, it is first converted to a `MidiFile` object
        before proceeding with the WAV conversion.


    Examples:
        >>> some_midi = ff.MidiPiece(midi_df)
        >>> midi_to_wav(some_midi, "test.wav")
    """
    if isinstance(midi, structures.MidiPiece):
        midi = midi.to_midi()

    # This will be deleted
    tmp_midi_path = tempfile.mkstemp(suffix=".mid")[1]

    # Add an silent event to make sure the final notes
    # have time to ring out
    end_time = midi.duration + 0.2
    pedal_off = pretty_midi.ControlChange(64, 0, end_time)

    midi._midi.instruments[0].control_changes.append(pedal_off)

    midi.write(tmp_midi_path)

    sound_font_path = soundfont.download_if_needed()
    synth = FluidSynth(sound_font=sound_font_path)
    synth.midi_to_audio(tmp_midi_path, wavpath)

download_if_needed()

Ensures the SoundFont file is downloaded in the user's data directory.

The function checks for 'soundfont.sf2' in the user's data directory, downloading it if absent. The download URL is sourced from the application's configuration.

Returns:

Name Type Description
Path Path

The path to the SoundFont file.

Source code in fortepyan/audio/soundfont.py
def download_if_needed() -> Path:
    """
    Ensures the SoundFont file is downloaded in the user's data directory.

    The function checks for 'soundfont.sf2' in the user's data directory, downloading it if absent.
    The download URL is sourced from the application's configuration.

    Returns:
        Path: The path to the SoundFont file.
    """
    app_name = "fortepyan"
    app_author = "me"

    data_dir = appdirs.user_data_dir(app_name, app_author)
    data_dir = Path(data_dir)

    data_dir.mkdir(parents=True, exist_ok=True)

    file_path = data_dir / "soundfont.sf2"

    if not file_path.exists():
        print("Downloading SoundFont")
        urllib.request.urlretrieve(C.SOUNDFONT_URL, file_path)

    return file_path