1 //
2 // Programmer:    Craig Stuart Sapp <craig@ccrma.stanford.edu>
3 // Creation Date: Tue Jan  8 10:08:15 PST 2002
4 // Last Modified: Mon Feb  9 21:24:41 PST 2015 Updated for C++11.
5 // Filename:      ...sig/doc/examples/all/createmidifile/createmidifile.cpp
6 // Syntax:        C++
7 //
8 // Description:   Demonstration of how to create a Multi-track MIDI file.
9 //
10 
11 #include "MidiFile.h"
12 #include <iostream>
13 
14 using namespace std;
15 using namespace smf;
16 
17 ///////////////////////////////////////////////////////////////////////////
18 
main(int argc,char ** argv)19 int main(int argc, char** argv) {
20    MidiFile outputfile;        // create an empty MIDI file with one track
21    outputfile.absoluteTicks();  // time information stored as absolute time
22                                // (will be coverted to delta time when written)
23    outputfile.addTrack(2);     // Add another two tracks to the MIDI file
24    vector<uchar> midievent;     // temporary storage for MIDI events
25    midievent.resize(3);        // set the size of the array to 3 bytes
26    int tpq = 120;              // default value in MIDI file is 48
27    outputfile.setTicksPerQuarterNote(tpq);
28 
29    // data to write to MIDI file: (60 = middle C)
30    // C5 C  G G A A G-  F F  E  E  D D C-
31    int melody[50]  = {72,72,79,79,81,81,79,77,77,76,76,74,74,72,-1};
32    int mrhythm[50] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,-1};
33 
34    // C3 C4 E C F C E C D B3 C4 A3 F G C-
35    int bass[50] =   {48,60,64,60,65,60,64,60,62,59,60,57,53,55,48,-1};
36    int brhythm[50]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,-1};
37 
38 
39    // store a melody line in track 1 (track 0 left empty for conductor info)
40    int i=0;
41    int actiontime = 0;      // temporary storage for MIDI event time
42    midievent[2] = 64;       // store attack/release velocity for note command
43    while (melody[i] >= 0) {
44       midievent[0] = 0x90;     // store a note on command (MIDI channel 1)
45       midievent[1] = melody[i];
46       outputfile.addEvent(1, actiontime, midievent);
47       actiontime += tpq * mrhythm[i];
48       midievent[0] = 0x80;     // store a note on command (MIDI channel 1)
49       outputfile.addEvent(1, actiontime, midievent);
50       i++;
51    }
52 
53    // store a base line in track 2
54    i=0;
55    actiontime = 0;          // reset time for beginning of file
56    midievent[2] = 64;
57    while (bass[i] >= 0) {
58       midievent[0] = 0x90;
59       midievent[1] = bass[i];
60       outputfile.addEvent(2, actiontime, midievent);
61       actiontime += tpq * brhythm[i];
62       midievent[0] = 0x80;
63       outputfile.addEvent(2, actiontime, midievent);
64       i++;
65    }
66 
67    outputfile.sortTracks();         // make sure data is in correct order
68    outputfile.write("twinkle.mid"); // write Standard MIDI File twinkle.mid
69    return 0;
70 }
71 
72 
73 /*  FUNCTIONS available in the MidiFile class:
74 
75 void absoluteTime(void);
76    Set the time information to absolute time.
77 int addEvent(int aTrack, int aTime, vector<uchar>& midiData);
78    Add an event to the end of a MIDI track.
79 int addTrack(void);
80    Add an empty track to the MIDI file.
81 int addTrack(int count);
82    Add a number of empty tracks to the MIDI file.
83 void deltaTime(void);
84    Set the time information to delta time.
85 void deleteTrack(int aTrack);
86    remove a track from the MIDI file.
87 void erase(void);
88    Empty the contents of the MIDI file, leaving one track with no data.
89 MFEvent& getEvent(int aTrack, int anIndex);
90    Return a MIDI event from the Track.
91 int getTimeState(void);
92    Indicates if the timestate is TIME_STATE_ABSOLUTE or TIME_STATE_DELTA.
93 int getTrackState(void);
94    Indicates if the tracks are being processed as multiple tracks or
95    as a single track.
96 int getTicksPerQuarterNote(void);
97    Returns the ticks per quarter note value from the MIDI file.
98 int getTrackCount(void);
99    Returns the number of tracks in the MIDI file.
100 int getNumTracks(void);
101    Alias for getTrackCount();
102 int getNumEvents(int aTrack);
103    Return the number of events present in the given track.
104 void joinTracks(void);
105    Merge all tracks together into one track.  This function is reversable,
106    unlike mergeTracks().
107 void mergeTracks(int aTrack1, int aTrack2);
108    Combine the two tracks into a single track stored in Track1.  Track2
109    is deleted.
110 int read(char* aFile);
111    Read the contents of a MIDI file into the MidiFile class data structure
112 void setTicksPerQuarterNote    (int ticks);
113    Set the MIDI file's ticks per quarter note information
114 void sortTrack(vector<MFEvent>& trackData);
115    If in absolute time, sort particular track into correct time order.
116 void sortTracks(void);
117    If in absolute time, sort tracks into correct time order.
118 
119 */
120 
121 
122 
123