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);
}
예제 #2
0
파일: mid2mat.cpp 프로젝트: mdsmus/humdrum
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);
      }
   }

}
예제 #3
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();

}