-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmidi-properties.cpp
131 lines (106 loc) · 4.23 KB
/
midi-properties.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <cassert>
#include <vector>
#include <jdksmidi/world.h>
#include <jdksmidi/fileread.h>
#include <jdksmidi/fileshow.h>
#include <jdksmidi/multitrack.h>
#include <jdksmidi/filereadmultitrack.h>
#include <jdksmidi/filewritemultitrack.h>
#include <jdksmidi/utils.h>
using namespace jdksmidi;
#include <iostream>
using namespace std;
void readTrack(const MIDITrack& track) {
int numEvents = track.GetNumEvents();
vector<vector<unsigned long> > activeNotesPerChannel(16);
for (int i = 0; i < 16; i++)
activeNotesPerChannel[i].resize(200,0);
std::cout << "There are " << numEvents << " events " << std::endl;
for (int i = 0; i < numEvents; i++) {
const MIDITimedBigMessage *event = track.GetEvent(i);
//std::cout << EventAsText(*event) << std::endl;
if (event->IsNoteOn()) {
int channel = (int)event->GetChannel();
int note = (int)event->GetNote();
MIDIClockTime startTime = event->GetTime();
//std::cerr << "Note On " << channel << " " << note << std::endl;
//assert(activeNotesPerChannel.at(channel).at(note) == 0);
activeNotesPerChannel[channel][note] = startTime;
}
if (event->IsNoteOff()) {
//std::cout << EventAsText(*event) << std::endl;
int channel = (int)event->GetChannel();
int note = (int)event->GetNote();
MIDIClockTime stopTime = event->GetTime();
//assert(activeNotesPerChannel.at(channel).at(note) != 0);
unsigned long onset = activeNotesPerChannel.at(channel).at(note);
unsigned long duration = stopTime - onset;
std::cout << "This should be a triple: " << note << " " << onset << " " << duration << std::endl;
// do something here and then restore to zero
activeNotesPerChannel[channel][note] = 0;
}
}
}
void readTracks(const MIDIMultiTrack& tracks) {
int numTracks = tracks.GetNumTracks();
//std::cout << "There are " << numTracks << std::endl;
for (int i = 0; i < numTracks; i++)
readTrack(*(tracks.GetTrack(i)));
}
int main ( int argc, char **argv ) {
if ( argc > 2 ) {
const char *infile_name = argv[1];
const char* outfile_name = argv[2];
MIDIFileReadStreamFile rs ( infile_name );
if ( !rs.IsValid() ) {
cerr << "\nError opening file " << infile_name << endl;
return -1;
}
// the multitrack object which will hold all the tracks
MIDIMultiTrack tracks( 1 ); // only 1 track in multitrack object - not enough for midifile format 1
// the object which loads the tracks into the tracks object
MIDIFileReadMultiTrack track_loader ( &tracks );
// the object which parses the midifile and gives it to the multitrack loader
MIDIFileRead reader ( &rs, &track_loader );
// make amount of of tracks equal to midifile_num_tracks
int midifile_num_tracks = reader.ReadNumTracks();
tracks.ClearAndResize( midifile_num_tracks );
/*
// if true print META_SEQUENCER_SPECIFIC events as text string
bool sqspecific_as_text = true;
MIDIFileShow shower ( stdout, sqspecific_as_text );
MIDIFileRead reader ( &rs, &shower );
*/
if ( !reader.Parse() ) {
cerr << "\nError parse file " << infile_name << endl;
return -1;
}
readTracks(tracks);
// writing
// create the output stream
MIDIFileWriteStreamFileName out_stream ( outfile_name );
if ( out_stream.IsValid() ) {
// the object which takes the midi tracks and writes the midifile to the output stream
MIDIFileWriteMultiTrack writer ( &tracks, &out_stream );
// uncomment this string for output midifile without running status usage
// writer.UseRunningStatus( false );
// extract the original multitrack division
int division = reader.GetDivision();
// get really number of track, used in reader.Parse() process
int num_tracks = tracks.GetNumTracksWithEvents();
// write the output midi file
if ( writer.Write ( num_tracks, division ) ) {
cout << "\nAll OK. Number of tracks with events " << num_tracks << endl;;
} else {
cerr << "\nError writing file " << outfile_name << endl;
}
} else {
cerr << "\nError opening file " << outfile_name << endl;
}
}
else {
cerr << "usage:\n\tjdkmidi_test_show INFILE.mid\n";
return -1;
}
return 0;
}