Skip to content

Commit

Permalink
update midifile
Browse files Browse the repository at this point in the history
  • Loading branch information
rettinghaus committed Apr 22, 2024
1 parent da4bac4 commit 22c48d8
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 9 deletions.
2 changes: 2 additions & 0 deletions include/midi/Binasc.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ class Binasc {
int getWord (std::string& word, const std::string& input,
const std::string& terminators, int index);

static const char *GMinstrument[128];

};

} // end of namespace smf
Expand Down
6 changes: 6 additions & 0 deletions include/midi/MidiEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#define _MIDIEVENT_H_INCLUDED

#include "MidiMessage.h"

#include <ostream>
#include <vector>

namespace smf {
Expand Down Expand Up @@ -63,6 +65,10 @@ class MidiEvent : public MidiMessage {

};


std::ostream& operator<<(std::ostream& out, MidiEvent& event);


} // end of namespace smf

#endif /* _MIDIEVENT_H_INCLUDED */
Expand Down
16 changes: 11 additions & 5 deletions include/midi/MidiFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@
#include <istream>
#include <fstream>

#define TIME_STATE_DELTA 0
#define TIME_STATE_ABSOLUTE 1
enum
{
TIME_STATE_DELTA = 0,
TIME_STATE_ABSOLUTE = 1
};

#define TRACK_STATE_SPLIT 0
#define TRACK_STATE_JOINED 1
enum
{
TRACK_STATE_SPLIT = 0,
TRACK_STATE_JOINED = 1
};

