void createMidiFile(const char* filename, vector<vector<int> >& sequence) { MidiFile midifile; midifile.absoluteTicks(); midifile.addTrack(1); int tpq = 120; double beat = 0.0; midifile.setTicksPerQuarterNote(tpq); MidiEvent tempo; tempo.setMetaTempo(60.0); tempo.track = 0; tempo.tick = 0; midifile.addEvent(tempo); int maxlen = 0; int i, j; for (i=0; i<(int)sequence.size(); i++) { if ((int)sequence[i].size() > maxlen) { maxlen = sequence[i].size(); } } vector<int> notelist; MidiEvent noteon(0x90, 0, 64); MidiEvent noteoff(0x80, 0, 64); noteon.track = 1; noteoff.track = 1; for (i=0; i<maxlen; i++) { notelist.clear(); for (j=0; j<(int)sequence.size(); j++) { if (i<(int)sequence[j].size()) { notelist.push_back(sequence[j][i]); } } for (j=0; j<(int)notelist.size(); j++) { noteon[1] = 0x7f & notelist[j]; noteoff[1] = 0x7f & notelist[j]; noteon.tick = (int)(beat * tpq + 0.5); noteoff.tick = (int)(beat * tpq + 1 * tpq + 0.5); midifile.addEvent(noteon); midifile.addEvent(noteoff); } beat += 1.0; } midifile.sortTracks(); midifile.write(filename); }
void AddDrumTrack(MidiFile& midifile, int* data, int instrument, int ticks) { vector<uchar> midievent; // temporary storage for MIDI events midievent.resize(3); // set the size of the array to 3 bytes midievent[2] = 64; // set the loudness to a constant value int notestate = 0; // 0 = off, 1 = on int i = 0; int actiontime; int track = midifile.addTrack(); // Add a track to the MIDI file while (data[i] >= 0) { switch (data[i]) { case 'x': case 'X': if (notestate) { // turn off previous note midievent[0] = 0x89; midievent[1] = instrument; actiontime = ticks * i - 1; midifile.addEvent(track, actiontime, midievent); } // turn on current note midievent[0] = 0x99; midievent[1] = instrument; actiontime = ticks * i; midifile.addEvent(track, actiontime, midievent); notestate = 1; break; case '0': case 'o': case 'O': // turn off previous note if (notestate) { midievent[0] = 0x89; midievent[1] = instrument; actiontime = ticks * i - 1; midifile.addEvent(track, actiontime, midievent); notestate = 0; } break; } i++; } if (notestate) { // turn off last note midievent[0] = 0x89; midievent[1] = instrument; actiontime = ticks * i; midifile.addEvent(track, actiontime, midievent); } }
void midiProcessing::generateMidiFile(const char *filePath, int size) { srand (time(NULL)); MidiFile outputFile; outputFile.absoluteTime(); outputFile.addTrack(1); outputFile.setTicksPerQuarterNote(tpq); Array<uchar> midiEvent; midiEvent.setSize(3); int actionTime = 0; int tempVectorIndex = 0; std::vector<note> tempNote; int tempIndex; for (int i = 0; i < size; i++) { tempNote = midiProcessing::markovList.at(tempVectorIndex); tempIndex = (rand() % (midiProcessing::markovList.at(tempVectorIndex).size()-1)) + 1; midiEvent[0] = 0x90; midiEvent[1] = tempNote.at(tempIndex).getNumber(); midiEvent[2] = tempNote.at(tempIndex).getVelocity(); outputFile.addEvent(1, actionTime, midiEvent); midiEvent[0] = 0x80; outputFile.addEvent(1, (tempNote.at(tempIndex).getDuration())+actionTime, midiEvent); actionTime += tempNote.at(tempIndex).getRest(); for (int j = 0; j < midiProcessing::markovList.size(); j++) { if (midiProcessing::markovList.at(j).at(0).getNumber() == tempNote.at(tempIndex).getNumber()) { tempVectorIndex = j; break; } } } outputFile.sortTracks(); outputFile.write(filePath); }
void createMidiFile(MidiFile& midifile, HumdrumFile& infile) { Array<int> millitimes; Array<double> velocities; Array<int> keynum; Array<int> track; millitimes.setSize(infile.getNumLines()); velocities.setSize(infile.getNumLines()); keynum.setSize(infile.getNumLines()); track.setSize(infile.getNumLines()); millitimes.setSize(0); velocities.setSize(0); keynum.setSize(0); track.setSize(0); int intval; double floatval; double dmax = -100000; double dmin = +100000; int i; for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isData()) { continue; } sscanf(infile[i][0], "%lf", &floatval); intval = int(floatval * 1000.0 + 0.5); millitimes.append(intval); sscanf(infile[i][1], "%lf", &floatval); velocities.append(floatval); if (floatval < dmin) { dmin = floatval; } if (floatval > dmax) { dmax = floatval; } intval = getMIDIKeyNum(infile[i][2]); keynum.append(intval); intval = getTrackNumber(infile[i][2]); track.append(intval); } millitimes.allowGrowth(0); velocities.allowGrowth(0); keynum.allowGrowth(0); track.allowGrowth(0); // normalize the dynamics data into the range from 0 to 1 double diff = dmax - dmin; for (i=0; i<velocities.getSize(); i++) { if (diff > 0.0) { velocities[i] = (velocities[i] - dmin) / diff; } else { velocities[i] = 0.5; } } // now ready to write the data to the MIDI file: midifile.setMillisecondDelta(); // SMPTE 25 frames & 40 subframes midifile.absoluteTime(); // Time values inserted are absolute midifile.addTrack(2); // Right and Left hands Array<uchar> event; event.setSize(3); int intdur = int(duration * 1000.0 + 0.5); int lasttime = 0; int dyndiff = maxdyn - mindyn; int vel; for (i=0; i<millitimes.getSize(); i++) { if ((keynum[i] <= 10) || (keynum[i] > 127)) { continue; } vel = int(velocities[i] * dyndiff + mindyn + 0.5); if (vel < 1) { vel = 1; } if (vel > 127) { vel = 127; } event[0] = 0x90; // note-on event[1] = keynum[i]; event[2] = vel; midifile.addEvent(track[i], millitimes[i], event); event[2] = 0; lasttime = millitimes[i] + intdur; midifile.addEvent(track[i], lasttime, event); } // write the end of track marker event[0] = 0xff; event[1] = 0x2f; event[2] = 0; for (i=0; i<midifile.getTrackCount(); i++) { if (i>0) { // have to lengthen the last note in track due to bugs // in various MIDI playback programs which clip // the last chord of a file midifile.getEvent(i, midifile.getNumEvents(i)-1).time += 1500; } midifile.addEvent(i, lasttime+2000, event); } // add comments from header for (i=0; i<infile.getNumLines() && i<lasttime; i++) { if (infile[i].isBibliographic() || infile[i].isGlobalComment()) { // 0x01 is a text event midifile.addMetaEvent(0, i, 0x01, infile[i].getLine()); } } // sort the ontimes and offtimes so they are in correct time order: midifile.sortTracks(); }