115 lines
3.2 KiB
C++
115 lines
3.2 KiB
C++
//
|
|
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
|
|
// Creation Date: Sat May 17 19:34:13 PDT 2003
|
|
// Last Modified: Mon Feb 9 21:23:13 PST 2015 Updated for C++11.
|
|
// Filename: tools/drumtab.cpp
|
|
// URL: https://github.com/craigsapp/midifile/blob/master/tools/drumtab.cpp
|
|
// Syntax: C++11
|
|
// vim: ts=3
|
|
//
|
|
// Description: Demonstration of how to convert a drum tab into
|
|
// a Multi-track MIDI file with one track for each
|
|
// drum part.
|
|
//
|
|
|
|
#include "MidiFile.h"
|
|
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
using namespace smf;
|
|
|
|
#define HIGH_HAT 59
|
|
#define SNARE 38
|
|
#define BASS_DRUM 41
|
|
|
|
#define QUARTER 120 /* ticks per quarter note */
|
|
#define SIXTEENTH 30 /* ticks per sixteenth note */
|
|
|
|
|
|
void AddDrumTrack(MidiFile& midifile, int* data, int instrument, int ticks);
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
int main(int argc, char** argv) {
|
|
MidiFile outputfile; // create an empty MIDI file with one track
|
|
outputfile.absoluteTicks(); // time information stored as absolute time
|
|
// (will be coverted to delta time when written)
|
|
outputfile.setTicksPerQuarterNote(QUARTER);
|
|
|
|
int hhdata[50] = {'x', '-', 'x', '-', 'x', '-', 'x', '-', -1};
|
|
int sndata[50] = {'-', '-', 'x', '-', '-', '-', 'x', '-', -1};
|
|
int bsdata[50] = {'x', '-', '-', '-', 'x', '-', '-', '-', -1};
|
|
|
|
AddDrumTrack(outputfile, hhdata, HIGH_HAT, SIXTEENTH);
|
|
AddDrumTrack(outputfile, sndata, SNARE, SIXTEENTH);
|
|
AddDrumTrack(outputfile, bsdata, BASS_DRUM, SIXTEENTH);
|
|
|
|
outputfile.sortTracks(); // make sure data is in correct order
|
|
outputfile.write("rhythm.mid"); // write Standard MIDI File twinkle.mid
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////
|
|
//
|
|
// AddDrumTrack -- add a new track to the MIDI file which contains
|
|
// a single percussion instrument. Tablature data is ended by a -1
|
|
//
|
|
|
|
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);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|