2024-07-15 11:46:59 +08:00

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);
}
}