#pragma once
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
namespace pd {
class Patch {
public:
Patch() :
_handle(NULL), _dollarZero(0), _dollarZeroStr("0"),
_filename(""), _path("") {}
Patch(const std::string &filename, const std::string &path) :
_handle(NULL), _dollarZero(0), _dollarZeroStr("0"),
_filename(filename), _path(path) {}
Patch(void *handle, int dollarZero,
const std::string &filename,
const std::string &path) :
_handle(handle), _dollarZero(dollarZero),
_filename(filename), _path(path) {
std::stringstream itoa;
itoa << dollarZero;
_dollarZeroStr = itoa.str();
}
void* handle() const {return _handle;}
int dollarZero() const {return _dollarZero;}
std::string filename() const {return _filename;}
std::string path() const {return _path;}
std::string dollarZeroStr() const {return _dollarZeroStr;}
bool isValid() const {return _handle != NULL;}
void clear() {
_handle = NULL;
_dollarZero = 0;
_dollarZeroStr = "0";
}
Patch(const Patch &from) {
_handle = from._handle;
_dollarZero = from._dollarZero;
_dollarZeroStr = from._dollarZeroStr;
_filename = from._filename;
_path = from._path;
}
void operator=(const Patch &from) {
_handle = from._handle;
_dollarZero = from._dollarZero;
_dollarZeroStr = from._dollarZeroStr;
_filename = from._filename;
_path = from._path;
}
friend std::ostream& operator<<(std::ostream &os, const Patch &from) {
return os << "Patch: \"" << from.filename() << "\" $0: "
<< from.dollarZeroStr() << " valid: " << from.isValid();
}
private:
void *_handle; int _dollarZero; std::string _dollarZeroStr;
std::string _filename; std::string _path; };
struct Bang {
const std::string dest;
explicit Bang(const std::string &dest) : dest(dest) {}
};
struct Float {
const std::string dest; const float num;
Float(const std::string &dest, const float num) :
dest(dest), num(num) {}
};
struct Symbol {
const std::string dest; const std::string symbol;
Symbol(const std::string &dest, const std::string &symbol) :
dest(dest), symbol(symbol) {}
};
class List {
public:
List() {}
bool isFloat(const unsigned int index) const {
if(index < objects.size())
if(objects[index].type == List::FLOAT)
return true;
return false;
}
bool isSymbol(const unsigned int index) const {
if(index < objects.size())
if(objects[index].type == List::SYMBOL)
return true;
return false;
}
float getFloat(const unsigned int index) const {
if(!isFloat(index)) {
std::cerr << "Pd: List object " << index << " is not a float"
<< std::endl;
return 0;
}
return objects[index].value;
}
std::string getSymbol(const unsigned int index) const {
if(!isSymbol(index)) {
std::cerr << "Pd: List object " << index << " is not a symbol"
<< std::endl;
return "";
}
return objects[index].symbol;
}
void addFloat(const float num) {
MsgObject o;
o.type = List::FLOAT;
o.value = num;
objects.push_back(o);
typeString += 'f';
}
void addSymbol(const std::string &symbol) {
MsgObject o;
o.type = List::SYMBOL;
o.symbol = symbol;
objects.push_back(o);
typeString += 's';
}
List& operator<<(const bool var) {
addFloat((float) var);
return *this;
}
List& operator<<(const int var) {
addFloat((float) var);
return *this;
}
List& operator<<(const float var) {
addFloat((float) var);
return *this;
}
List& operator<<(const double var) {
addFloat((float) var);
return *this;
}
List& operator<<(const char var) {
std::string s;
s = var;
addSymbol(s);
return *this;
}
List& operator<<(const char *var) {
addSymbol((std::string) var);
return *this;
}
List& operator<<(const std::string &var) {
addSymbol((std::string) var);
return *this;
}
unsigned int len() const {return (unsigned int) objects.size();}
const std::string& types() const {return typeString;}
void clear() {
typeString = "";
objects.clear();
}
std::string toString() const {
std::string line;
std::stringstream itoa;
for(int i = 0; i < (int)objects.size(); ++i) {
if(isFloat(i)) {
itoa << getFloat(i);
line += itoa.str();
itoa.str("");
}
else {
line += getSymbol(i);
}
if(i < (int)objects.size()-1) {
line += " ";
}
}
return line;
}
friend std::ostream& operator<<(std::ostream &os, const List &from) {
return os << from.toString();
}
private:
std::string typeString;
enum MsgType {
FLOAT,
SYMBOL
};
struct MsgObject {
MsgType type;
float value;
std::string symbol;
};
std::vector<MsgObject> objects; };
struct StartMessage {
explicit StartMessage() {}
};
struct FinishList {
const std::string dest;
explicit FinishList(const std::string &dest) : dest(dest) {}
};
struct FinishMessage {
const std::string dest; const std::string msg;
FinishMessage(const std::string &dest, const std::string &msg) :
dest(dest), msg(msg) {}
};
struct NoteOn {
const int channel; const int pitch; const int velocity;
NoteOn(const int channel, const int pitch, const int velocity=64) :
channel(channel), pitch(pitch), velocity(velocity) {}
};
struct ControlChange {
const int channel; const int controller; const int value;
ControlChange(const int channel, const int controller, const int value) :
channel(channel), controller(controller), value(value) {}
};
struct ProgramChange {
const int channel; const int value;
ProgramChange(const int channel, const int value) :
channel(channel), value(value) {}
};
struct PitchBend {
const int channel; const int value;
PitchBend(const int channel, const int value) :
channel(channel), value(value) {}
};
struct Aftertouch {
const int channel; const int value;
Aftertouch(const int channel, const int value) :
channel(channel), value(value) {}
};
struct PolyAftertouch {
const int channel; const int pitch; const int value;
PolyAftertouch(const int channel, const int pitch, const int value) :
channel(channel), pitch(pitch), value(value) {}
};
struct MidiByte {
const int port; const unsigned char byte;
MidiByte(const int port, unsigned char byte) : port(port), byte(byte) {}
};
struct StartMidi {
const int port;
explicit StartMidi(const int port=0) : port(port) {}
};
struct StartSysex {
const int port;
explicit StartSysex(const int port=0) : port(port) {}
};
struct StartSysRealTime {
const int port;
explicit StartSysRealTime(const int port=0) : port(port) {}
};
struct Finish {
explicit Finish() {}
};
}