diff --git a/dashboards/merge_files.py b/dashboards/merge_files.py new file mode 100644 index 0000000..e4cd192 --- /dev/null +++ b/dashboards/merge_files.py @@ -0,0 +1,40 @@ +import streamlit as st +from streamlit_pianoroll import from_fortepyan + +from fortepyan import MidiFile + + +def main(): + st.write("# Test MidiFile merging") + uploaded_files = st.file_uploader( + label="Upload one or many MIDI files", + accept_multiple_files=True, + ) + + if not uploaded_files: + st.write("Waiting for files") + return + + midi_files = [] + for uploaded_file in uploaded_files: + midi_file = MidiFile.from_file(uploaded_file) + midi_files.append(midi_file) + + merge_spacing = st.number_input( + label="merge spacing [s] (time interval inserted between files)", + min_value=0.0, + max_value=30.0, + value=5.0, + ) + merged_midi_file = MidiFile.merge_files( + midi_files=midi_files, + space=merge_spacing, + ) + st.write("Duration after merge:", merged_midi_file.duration) + st.write("Number of notes after merge:", merged_midi_file.piece.size) + + from_fortepyan(merged_midi_file.piece) + + +if __name__ == "__main__": + main() diff --git a/fortepyan/midi/structures.py b/fortepyan/midi/structures.py index 35f090c..c783b43 100644 --- a/fortepyan/midi/structures.py +++ b/fortepyan/midi/structures.py @@ -1,5 +1,5 @@ import json -from typing import Optional +from typing import IO, Optional from dataclasses import field, dataclass import numpy as np @@ -472,6 +472,22 @@ def piece(self) -> MidiPiece: ) return out + @classmethod + def from_file(cls, midi_file: IO) -> "MidiFile": + """ + Generic wrapper for the pretty_midi.PrettyMIDI interface. + + Args: + midi_file (str or file): Path or file pointer to a MIDI file. + + Returns: + MidiFile: A new `MidiFile` object containing the input file. + """ + _midi = pretty_midi.PrettyMIDI(midi_file) + + midi_file = cls(_midi=_midi) + return midi_file + @classmethod def from_piece(cls, piece: MidiPiece) -> "MidiFile": _midi = pretty_midi.PrettyMIDI() diff --git a/pyproject.toml b/pyproject.toml index 8c7f2b1..01a6427 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,8 +28,15 @@ dependencies = [ "Levenshtein>=0.20.9", "cmcrameri>=1.5", ] + requires-python = ">=3.9" +[project.optional-dependencies] +dev = [ + "pre-commit ~= 3.8.0", + "streamlit-pianoroll == 0.7.1" +] + [project.urls] Homepage = "https://github.com/Nospoko/fortepyan"