To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / main.cpp @ 5:7fde3cc109dc

History | View | Annotate | Download (7.68 KB)

1
/*
2
    This file copyright 2010 Chris Cannam.
3
  
4
    Permission is hereby granted, free of charge, to any person
5
    obtaining a copy of this software and associated documentation
6
    files (the "Software"), to deal in the Software without
7
    restriction, including without limitation the rights to use, copy,
8
    modify, merge, publish, distribute, sublicense, and/or sell copies
9
    of the Software, and to permit persons to whom the Software is
10
    furnished to do so, subject to the following conditions:
11

12
    The above copyright notice and this permission notice shall be
13
    included in all copies or substantial portions of the Software.
14

15
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
19
    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20
    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22

23
    Except as contained in this notice, the names of the authors
24
    shall not be used in advertising or otherwise to promote the sale,
25
    use or other dealings in this Software without prior written
26
    authorization.
27
*/
28

    
29
#include "MIDIFileReader.h"
30

    
31
#include <iostream>
32

    
33
using namespace std;
34
using namespace MIDIConstants;
35

    
36
int main(int argc, char **argv)
37
{
38
    if (argc != 2) {
39
        cerr << "Usage: midifile <file.mid>" << endl;
40
        return 1;
41
    }
42

    
43
    std::string filename = argv[1];
44

    
45
    MIDIFileReader fr(filename);
46
    if (!fr.isOK()) {
47
        std::cerr << "Error: " << fr.getError().c_str() << std::endl;
48
        return 1;
49
    }
50

    
51
    MIDIComposition c = fr.load();
52

    
53
    switch (fr.getFormat()) {
54
    case MIDI_SINGLE_TRACK_FILE: cout << "Format: MIDI Single Track File" << endl; break;
55
    case MIDI_SIMULTANEOUS_TRACK_FILE: cout << "Format: MIDI Simultaneous Track File" << endl; break;
56
    case MIDI_SEQUENTIAL_TRACK_FILE: cout << "Format: MIDI Sequential Track File" << endl; break;
57
    default: cout << "Format: Unknown MIDI file format?" << endl; break;
58
    }
59

    
60
    cout << "Tracks: " << c.size() << endl;
61

    
62
    int td = fr.getTimingDivision();
63
    if (td < 32768) {
64
        cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl;
65
    } else {
66
        int frames = 256 - (td >> 8);
67
        int subframes = td & 0xff;
68
        cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl;
69
    }
70

    
71
    for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) {
72
        
73
        cout << "Start of track: " << i->first+1 << endl;
74

    
75
        for (MIDITrack::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
76

    
77
            unsigned int t = j->getTime();
78
            int ch = j->getChannelNumber();
79

    
80
            if (j->isMeta()) {
81
                int code = j->getMetaEventCode();
82
                string name;
83
                bool printable = true;
84
                switch (code) {
85

    
86
                case MIDI_END_OF_TRACK:
87
                    cout << t << ": End of track" << endl;
88
                    break;
89

    
90
                case MIDI_TEXT_EVENT: name = "Text"; break;
91
                case MIDI_COPYRIGHT_NOTICE: name = "Copyright"; break;
92
                case MIDI_TRACK_NAME: name = "Track name"; break;
93
                case MIDI_INSTRUMENT_NAME: name = "Instrument name"; break;
94
                case MIDI_LYRIC: name = "Lyric"; break;
95
                case MIDI_TEXT_MARKER: name = "Text marker"; break;
96
                case MIDI_SEQUENCE_NUMBER: name = "Sequence number"; printable = false; break;
97
                case MIDI_CHANNEL_PREFIX_OR_PORT: name = "Channel prefix or port"; printable = false; break;
98
                case MIDI_CUE_POINT: name = "Cue point"; break;
99
                case MIDI_CHANNEL_PREFIX: name = "Channel prefix"; printable = false; break;
100
                case MIDI_SEQUENCER_SPECIFIC: name = "Sequencer specific"; printable = false; break;
101
                case MIDI_SMPTE_OFFSET: name = "SMPTE offset"; printable = false; break;
102

    
103
                case MIDI_SET_TEMPO:
104
                {
105
                    int m0 = j->getMetaMessage()[0];
106
                    int m1 = j->getMetaMessage()[1];
107
                    int m2 = j->getMetaMessage()[2];
108
                    long tempo = (((m0 << 8) + m1) << 8) + m2;
109

    
110
                    cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl;
111
                }
112
                    break;
113

    
114
                case MIDI_TIME_SIGNATURE:
115
                {
116
                    int numerator = j->getMetaMessage()[0];
117
                    int denominator = 1 << (int)j->getMetaMessage()[1];
118
                    
119
                    cout << t << ": Time signature: " << numerator << "/" << denominator << endl;
120
                }
121

    
122
                case MIDI_KEY_SIGNATURE:
123
                {
124
                    int accidentals = j->getMetaMessage()[0];
125
                    int isMinor = j->getMetaMessage()[1];
126
                    bool isSharp = accidentals < 0 ? false : true;
127
                    accidentals = accidentals < 0 ? -accidentals : accidentals;
128
                    cout << t << ": Key signature: " << accidentals << " "
129
                         << (isSharp ?
130
                             (accidentals > 1 ? "sharps" : "sharp") :
131
                             (accidentals > 1 ? "flats" : "flat"))
132
                         << (isMinor ? ", minor" : ", major") << endl;
133
                }
134

    
135
                }
136
                
137

    
138
                if (name != "") {
139
                    if (printable) {
140
                        cout << t << ": File meta event: code " << code
141
                             << ": " << name << ": \"" << j->getMetaMessage()
142
                             << "\"" << endl;
143
                    } else {
144
                        cout << t << ": File meta event: code " << code
145
                             << ": " << name << ": ";
146
                        for (int k = 0; k < j->getMetaMessage().length(); ++k) {
147
                            cout << (int)j->getMetaMessage()[k] << " ";
148
                        }
149
                    }
150
                }
151
                continue;
152
            }
153

    
154
            switch (j->getMessageType()) {
155
                
156
            case MIDI_NOTE_ON:
157
                cout << t << ": Note: channel " << ch
158
                     << " duration " << j->getDuration()
159
                     << " pitch " << j->getPitch()
160
                     << " velocity " << j->getVelocity() << endl;
161
                break;
162

    
163
            case MIDI_POLY_AFTERTOUCH:
164
                cout << t << ": Polyphonic aftertouch: channel " << ch
165
                     << " pitch " << j->getPitch()
166
                     << " pressure " << j->getData2() << endl;
167
                break;
168
                
169
            case MIDI_CTRL_CHANGE:
170
            {
171
                int controller = j->getData1();
172
                string name;
173
                switch (controller) {
174
                case MIDI_CONTROLLER_BANK_MSB: name = "Bank select MSB"; break;
175
                case MIDI_CONTROLLER_VOLUME: name = "Volume"; break;
176
                case MIDI_CONTROLLER_BANK_LSB: name = "Bank select LSB"; break;
177
                case MIDI_CONTROLLER_MODULATION: name = "Modulation wheel"; break;
178
                case MIDI_CONTROLLER_PAN: name = "Pan"; break;
179
                case MIDI_CONTROLLER_SUSTAIN: name = "Sustain"; break;
180
                case MIDI_CONTROLLER_RESONANCE: name = "Resonance"; break;
181
                case MIDI_CONTROLLER_RELEASE: name = "Release"; break;
182
                case MIDI_CONTROLLER_ATTACK: name = "Attack"; break;
183
                case MIDI_CONTROLLER_FILTER: name = "Filter"; break;
184
                case MIDI_CONTROLLER_REVERB: name = "Reverb"; break;
185
                case MIDI_CONTROLLER_CHORUS: name = "Chorus"; break;
186
                case MIDI_CONTROLLER_NRPN_1: name = "NRPN 1"; break;
187
                case MIDI_CONTROLLER_NRPN_2: name = "NRPN 2"; break;
188
                case MIDI_CONTROLLER_RPN_1: name = "RPN 1"; break;
189
                case MIDI_CONTROLLER_RPN_2: name = "RPN 2"; break;
190
                case MIDI_CONTROLLER_SOUNDS_OFF: name = "All sounds off"; break;
191
                case MIDI_CONTROLLER_RESET: name = "Reset"; break;
192
                case MIDI_CONTROLLER_LOCAL: name = "Local"; break;
193
                case MIDI_CONTROLLER_ALL_NOTES_OFF: name = "All notes off"; break;
194
                }
195
                cout << t << ": Controller change: channel " << ch
196
                     << " controller " << j->getData1();
197
                if (name != "") cout << " (" << name << ")";
198
                cout << " value " << j->getData2() << endl;
199
            }
200
                break;
201

    
202
            case MIDI_PROG_CHANGE:
203
                cout << t << ": Program change: channel " << ch
204
                     << " program " << j->getData1() << endl;
205
                break;
206

    
207
            case MIDI_CHNL_AFTERTOUCH:
208
                cout << t << ": Channel aftertouch: channel " << ch
209
                     << " pressure " << j->getData1() << endl;
210
                break;
211

    
212
            case MIDI_PITCH_BEND:
213
                cout << t << ": Pitch bend: channel " << ch
214
                     << " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl;
215
                break;
216

    
217
            case MIDI_SYSTEM_EXCLUSIVE:
218
                cout << t << ": System exclusive: code "
219
                     << (int)j->getMessageType() << " message length " <<
220
                    j->getMetaMessage().length() << endl;
221
                break;
222
                
223

    
224
            }
225

    
226
            
227
        }
228

    
229

    
230
    }
231

    
232
}
233

    
234