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 convertMidiFile(MidiFile& midifile, Array<Array<double> >& matlab) { midifile.absoluteTime(); midifile.joinTracks(); Array<double> event(7); event.allowGrowth(0); Array<double> ontimes(128); Array<int> onvelocities(128); int i; for (i=0; i<128; i++) { ontimes[i] = -1.0; onvelocities[i] = -1; } double offtime = 0.0; int key = 0; int vel = 0; int command = 0; if (verboseQ) { cout << "-1\ttpq\t" << midifile.getTicksPerQuarterNote() << endl; } for (i=0; i<midifile.getNumEvents(0); i++) { event.setAll(unused); command = midifile.getEvent(0, i).data[0] & 0xf0; if (command == 0xf0) { command = midifile.getEvent(0, i).data[0]; } if (command == 0x90 && midifile.getEvent(0, i).data[2] != 0) { // store note-on velocity and time key = midifile.getEvent(0, i).data[1]; vel = midifile.getEvent(0, i).data[2]; ontimes[key] = getTime(midifile.getEvent(0, i).time, tempo, midifile.getTicksPerQuarterNote()); onvelocities[key] = vel; } else if (command == 0x90 || command == 0x80) { // note off command write to output key = midifile.getEvent(0, i).data[1]; offtime = getTime(midifile.getEvent(0, i).time, tempo, midifile.getTicksPerQuarterNote()); legend_opcode[OP_NOTE/1000] = 1; if (verboseQ) { cout << ontimes[key] << "\tnote" << "\tdur=" << offtime - ontimes[key] << "\tpch=" << key << "\tvel=" << onvelocities[key] << "\tch=" << (midifile.getEvent(0, i).data[0] & 0x0f) << "\ttrack=" << midifile.getEvent(0, i).track << endl; } else { event[0] = ontimes[key]; event[1] = OP_NOTE; event[2] = offtime - ontimes[key]; event[3] = key; event[4] = onvelocities[key]; event[5] = (midifile.getEvent(0, i).data[0] & 0x0f); event[6] = midifile.getEvent(0, i).track; } } else if (command == 0xb0) { legend_controller[midifile.getEvent(0,i).data[1]] = 1; legend_opcode[OP_CONTROL/1000] = 1; if (verboseQ) { cout << getTime(midifile.getEvent(0,i).time, tempo, midifile.getTicksPerQuarterNote()) << "\tcontrol" << "\ttype=" << (int)midifile.getEvent(0, i).data[1] << "\tval=" << (int)midifile.getEvent(0, i).data[2] << "\tch=" << (midifile.getEvent(0, i).data[0] & 0x0f) << "\ttrack=" << midifile.getEvent(0, i).track << "\n"; } else { event[0] = getTime(midifile.getEvent(0,i).time, tempo, midifile.getTicksPerQuarterNote()); event[1] = OP_CONTROL; event[2] = (int)midifile.getEvent(0,i).data[1]; event[3] = (int)midifile.getEvent(0,i).data[2]; event[5] = (midifile.getEvent(0, i).data[0] & 0x0f); event[6] = midifile.getEvent(0, i).track; } } else if (command == 0xc0) { legend_instr[midifile.getEvent(0,i).data[1]] = 1; legend_opcode[OP_INSTR/1000] = 1; if (verboseQ) { cout << getTime(midifile.getEvent(0,i).time, tempo, midifile.getTicksPerQuarterNote()) << "\tinstr" << "\tname=" << GMinstrument[midifile.getEvent(0,i).data[1]] << "\tnum=" << (int)midifile.getEvent(0, i).data[1] << "\tch=" << (midifile.getEvent(0, i).data[0] & 0x0f) << "\ttrack=" << midifile.getEvent(0, i).track << "\n"; } else { event[0] = getTime(midifile.getEvent(0,i).time, tempo, midifile.getTicksPerQuarterNote()); event[1] = OP_INSTR; event[2] = (int)midifile.getEvent(0, i).data[1]; event[5] = (midifile.getEvent(0, i).data[0] & 0x0f); event[6] = midifile.getEvent(0, i).track; } } else if (command == 0xff) { if (verboseQ) { cout << getTime(midifile.getEvent(0,i).time, tempo, midifile.getTicksPerQuarterNote()) << "\t"; } else { event[0] = getTime(midifile.getEvent(0,i).time, tempo, midifile.getTicksPerQuarterNote()); } processMetaEvent(midifile, i, event); if (verboseQ) { cout << "\n"; } } // check for tempo indication if (midifile.getEvent(0, i).data[0] == 0xff && midifile.getEvent(0, i).data[1] == 0x51) { setTempo(midifile, i, tempo); } if (event[1] != unused) { matlab.append(event); } } }
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(); }