namespace smf {

Expand Down Expand Up @@ -217,7 +223,7 @@ class MidiFile {
MidiEvent* addTempo (int aTrack, int aTick,
double aTempo);
MidiEvent* addKeySignature (int aTrack, int aTick,
int key, bool mode = 0);
int fifths, bool mode = 0);
MidiEvent* addTimeSignature (int aTrack, int aTick,
int top, int bottom,
int clocksPerClick = 24,
Expand Down
10 changes: 10 additions & 0 deletions include/midi/MidiMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#ifndef _MIDIMESSAGE_H_INCLUDED
#define _MIDIMESSAGE_H_INCLUDED

#include <iostream>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -122,6 +123,12 @@ class MidiMessage : public std::vector<uchar> {
void makePatchChange (int channel, int patchnum);
void makeTimbre (int channel, int patchnum);
void makeController (int channel, int num, int value);
void makePitchBend (int channel, int lsb, int msb);
void makePitchBend (int channel, int value);
void makePitchBendDouble (int channel, double value);
void makePitchbend (int channel, int lsb, int msb) { makePitchBend(channel, lsb, msb); }
void makePitchbend (int channel, int value) { makePitchBend(channel, value); }
void makePitchbendDouble (int channel, double value) { makePitchBendDouble(channel, value); }

// helper functions to create various continuous controller messages:
void makeSustain (int channel, int value);
Expand Down Expand Up @@ -199,6 +206,9 @@ class MidiMessage : public std::vector<uchar> {
};


std::ostream& operator<<(std::ostream& out, MidiMessage& event);


} // end of namespace smf


Expand Down
29 changes: 28 additions & 1 deletion src/midi/Binasc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,31 @@

namespace smf {

const char* Binasc::GMinstrument[128] = {
"acoustic grand piano", "bright acoustic piano", "electric grand piano", "honky-tonk piano", "rhodes piano", "chorused piano",
"harpsichord", "clavinet", "celeste", "glockenspiel", "music box", "vibraphone",
"marimba", "xylophone", "tubular bells", "dulcimer", "hammond organ", "percussive organ",
"rock organ", "church organ", "reed organ", "accordion", "harmonica", "tango accordion",
"nylon guitar", "steel guitar", "jazz guitar", "clean guitar", "muted guitar", "overdriven guitar",
"distortion guitar", "guitar harmonics", "acoustic bass", "fingered electric bass", "picked electric bass", "fretless bass",
"slap bass 1", "slap bass 2", "synth bass 1", "synth bass 2", "violin", "viola",
"cello", "contrabass", "tremolo strings", "pizzcato strings", "orchestral harp", "timpani",
"string ensemble 1", "string ensemble 2", "synth strings 1", "synth strings 1", "choir aahs", "voice oohs",
"synth voices", "orchestra hit", "trumpet", "trombone", "tuba", "muted trumpet",
"frenc horn", "brass section", "syn brass 1", "synth brass 2", "soprano sax", "alto sax",
"tenor sax", "baritone sax", "oboe", "english horn", "bassoon", "clarinet",
"piccolo", "flute", "recorder", "pan flute", "bottle blow", "shakuhachi",
"whistle", "ocarina", "square wave", "saw wave", "calliope lead", "chiffer lead",
"charang lead", "voice lead", "fifths lead", "brass lead", "newage pad", "warm pad",
"polysyn pad", "choir pad", "bowed pad", "metallic pad", "halo pad", "sweep pad",
"rain", "soundtrack", "crystal", "atmosphere", "brightness", "goblins",
"echoes", "sci-fi", "sitar", "banjo", "shamisen", "koto",
"kalimba", "bagpipes", "fiddle", "shanai", "tinkle bell", "agogo",
"steel drums", "woodblock", "taiko drum", "melodoc tom", "synth drum", "reverse cymbal",
"guitar fret noise", "breath noise", "seashore", "bird tweet", "telephone ring", "helicopter",
"applause", "gunshot"
};

//////////////////////////////
//
// Binasc::Binasc -- Constructor: set the default option values.
Expand Down Expand Up @@ -717,7 +742,9 @@ int Binasc::readMidiEvent(std::ostream& out, std::istream& infile,
output << " '" << std::dec << (int)byte1;
if (m_commentsQ) {
output << "\t";
comment += "patch-change";
comment += "patch-change (";
comment += GMinstrument[byte1 & 0x7f];
comment += ")";
}
break;
case 0xD0: // channel pressure: 1 bytes
Expand Down
14 changes: 14 additions & 0 deletions src/midi/MidiEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,20 @@ double MidiEvent::getDurationInSeconds(void) const {
}



//////////////////////////////
//
// operator<<(MidiMessage) -- Print tick value followed by MIDI bytes for event.
// The tick value will be either relative or absolute depending on the state
// of the MidiFile object containing it.
//

std::ostream& operator<<(std::ostream& out, MidiEvent& event) {
out << event.tick << '(' << static_cast<MidiMessage&>(event) << ')';
return out;
}


} // end namespace smf


Expand Down
88 changes: 85 additions & 3 deletions src/midi/MidiMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@

#include <cmath>
#include <iostream>
#include <iomanip>
#include <iterator>

#include <stdlib.h>


Expand Down Expand Up @@ -315,11 +317,13 @@ bool MidiMessage::isMetaMessage(void) const {
//

bool MidiMessage::isNoteOff(void) const {
if (size() != 3) {
const MidiMessage& message = *this;
const vector<uchar>& chars = message;
if (message.size() != 3) {
return false;
} else if (((*this)[0] & 0xf0) == 0x80) {
} else if ((chars[0] & 0xf0) == 0x80) {
return true;
} else if ((((*this)[0] & 0xf0) == 0x90) && ((*this)[2] == 0)) {
} else if (((chars[0] & 0xf0) == 0x90) && (chars[2] == 0x00)) {
return true;
} else {
return false;
Expand Down Expand Up @@ -1764,6 +1768,60 @@ void MidiMessage::makeController(int channel, int num, int value) {



/////////////////////////////
//
// MidiMessage::makePitchBend -- Create a pitch-bend message. lsb is
// least-significant 7 bits of the 14-bit range, and msb is the
// most-significant 7 bits of the 14-bit range. The range depth
// is determined by a setting in the synthesizer. Typically it is
// +/- two semitones by default. See MidiFile::setPitchBendRange()
// to change the default (or change to the typical default).
//

void MidiMessage::makePitchBend(int channel, int lsb, int msb) {
resize(0);
push_back(0xe0 | (0x0e & channel));
push_back(0x7f & lsb);
push_back(0x7f & msb);
}

//
// value is a 14-bit number, where 0 is the lowest pitch of the range, and
// 2^15-1 is the highest pitch of the range.
//

void MidiMessage::makePitchBend(int channel, int value) {
resize(0);
int lsb = value & 0x7f;
int msb = (value >> 7) & 0x7f;
push_back(0xe0 | (0x7f & channel));
push_back(lsb);
push_back(msb);
}

//
// value is a number between -1.0 and +1.0.
//

void MidiMessage::makePitchBendDouble(int channel, double value) {
// value is in the range from -1 for minimum and 2^18 - 1 for the maximum
resize(0);
int ivalue = (value + 1.0) * (pow(2, 15));
if (ivalue < 0) {
ivalue = 0;
}
if (ivalue > pow(2, 15) - 1) {
ivalue = pow(2, 15) - 1;
}
int lsb = ivalue & 0x7f;
int msb = (ivalue >> 7) & 0x7f;
push_back(0xe0 | (0x7f & channel));
push_back(lsb);
push_back(msb);
}



/////////////////////////////
//
// MidiMessage::makeSustain -- Create a sustain pedal message.
Expand Down Expand Up @@ -2294,6 +2352,30 @@ void MidiMessage::makeTemperamentMeantoneCommaHalf(int referencePitchClass, int
}



//////////////////////////////
//
// operator<<(MidiMessage) -- Print MIDI messages as text. 0x80 and above
// are printed as hex, below as dec (will look strange for meta messages
// and system exclusives which could be dealt with later).
//

std::ostream& operator<<(std::ostream& out, MidiMessage& message) {
for (int i=0; i<(int)message.size(); i++) {
if (message[i] >= 0x80) {
out << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)message[i];
out << std::dec << std::setw(0) << std::setfill(' ');
} else {
out << (int)message[i];
}
if (i<(int)message.size() - 1) {
out << ' ';
}
}
return out;
}


} // end namespace smf


Expand Down

0 comments on commit 22c48d8

Please sign in to comment.