예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #4
0
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();

}