Fixes issues on Windows

This commit is contained in:
pianobooster 2020-05-14 12:36:54 +01:00
parent a7c497f98e
commit 8bc1f43f73
21 changed files with 170 additions and 101 deletions

View File

@ -1,6 +1,10 @@
# Cmake File for Piano Booster
option(USE_FTGL "build with ftgl" ON)
if(WIN32)
option(USE_FTGL "build with ftgl" OFF)
else()
option(USE_FTGL "build with ftgl" ON)
endif()
option(USE_JACK "build with Jack (Only required for BSD Unix)" OFF)
option(USE_SYSTEM_FONT "build with system font" OFF)
if(${CMAKE_SYSTEM} MATCHES "Linux")
@ -55,13 +59,16 @@ if(NOT WIN32)
endif()
if(USE_FTGL)
pkg_check_modules(FTGL ftgl)
if(NOT FTGL_FOUND)
MESSAGE(FATAL_ERROR "FTGL was not found")
endif(NOT FTGL_FOUND)
SET(FTGL_INCLUDE_DIR ${FTGL_INCLUDE_DIRS})
SET(FTGL_LIBRARY ${FTGL_LIBRARIES})
if(NOT WIN32)
pkg_check_modules(FTGL ftgl)
if(NOT FTGL_FOUND)
MESSAGE(FATAL_ERROR "FTGL was not found")
endif(NOT FTGL_FOUND)
SET(FTGL_INCLUDE_DIR ${FTGL_INCLUDE_DIRS})
SET(FTGL_LIBRARY ${FTGL_LIBRARIES})
else()
FIND_PACKAGE( ftgl REQUIRED )
endif()
else(USE_FTGL)
add_compile_options("-DNO_USE_FTGL")
endif(USE_FTGL)
@ -95,23 +102,18 @@ if(${CMAKE_SYSTEM} MATCHES "Darwin")
endif(${CMAKE_SYSTEM} MATCHES "Darwin")
if(WITH_INTERNAL_FLUIDSYNTH)
ADD_DEFINITIONS(-DWITH_INTERNAL_FLUIDSYNTH)
MESSAGE("Building using fluidsynth")
SET( PB_BASE_SRCS MidiDeviceFluidSynth.cpp )
if(DEFINED ENV{FLUIDSYNTH_INPLACE_DIR})
SET (FLUIDSYNTH_INPLACE_DIR = $ENV{FLUIDSYNTH_INPLACE_DIR})
INCLUDE_DIRECTORIES(${FLUIDSYNTH_INPLACE_DIR}/include/)
if(WIN32)
LINK_LIBRARIES( $ENV{FLUIDSYNTH_INPLACE_DIR}/lib/libfluidsynth.dll.a)
endif(WIN32)
else()
if(NOT WIN32)
pkg_check_modules(FLUIDSYNTH fluidsynth)
if(NOT FLUIDSYNTH_FOUND)
MESSAGE(FATAL_ERROR "FLUIDSYNTH was not found")
MESSAGE(FATAL_ERROR "FLUIDSYNTH was not found")
endif(NOT FLUIDSYNTH_FOUND)
LINK_LIBRARIES(fluidsynth)
else()
FIND_PACKAGE( fluidsynth REQUIRED )
endif()
ADD_DEFINITIONS(-DWITH_INTERNAL_FLUIDSYNTH)
MESSAGE("Building with internal fluidsynth")
SET( PB_BASE_SRCS MidiDeviceFluidSynth.cpp )
endif(WITH_INTERNAL_FLUIDSYNTH)
# we need this to be able to include headers produced by uic in our code
@ -123,7 +125,6 @@ SET(PB_BASE_SRCS MidiFile.cpp MidiTrack.cpp Song.cpp Conductor.cpp Util.cpp
SET(PB_BASE_HDR MidiFile.h MidiTrack.h Song.h Conductor.h Rating.h Util.h
Chord.h Tempo.h MidiDevice.h)
if(USE_JACK)
# Check for Jack
find_library(JACK_LIB jack)
@ -254,7 +255,7 @@ if(UNIX)
endif(UNIX)
if(WIN32)
ADD_EXECUTABLE( pianobooster WIN32 ${PIANOBOOSTER_SRCS}
ADD_EXECUTABLE( pianobooster ${PIANOBOOSTER_SRCS}
${PIANOBOOSTER_MOC_SRCS} ${PIANOBOOSTER_RC_SRCS}
${PIANOBOOSTER_UI_HDRS} ${PIANOBOOSTER_RCS} )
SET_TARGET_PROPERTIES(pianobooster PROPERTIES LINK_FLAGS "-mwindows")
@ -306,7 +307,8 @@ if(USE_FONT)
endif(USE_FONT)
if(NOT USE_SYSTEM_FONT)
INSTALL ( FILES fonts/DejaVuSans.ttf DESTINATION ${DATA_DIR}/fonts)
configure_file(fonts/DejaVuSans.ttf ${CMAKE_CURRENT_BINARY_DIR}/fonts/DejaVuSans.ttf COPYONLY)
INSTALL ( FILES fonts/DejaVuSans.ttf DESTINATION ${DATA_DIR}/fonts/)
endif(NOT USE_SYSTEM_FONT)
if(NOT NO_LANGS)

View File

@ -30,7 +30,6 @@
float Cfg::m_staveEndX;
int Cfg::logLevel = 1;
bool Cfg::quickStart = false;
int Cfg::m_appX;
int Cfg::m_appY;
int Cfg::m_appWidth;

View File

@ -130,7 +130,6 @@ public:
static int defaultRightPatch() {return 1;} // Starts at 1
static int logLevel;
static bool quickStart;
static bool experimentalTempo;
static bool experimentalNoteLength;
static int experimentalSwapInterval;

View File

@ -388,8 +388,25 @@ void CConductor::testWrongNoteSound(bool enable)
updatePianoSounds();
}
void CConductor::reconnectMidi()
{
if (!validMidiOutput()) {
QString midiInputName = m_settings->value("Midi/Input").toString();
if (midiInputName.startsWith(tr("None"))) {
CChord::setPianoRange(PC_KEY_LOWEST_NOTE, PC_KEY_HIGHEST_NOTE);
} else {
CChord::setPianoRange(m_settings->value("Keyboard/LowestNote", 0).toInt(),
m_settings->value("Keyboard/HighestNote", 127).toInt());
}
openMidiPort(CMidiDevice::MIDI_INPUT, midiInputName);
openMidiPort(CMidiDevice::MIDI_OUTPUT,m_settings->value("Midi/Output").toString());
}
m_settings->updateWarningMessages();
}
void CConductor::playMusic(bool start)
{
reconnectMidi();
m_playing = start;
allSoundOff();
if (start)

View File

@ -100,6 +100,7 @@ public:
void realTimeEngine(int mSecTicks);
void playMusic(bool start);
bool playingMusic() {return m_playing;}
void reconnectMidi();
float getSpeed() {return m_tempo.getSpeed();}
void setSpeed(float speed)

View File

@ -2,7 +2,7 @@
/*!
@file Draw.cpp
@brief xxxxx.
@author L. J. Barman
@ -61,7 +61,7 @@ CDraw::CDraw(CSettings* settings)
for (int i=0;i<listPathFonts.size();i++){
QFile file(listPathFonts.at(i));
if (file.exists()){
font = new FTGLPixmapFont(listPathFonts.at(i).toStdString().c_str());
font = new FTBitmapFont(listPathFonts.at(i).toStdString().c_str());
break;
}
}

View File

@ -125,7 +125,7 @@ private:
CScrollProperties m_scrollPropertiesHorizontal;
CScrollProperties m_scrollPropertiesVertical;
#ifndef NO_USE_FTGL
FTGLPixmapFont *font;
FTFont *font;
#endif
};

View File

@ -42,6 +42,8 @@
#define REDRAW_COUNT ((m_cfg_openGlOptimise >= 2) ? 1 : 2) // there are two gl buffers but redrawing once is best (set 2 with buggy gl drivers)
#define TEXT_LEFT_MARGIN 30
CGLView::CGLView(QtWindow* parent, CSettings* settings)
: QGLWidget(parent)
{
@ -133,9 +135,6 @@ void CGLView::paintGL()
void CGLView::drawTimeSignature()
{
if (Cfg::quickStart)
return;
if (m_forcefullRedraw == 0)
return;
@ -181,7 +180,7 @@ void CGLView::drawAccurracyBar()
CColor color;
float y = Cfg::getAppHeight() - 14;
const float x = 120;
const float x = accuracyBarStart;
const int width = 360;
const int lineWidth = 8/2;
@ -212,9 +211,6 @@ void CGLView::drawDisplayText()
return; // don't run this func the first time it is called
}
if (Cfg::quickStart)
return;
if (m_forcefullRedraw == 0)
return;
@ -223,21 +219,28 @@ void CGLView::drawDisplayText()
if (!m_settings->getWarningMessage().isEmpty())
{
glColor3f(1.0,0.2,0.0);
renderText(30, y-4, 0, m_settings->getWarningMessage(), m_timeRatingFont);
renderText(TEXT_LEFT_MARGIN, y-4, 0, m_settings->getWarningMessage(), m_timeRatingFont);
return;
}
glColor3f(1.0,1.0,1.0);
if (m_song->getPlayMode() != PB_PLAY_MODE_listen)
renderText(30, y-4,0 ,tr("Accuracy:"), m_timeRatingFont);
if (m_song->getPlayMode() != PB_PLAY_MODE_listen) {
if (accuracyBarStart == 0) {
QFontMetrics fm(m_timeRatingFont);
accuracyText = tr("Accuracy:");
accuracyBarStart=fm.horizontalAdvance(accuracyText + " ") + TEXT_LEFT_MARGIN;
}
renderText(TEXT_LEFT_MARGIN, y-4,0 ,accuracyText, m_timeRatingFont);
}
if (m_titleHeight < 45 )
return;
y = Cfg::getAppHeight() - m_titleHeight;
renderText(30, y+6, 0,tr("Song:") + " " + m_song->getSongTitle(), m_timeRatingFont);
renderText(TEXT_LEFT_MARGIN, y+6, 0,tr("Song:") + " " + m_song->getSongTitle(), m_timeRatingFont);
/*
char buffer[100];
sprintf(buffer, "Notes %d wrong %d Late %d Score %4.1f%%",
@ -249,12 +252,12 @@ void CGLView::drawDisplayText()
void CGLView::drawBarNumber()
{
if (m_forceBarRedraw == 0 || Cfg::quickStart)
if (m_forceBarRedraw == 0)
return;
m_forceBarRedraw--;
float y = Cfg::getAppHeight() - m_titleHeight - 34;
float x = 30;
float x = TEXT_LEFT_MARGIN;
//CDraw::drColor (Cfg::backgroundColor());
//CDraw::drColor (Cfg::noteColorDim());
@ -288,6 +291,10 @@ void CGLView::resizeGL(int width, int height)
m_titleHeight = 60;
}
maxSoreHeight = heightAboveStave + heightBelowStave + staveGap + m_titleHeight;
if (height > maxSoreHeight) {
int scoreExtraTopGap = (height - maxSoreHeight);
maxSoreHeight += qMin(200, scoreExtraTopGap);
}
int sizeX = qMin(width, maxSoreWidth);
int sizeY = qMin(height, maxSoreHeight);
int x = (width - sizeX)/2;
@ -339,19 +346,15 @@ void CGLView::initializeGL()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//enableAntialiasedLines();
m_timeSigFont = QFont("Arial", 22 );
m_timeRatingFont = QFont("Arial", 12 );
// This is a work around for Windows different display scaling option
int widgetPointSize = m_qtWindow->font().pointSize();
m_timeSigFont = QFont("Arial", widgetPointSize*2 );
m_timeRatingFont = QFont("Arial", static_cast<int>(widgetPointSize * 1.2) );
Cfg::setStaveEndX(400); //This value get changed by the resizeGL func
m_song->setActiveHand(PB_PART_both);
if (!Cfg::quickStart)
{
renderText(10,10,QString("~"), m_timeRatingFont); //fixme this is a work around for a QT bug.
renderText(10,10,QString("~"), m_timeSigFont); //this is a work around for a QT bug.
}
setFocusPolicy(Qt::ClickFocus);
m_qtWindow->init();

View File

@ -71,6 +71,9 @@ private:
void drawBarNumber();
void updateMidiTask();
QString accuracyText;
int accuracyBarStart = 0;
QColor m_backgroundColor;
QtWindow* m_qtWindow; // The parent Window
CSettings* m_settings;

View File

@ -139,6 +139,14 @@ CMidiEvent CMidiDevice::readMidiInput()
return m_selectedMidiInputDevice->readMidiInput();
}
bool CMidiDevice::validMidiOutput()
{
if (m_validOutput) {
return m_selectedMidiOutputDevice->validMidiConnection();
}
return m_validOutput;
}
int CMidiDevice::midiSettingsSetStr(QString name, QString str)
{
if (m_selectedMidiOutputDevice)

View File

@ -49,7 +49,8 @@ public:
void playMidiEvent(const CMidiEvent & event);
int checkMidiInput();
CMidiEvent readMidiInput();
bool validMidiOutput() { return m_validOutput; }
bool validMidiOutput();
virtual bool validMidiConnection() {return validMidiOutput();}
QStringList getMidiPortList(midiType_t type);
bool openMidiPort(midiType_t type, QString portName);

View File

@ -50,6 +50,8 @@ public:
virtual QStringList getMidiPortList(midiType_t type) = 0;
virtual bool openMidiPort(midiType_t type, QString portName) = 0;
virtual bool validMidiConnection() = 0;
virtual void closeMidiPort(midiType_t type, int index) = 0;
// based on the fluid synth settings

View File

@ -34,6 +34,7 @@ CMidiDeviceFluidSynth::CMidiDeviceFluidSynth()
m_fluidSettings = nullptr;
m_audioDriver = nullptr;
m_rawDataIndex = 0;
m_validConnection = false;
}
CMidiDeviceFluidSynth::~CMidiDeviceFluidSynth()
@ -71,13 +72,13 @@ bool CMidiDeviceFluidSynth::openMidiPort(midiType_t type, QString portName)
if (type == MIDI_INPUT)
return false;
if (!portName.endsWith(FLUID_NAME)) return false;
if (!portName.endsWith(FLUID_NAME)) {return false;}
if (getMidiPortList(type).size()==0) return false;
if (getMidiPortList(type).size()==0) {return false;}
// Load a SoundFont
QStringList fontList = qsettings->value("FluidSynth/SoundFont").toStringList();
if (fontList.size() == 0) return false;
if (fontList.size() == 0) {return false;}
// Create the settings.
m_fluidSettings = new_fluid_settings();
@ -110,12 +111,15 @@ bool CMidiDeviceFluidSynth::openMidiPort(midiType_t type, QString portName)
{
fluid_synth_program_change(m_synth, channel, GM_PIANO_PATCH);
}
fluid_synth_set_gain(m_synth, qsettings->value("FluidSynth/masterGainSpin", 40).toFloat()/100.0f );
fluid_synth_set_gain(m_synth, qsettings->value("FluidSynth/masterGainSpin", 80).toFloat()/100.0f );
m_validConnection = true;
return true;
}
void CMidiDeviceFluidSynth::closeMidiPort(midiType_t type, int index)
{
m_validConnection = false;
if (type != MIDI_OUTPUT)
return;

View File

@ -45,6 +45,8 @@ class CMidiDeviceFluidSynth : public CMidiDeviceBase
virtual bool openMidiPort(midiType_t type, QString portName);
virtual void closeMidiPort(midiType_t type, int index);
virtual bool validMidiConnection() {return m_validConnection;}
// based on the fluid synth settings
virtual int midiSettingsSetStr(QString name, QString str);
virtual int midiSettingsSetNum(QString name, double val);
@ -71,6 +73,7 @@ private:
fluid_synth_t* m_synth;
fluid_audio_driver_t* m_audioDriver;
int m_soundFontId;
bool m_validConnection;
};
#endif //__MIDI_DEVICE_FLUIDSYNTH_H__

View File

@ -30,35 +30,51 @@
CMidiDeviceRt::CMidiDeviceRt()
{
try {
m_midiout = new RtMidiOut();
}
catch(RtMidiError &error){
error.printMessage();
exit(1);
}
try {
m_midiin = new RtMidiIn();
}
catch(RtMidiError &error){
error.printMessage();
exit(1);
}
m_validConnection = false;
m_midiout = nullptr;
m_midiin = nullptr;
m_midiPorts[0] = -1;
m_midiPorts[1] = -1;
m_rawDataIndex = 0;
init();
}
CMidiDeviceRt::~CMidiDeviceRt()
{
delete m_midiout;
delete m_midiin;
if (m_midiout!=nullptr) { delete m_midiout; }
if (m_midiin!=nullptr) {delete m_midiin; }
}
void CMidiDeviceRt::init()
{
if (m_midiin == nullptr || m_midiout == nullptr) {
m_midiPorts[0] = -1;
m_midiPorts[1] = -1;
m_rawDataIndex = 0;
if (m_midiout!=nullptr) {
delete m_midiout;
m_midiout = nullptr;
}
try {
m_midiout = new RtMidiOut();
}
catch(RtMidiError &error){
error.printMessage();
return;
}
if (m_midiin!=nullptr) {
delete m_midiin;
m_midiin = nullptr;
}
try {
m_midiin = new RtMidiIn();
}
catch(RtMidiError &error){
error.printMessage();
return;
}
}
}
QString CMidiDeviceRt::addIndexToString(QString name, int index)
@ -72,10 +88,15 @@ QString CMidiDeviceRt::addIndexToString(QString name, int index)
}
QStringList CMidiDeviceRt::getMidiPortList(midiType_t type)
{
init();
QStringList portNameList;
if (m_midiin == nullptr || m_midiout == nullptr) {
return portNameList;
}
unsigned int nPorts;
QString name;
RtMidi* midiDevice;
QStringList portNameList;
if (type == MIDI_INPUT)
midiDevice = m_midiin;
@ -100,6 +121,11 @@ QStringList CMidiDeviceRt::getMidiPortList(midiType_t type)
bool CMidiDeviceRt::openMidiPort(midiType_t type, QString portName)
{
init();
if (m_midiin == nullptr || m_midiout == nullptr) {
return false;
}
unsigned int nPorts;
QString name;
RtMidi* midiDevice;
@ -134,6 +160,7 @@ bool CMidiDeviceRt::openMidiPort(midiType_t type, QString portName)
m_rawDataIndex = 0;
midiDevice->openPort( i );
m_validConnection = true;
return true;
}
}
@ -142,6 +169,7 @@ bool CMidiDeviceRt::openMidiPort(midiType_t type, QString portName)
void CMidiDeviceRt::closeMidiPort(midiType_t type, int index)
{
m_validConnection = false;
if (type == MIDI_INPUT)
m_midiin->closePort();
else
@ -215,8 +243,13 @@ void CMidiDeviceRt::playMidiEvent(const CMidiEvent & event)
return;
}
m_midiout->sendMessage( &message );
try {
m_midiout->sendMessage( &message );
}
catch(RtMidiError &error){
error.printMessage();
m_validConnection = false;
}
//event.printDetails(); // useful for debugging
}
@ -226,7 +259,16 @@ int CMidiDeviceRt::checkMidiInput()
{
if (m_midiPorts[0] < 0)
return 0;
m_stamp = m_midiin->getMessage( &m_inputMessage );
try {
m_stamp = m_midiin->getMessage( &m_inputMessage );
}
catch(RtMidiError &error){
error.printMessage();
m_validConnection = false;
return 0;
}
return m_inputMessage.size();
}

View File

@ -2,11 +2,9 @@
/*!
@file MidiDeviceRt.h
@brief xxxxxx.
@author L. J. Barman
Copyright (c) 2008-2013, L. J. Barman, all rights reserved
Copyright (c) 2008-2020, L. J. Barman, all rights reserved
This file is part of the PianoBooster application
@ -29,12 +27,9 @@
#ifndef __MIDI_DEVICE_RT_H__
#define __MIDI_DEVICE_RT_H__
#include "MidiDeviceBase.h"
#include "rtmidi/RtMidi.h"
class CMidiDeviceRt : public CMidiDeviceBase
{
virtual void init();
@ -48,6 +43,8 @@ class CMidiDeviceRt : public CMidiDeviceBase
virtual bool openMidiPort(midiType_t type, QString portName);
virtual void closeMidiPort(midiType_t type, int index);
virtual bool validMidiConnection() {return m_validConnection;}
// based on the fluid synth settings
virtual int midiSettingsSetStr(QString name, QString str);
virtual int midiSettingsSetNum(QString name, double val);
@ -76,6 +73,8 @@ private:
// kotechnology added function to create indexed string. Format: "1 - Example"
QString addIndexToString(QString name, int index);
bool m_validConnection;
};
#endif //__MIDI_DEVICE_RT_H__

View File

@ -284,7 +284,7 @@ void CMidiTrack::readMetaEvent(byte_t type)
case METATEMPO: /* Set Tempo */
{
byte b1,b2, b3;
byte_t b1,b2, b3;
int tempo;
b1 = readVarLen();

View File

@ -117,21 +117,13 @@ QtWindow::QtWindow()
m_song->setPianoSoundPatches(m_settings->value("Keyboard/RightSound", Cfg::defaultRightPatch()).toInt() - 1,
m_settings->value("Keyboard/WrongSound", Cfg::defaultWrongPatch()).toInt() - 1, true);
QString midiInputName = m_settings->value("Midi/Input").toString();
if (midiInputName.startsWith(tr("None")))
CChord::setPianoRange(PC_KEY_LOWEST_NOTE, PC_KEY_HIGHEST_NOTE);
else
CChord::setPianoRange(m_settings->value("Keyboard/LowestNote", 0).toInt(),
m_settings->value("Keyboard/HighestNote", 127).toInt());
m_song->setLatencyFix(m_settings->value("Midi/Latency", 0).toInt());
m_song->cfg_timingMarkersFlag = m_settings->value("Score/TimingMarkers", m_song->cfg_timingMarkersFlag ).toBool();
m_song->cfg_stopPointMode = static_cast<stopPointMode_t> (m_settings->value("Score/StopPointMode", m_song->cfg_stopPointMode ).toInt());
m_song->cfg_rhythmTapping = static_cast<rhythmTapping_t> (m_settings->value("Score/RtyhemTappingMode", m_song->cfg_rhythmTapping ).toInt());
m_song->openMidiPort(CMidiDevice::MIDI_INPUT, midiInputName);
m_song->openMidiPort(CMidiDevice::MIDI_OUTPUT,m_settings->value("Midi/Output").toString());
m_song->reconnectMidi();
readSettings();
@ -140,7 +132,6 @@ QtWindow::QtWindow()
if (!songName.isEmpty())
m_settings->openSongFile( songName );
});
}
void QtWindow::init()
@ -167,10 +158,7 @@ void QtWindow::displayUsage()
{
fprintf(stdout, "Usage: pianobooster [flags] [midifile]\n");
fprintf(stdout, " -d, --debug Increase the debug level.\n");
fprintf(stdout, " -q, --quick-start Quick start.\n");
fprintf(stdout, " --Xnote-length Displays the note length (experimental)\n");
fprintf(stdout, " --Xtick-rate=RATE Adjust the tick rate in mSec (experimental).\n");
fprintf(stdout, " default 4 (12 windows).\n");
fprintf(stdout, " -h, --help Displays this help message.\n");
fprintf(stdout, " -v, --version Displays version number and then exits.\n");
fprintf(stdout, " -l --log Write debug info to the \"pb.log\" log file.\n");
@ -267,8 +255,6 @@ void QtWindow::decodeCommandLine()
{
if (arg.startsWith("-d") || arg.startsWith("--debug"))
Cfg::logLevel++;
else if (arg.startsWith("-q") || arg.startsWith("--quick-start"))
Cfg::quickStart = true;
else if (arg.startsWith("--Xnote-length"))
Cfg::experimentalNoteLength = true;
else if (arg.startsWith("--Xtick-rate")) {
@ -279,7 +265,6 @@ void QtWindow::decodeCommandLine()
Cfg::useLogFile = true;
else if (arg.startsWith("--midi-input-dump"))
Cfg::midiInputDump = true;
else if (arg.startsWith("-X1"))
Cfg::experimentalTempo = true;
else if (arg.startsWith("-Xswap"))

View File

@ -92,6 +92,7 @@ private slots:
preferencesDialog.exec();
refreshTranslate();
m_score->refreshScroll();
}
void showSongDetailsDialog()

View File

@ -172,7 +172,7 @@ private:
CStavePos m_stavePos;
musicalSymbol_t m_symbolType;
byte m_midiNote;
byte_t m_midiNote;
accidentalModifer_t m_accidentalModifer; // Used to suppress the second sharp in the same bar
int m_midiDuration;
whichPart_t m_hand;

View File

@ -46,7 +46,7 @@ using namespace std;
#define MAX_MIDI_NOTES 128
#define MAX_MIDI_TRACKS 32 // This will allow us to map midi track on to midi channels
typedef unsigned char byte;
typedef unsigned char byte_t;
#define arraySize(a) (sizeof(a)/sizeof(a[0])) /* Returns (at compile time) the number of elements in an array */