1 /*
2 * Copyright (C) 2020-2021 Alexandros Theodotou <alex at zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Zrythm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "audio/midi_file.h"
21
22 #include <ext/midilib/src/midifile.h>
23
24 #include <gtk/gtk.h>
25
26 /**
27 * Returns whether the given track in the midi file
28 * has data.
29 */
30 bool
midi_file_track_has_data(const char * abs_path,int track_idx)31 midi_file_track_has_data (
32 const char * abs_path,
33 int track_idx)
34 {
35 MIDI_FILE * mf = midiFileOpen (abs_path);
36 g_return_val_if_fail (mf, false);
37
38 MIDI_MSG msg;
39 midiReadInitMessage (&msg);
40
41 int ev;
42 g_debug ("reading MIDI Track %d", track_idx);
43 bool have_data = false;
44 while (midiReadGetNextMessage (
45 mf, track_idx, &msg))
46 {
47 if (msg.bImpliedMsg)
48 {
49 ev = msg.iImpliedMsg;
50 }
51 else
52 {
53 ev = msg.iType;
54 }
55
56 switch(ev)
57 {
58 case msgNoteOff:
59 case msgMetaEvent:
60 break;
61 case msgNoteOn:
62 case msgNoteKeyPressure:
63 case msgSetParameter:
64 case msgSetProgram:
65 case msgChangePressure:
66 case msgSetPitchWheel:
67 case msgSysEx1:
68 case msgSysEx2:
69 have_data = true;
70 break;
71 }
72
73 if (have_data)
74 {
75 break;
76 }
77 }
78
79 midiReadFreeMessage (&msg);
80 midiFileClose (mf);
81
82 return have_data;
83 }
84
85 /**
86 * Returns the number of tracks in the MIDI file.
87 */
88 int
midi_file_get_num_tracks(const char * abs_path,bool non_empty_only)89 midi_file_get_num_tracks (
90 const char * abs_path,
91 bool non_empty_only)
92 {
93 MIDI_FILE * mf =
94 midiFileOpen (abs_path);
95 g_return_val_if_fail (mf, -1);
96
97 int actual_num = 0;
98
99 int num = midiReadGetNumTracks (mf);
100 g_debug ("%s: num tracks = %d", abs_path, num);
101
102 if (!non_empty_only)
103 {
104 midiFileClose (mf);
105 return num;
106 }
107
108 for (int i = 0; i < num; i++)
109 {
110 if (midi_file_track_has_data (abs_path, i))
111 {
112 actual_num++;
113 }
114 }
115
116 midiFileClose (mf);
117
118 return actual_num;
119 }
120