From 5f18fd806841e2cb2e68efc6f5b8ee816acf30f3 Mon Sep 17 00:00:00 2001 From: fosfrancesco Date: Fri, 18 Aug 2023 11:30:47 +0200 Subject: [PATCH] add a bugfix for midi scores that only report time signature in one track. Now this ts is shared between all the tracks --- partitura/io/importmidi.py | 12 ++++++++++++ tests/__init__.py | 4 ++++ tests/data/midi/bach_midi_score.mid | Bin 0 -> 5200 bytes tests/test_midi_import.py | 9 +++++++++ 4 files changed, 25 insertions(+) create mode 100644 tests/data/midi/bach_midi_score.mid diff --git a/partitura/io/importmidi.py b/partitura/io/importmidi.py index ecfe2be3..ff5421b6 100644 --- a/partitura/io/importmidi.py +++ b/partitura/io/importmidi.py @@ -473,6 +473,18 @@ def load_score_midi( else: note_ids = [None for i in range(len(note_array))] + ## sanitize time signature, when they are only present in one track, and no global is set + # find the number of ts per each track + number_of_time_sig_per_track = [len(time_sigs_by_track[t]) for t in key_sigs_by_track.keys()] + # if one track has 0 ts, and another has !=0 ts, and no global_time_sigs is present, sanitize + # all key signatures are copied to global, and the track ts are removed + if len(global_time_sigs) == 0 and min(number_of_time_sig_per_track) == 0 and max(number_of_time_sig_per_track)!= 0: + warnings.warn("Sanitizing time signatures. They will be shared across all tracks.") + for ts in [ts for ts_track in time_sigs_by_track.values() for ts in ts_track]: #flattening all track time signatures to a list of ts + global_time_sigs.append(ts) + # now clear all track_ts + time_sigs_by_track.clear() + time_sigs_by_part = defaultdict(set) for tr, ts_list in time_sigs_by_track.items(): for ts in ts_list: diff --git a/tests/__init__.py b/tests/__init__.py index ce7bf09c..80e898ab 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -236,4 +236,8 @@ MIDIEXPORT_TESTFILES = [ os.path.join(DATA_PATH, "musicxml", "test_anacrusis.xml") +] + +MIDIINPORT_TESTFILES = [ + os.path.join(DATA_PATH, "midi", "bach_midi_score.mid") ] \ No newline at end of file diff --git a/tests/data/midi/bach_midi_score.mid b/tests/data/midi/bach_midi_score.mid new file mode 100644 index 0000000000000000000000000000000000000000..d2f945a4b586b543ca93030ba2d25c08ee5fc32f GIT binary patch literal 5200 zcmeHKOKuxS5UsX?DDerhO!fjKS|Uw-DblnoL8e%gwMY;IgaI!ic%dMh2A2{cWScAa z20ns!xkhfHyy;gQ*O=W3H`!$~tbSep-wa1rzrGWZuO-Nn@b~EI_xB=C-^;^~U#+cu z_l-RK^kiM+VY0UV;d}Ww6Zs_aas8b5#(eHKAz>=Ee|P?0h~;}CeLj^ zFW@UYw?VVhD{#K5qRQNvoK>#YY4KM}@$rcNUzW{btd=DQGi7Gxo<*D*94Dpx>!_iJ zJ+jPS!Z{Jk{3V>dnU?L$J*{UQ!dsif6!pwK{{>G`TU?}*KeIFwGtLB;@ZT5E zX<3RIQYX&_8V6!=5lOPN8@O$#hdN(te4U#D;^bMDq6Ws5IA^3^YJ4f?1Ff?z#~P0% z!_(8)lW?H%KtfkzS7z>6#1Azd=J-o^%1K6l3GZv{=k%BG7aCtk*weTtGxrPy{O-D= zu_Iwuf7%3@&dIcMBYtOIE`fA-g8LFINLH0$4BKUym zCFm4TFG2XiIW(^O@!^8&VN>|Y`R!kePtEi_*}}?gRT8&1D8x2S+x4l9Q@cKOa6+iY z*}OBk1870{Yn}5cbh0H$4jyv zrw=|N(!?2~zoiwAdt_hZzBQZ0&TeXJMA|K`L>hQ!cJXOrdu^a)dHb;XL3il zJ90YbQ*f>l4Sit*K1ybVc!_3q$y1^^xa29(C0UQt2Okk>;=W40J|3qJX}yIbjmQ>n zNfReRyF^HHJ&>kFuYsDqHX>HAZPW(c-$NBsQPL#ZDA}~Nz>=oaCMu2D9>BeYm(=LH zi}r}D=1sN0$;lXeJU+9J+seAU4_{NSCztKC32;-wJ_7%I*9C}XrVY+ROCy3O?QzZz z@e)nH$y1^kEqO|GN!H`b^Gt7v``VDEMUO8do^!Dms$E&{*#Ba0C!HM>0{gy=pR|oq zlUjA`??=6VQpvJlAL4ieTT_^L7Bpqn_{Nz9v*KCs7}k%!w4McV|b?jHl>yfFX( literal 0 HcmV?d00001 diff --git a/tests/test_midi_import.py b/tests/test_midi_import.py index cf31f169..0255d38e 100644 --- a/tests/test_midi_import.py +++ b/tests/test_midi_import.py @@ -13,6 +13,7 @@ from partitura import load_score_midi from partitura.utils import partition import partitura.score as score +from tests import MIDIINPORT_TESTFILES LOGGER = logging.getLogger(__name__) @@ -310,3 +311,11 @@ def test_midi_import_mode_5(self): def tearDown(self): # remove tmp file self.tmpfile = None + +class TestScoreMidi(unittest.TestCase): + def test_time_signature(self): + score = load_score_midi(MIDIINPORT_TESTFILES[0]) + self.assertEqual(score.note_array()["onset_beat"][2], 0.5) + na = score.note_array(include_time_signature=True) + self.assertTrue(all([n==3 for n in na["ts_beats"]])) + self.assertTrue(all([d==8 for d in na["ts_beat_type"]])) \ No newline at end of file