Skip to content

Commit

Permalink
Merge pull request #3654 from rettinghaus/update-midi
Browse files Browse the repository at this point in the history
Update Midifile library
  • Loading branch information
lpugin authored May 1, 2024
2 parents ed140f4 + 8598527 commit 6aa2e96
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 98 deletions.
8 changes: 5 additions & 3 deletions include/midi/Binasc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
#ifndef _BINASC_H_INCLUDED
#define _BINASC_H_INCLUDED

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <stdlib.h> /* needed for MinGW */


namespace smf {

Expand Down 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
7 changes: 7 additions & 0 deletions include/midi/MidiEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
#define _MIDIEVENT_H_INCLUDED

#include "MidiMessage.h"

#include <ostream>
#include <vector>


namespace smf {

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

};


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


} // end of namespace smf

#endif /* _MIDIEVENT_H_INCLUDED */
Expand Down
2 changes: 2 additions & 0 deletions include/midi/MidiEventList.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
#define _MIDIEVENTLIST_H_INCLUDED

#include "MidiEvent.h"

#include <vector>


namespace smf {

class MidiEventList {
Expand Down
23 changes: 14 additions & 9 deletions include/midi/MidiFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,24 @@

#include "MidiEventList.h"

#include <vector>
#include <string>
#include <istream>
#include <fstream>
#include <istream>
#include <string>
#include <vector>

#define TIME_STATE_DELTA 0
#define TIME_STATE_ABSOLUTE 1

#define TRACK_STATE_SPLIT 0
#define TRACK_STATE_JOINED 1

namespace smf {

enum {
TRACK_STATE_SPLIT = 0, // Tracks are separated into separate vector postions.
TRACK_STATE_JOINED = 1 // Tracks are merged into a single vector position,
}; // like a Type-0 MIDI file, but reversible.

enum {
TIME_STATE_DELTA = 0, // MidiMessage::ticks are in delta time format (like MIDI file).
TIME_STATE_ABSOLUTE = 1 // MidiMessage::ticks are in absolute time format (0=start time).
};

class _TickTime {
public:
int tick;
Expand Down Expand Up @@ -217,7 +222,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
11 changes: 11 additions & 0 deletions include/midi/MidiMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
#ifndef _MIDIMESSAGE_H_INCLUDED
#define _MIDIMESSAGE_H_INCLUDED

#include <iostream>
#include <string>
#include <utility>
#include <vector>


namespace smf {

typedef unsigned char uchar;
Expand Down Expand Up @@ -122,6 +124,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 +207,9 @@ class MidiMessage : public std::vector<uchar> {
};


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


} // end of namespace smf


Expand Down
31 changes: 29 additions & 2 deletions src/midi/Binasc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,37 @@

#include "Binasc.h"

#include <cstdlib>
#include <sstream>
#include <stdlib.h>


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
16 changes: 15 additions & 1 deletion src/midi/MidiEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#include "MidiEvent.h"

#include <stdlib.h>
#include <cstdlib>


namespace smf {
Expand Down 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
43 changes: 21 additions & 22 deletions src/midi/MidiEventList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@
// Description: A class which stores a MidiEvents for a MidiFile track.
//


#include "MidiEventList.h"

#include <vector>
#include <algorithm>
#include <cstdlib>
#include <iterator>
#include <utility>
#include <vector>

#include <stdlib.h>

namespace smf {

Expand Down Expand Up @@ -54,8 +53,8 @@ MidiEventList::MidiEventList(const MidiEventList& other) {
//

MidiEventList::MidiEventList(MidiEventList&& other) {
list = std::move(other.list);
other.list.clear();
list = std::move(other.list);
other.list.clear();
}


Expand Down Expand Up @@ -124,12 +123,12 @@ const MidiEvent& MidiEventList::last(void) const {
//

MidiEvent& MidiEventList::getEvent(int index) {
return *list[index];
return *list[index];
}


const MidiEvent& MidiEventList::getEvent(int index) const {
return *list[index];
return *list[index];
}


Expand All @@ -141,10 +140,10 @@ const MidiEvent& MidiEventList::getEvent(int index) const {
//

void MidiEventList::clear(void) {
for (int i=0; i<(int)list.size(); i++) {
if (list[i] != NULL) {
delete list[i];
list[i] = NULL;
for (auto& item : list) {
if (item != NULL) {
delete item;
item = NULL;
}
}
list.resize(0);
Expand Down Expand Up @@ -245,10 +244,10 @@ int MidiEventList::push_back(MidiEvent& event) {

void MidiEventList::removeEmpties(void) {
int count = 0;
for (int i=0; i<(int)list.size(); i++) {
if (list[i]->empty()) {
delete list[i];
list[i] = NULL;
for (auto& item : list) {
if (item->empty()) {
delete item;
item = NULL;
count++;
}
}
Expand All @@ -257,9 +256,9 @@ void MidiEventList::removeEmpties(void) {
}
std::vector<MidiEvent*> newlist;
newlist.reserve(list.size() - count);
for (int i=0; i<(int)list.size(); i++) {
if (list[i]) {
newlist.push_back(list[i]);
for (auto& item : list) {
if (item) {
newlist.push_back(item);
}
}
list.swap(newlist);
Expand Down Expand Up @@ -292,8 +291,8 @@ int MidiEventList::linkNotePairs(void) {
// dimension 3: List of active note-ons or note-offs.
std::vector<std::vector<std::vector<MidiEvent*>>> noteons;
noteons.resize(16);
for (int i=0; i<(int)noteons.size(); i++) {
noteons[i].resize(128);
for (auto& noteon : noteons) {
noteon.resize(128);
}

// Controller linking: The following General MIDI controller numbers are
Expand Down Expand Up @@ -433,7 +432,7 @@ void MidiEventList::clearLinks(void) {

//////////////////////////////
//
// MidiEventList::clearSequence -- Remove any seqence serial numbers from
// MidiEventList::clearSequence -- Remove any sequence serial numbers from
// MidiEvents in the list. This will cause the default ordering by
// sortTracks() to be used, in which case the ordering of MidiEvents
// occurring at the same tick may switch their ordering.
Expand All @@ -454,7 +453,7 @@ void MidiEventList::clearSequence(void) {
// to preseve the order of MIDI messages in a track when they occur
// at the same tick time. Particularly for use with joinTracks()
// or sortTracks(). markSequence will be done automatically when
// a MIDI file is read, in case the ordering of events occuring at
// a MIDI file is read, in case the ordering of events occurring at
// the same time is important. Use clearSequence() to use the
// default sorting behavior of sortTracks() when events occur at the
// same time. Returns the next serial number that has not yet been
Expand Down
Loading

0 comments on commit 6aa2e96

Please sign in to comment.