MidiMessage.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #ifndef MIDIMESSAGE_H
  2. #define MIDIMESSAGE_H
  3. #include "utils.h"
  4. #include <sstream>
  5. class MidiException
  6. {
  7. public:
  8. MidiException(int c=0, const std::string& m="Success") :
  9. code(c), message(m){}
  10. MidiException(const std::string& m, const char* t) :
  11. code(-1), message(m){}
  12. virtual ~MidiException(){}
  13. MidiException(const MidiException& m){
  14. code=m.code;
  15. message=m.message;
  16. }
  17. int code;
  18. std::string message;
  19. const int SUCCESS=0;
  20. const int OVERFLOW_EXCEPTION=1;
  21. const int PARSE_EXCEPTION=2;
  22. };
  23. class MidiOverflowException : public MidiException
  24. {
  25. public:
  26. MidiOverflowException(const std::string& m, const char* t) :
  27. MidiException(PARSE_EXCEPTION, "ParseError: "+m){}
  28. MidiOverflowException() : MidiException(OVERFLOW_EXCEPTION, "Overflow") {}
  29. virtual ~MidiOverflowException(){}
  30. };
  31. class MidiParseException : public MidiException
  32. {
  33. public:
  34. MidiParseException(const std::string& m, const char* t) :
  35. MidiException(PARSE_EXCEPTION, "ParseError: "+m){}
  36. MidiParseException(const std::string& m) : MidiException(PARSE_EXCEPTION, "ParseError: "+m) {}
  37. virtual ~MidiParseException(){}
  38. };
  39. class MidiMessage
  40. {
  41. public:
  42. // types de trames
  43. static const uint8_t NOTE_ON = 0x90;
  44. static const uint8_t NOTE_OFF = 0x80;
  45. static const uint8_t CONTROLLER_CHANGE = 0xB0;
  46. //constructors / destructors & operators
  47. MidiMessage(){}
  48. MidiMessage(int _type) : type(_type) {}
  49. MidiMessage(const MidiMessage& m ) : type(m.type) {}
  50. virtual ~MidiMessage(){}
  51. // functions
  52. virtual int get_bytes(uint8_t* buffer) const =0;
  53. virtual std::string to_string() const = 0;
  54. bool is_note_on() const { return (type&0xf0)==NOTE_ON; }
  55. bool is_note_off() const { return (type&0xf0)==NOTE_OFF; }
  56. virtual MidiMessage* copy() const
  57. {
  58. uint8_t tmp[3];
  59. int n;
  60. n=get_bytes(tmp);
  61. return MidiMessage::parse(tmp, n);
  62. }
  63. //data
  64. uint8_t type;
  65. static MidiMessage* parse(const MidiRawMessage&);
  66. static MidiMessage* parse(uint8_t * c, int len)
  67. {
  68. MidiRawMessage msg(c, c+len);
  69. return MidiMessage::parse(msg);
  70. }
  71. static MidiMessage* parse(Json::Value& v);
  72. };
  73. class MidiMessageList : public std::vector<MidiMessage*>
  74. {
  75. public:
  76. MidiMessageList() : std::vector<MidiMessage*>() {}
  77. MidiMessageList(const MidiMessageList& mml) : std::vector<MidiMessage*>(mml){
  78. }
  79. void clear()
  80. {
  81. //for(int i=0; i<size(); i++) delete at(i);
  82. std::vector<MidiMessage*>::clear();
  83. }
  84. const MidiMessageList& operator=(const MidiMessageList& m)
  85. {
  86. int s = m.size();
  87. clear();
  88. for(int i=0; i<s; i++)
  89. push_back(m[i]->copy());
  90. return m;
  91. }
  92. MidiMessageList(MidiMessage* mm) : std::vector<MidiMessage*>()
  93. {
  94. push_back(mm);
  95. }
  96. virtual ~MidiMessageList(){
  97. }
  98. void free_content(){
  99. int s = size();
  100. for(int i=0; i<s; i++)
  101. delete at(i);
  102. clear();
  103. }
  104. static MidiMessageList* parse(Json::Value& msg){
  105. MidiMessageList* m = new MidiMessageList();
  106. int l = msg.size();
  107. if(!msg.isArray() || !l){
  108. std::cerr << "Erreur array attendu dans pad::input(JSon::Value&)\n";
  109. return NULL;
  110. }
  111. if(msg[0].isString()){
  112. m->push_back(MidiMessage::parse(msg));
  113. }else{
  114. for(int i=0; i<l ;i++)
  115. {
  116. m->push_back(MidiMessage::parse(msg[i]));
  117. }
  118. }
  119. return m;
  120. }
  121. static MidiMessageList* parse(const std::string& msg){
  122. Json::Value v;
  123. std::istringstream iss(msg);
  124. iss >> v;
  125. return parse(v);
  126. }
  127. };
  128. class Note : public MidiMessage
  129. {
  130. public:
  131. Note() : MidiMessage() {}
  132. Note(int _type, int ch, int key, int vel) :
  133. MidiMessage(_type), channel(ch), key(key), velocity(vel) {}
  134. Note(const Note& n) : MidiMessage(n.type),
  135. channel(n.channel), key(n.key), velocity(n.velocity) {}
  136. virtual ~Note(){}
  137. uint8_t channel;
  138. uint8_t key;
  139. uint8_t velocity;
  140. virtual Note* copy() const
  141. {
  142. uint8_t tmp[3];
  143. int n;
  144. n=get_bytes(tmp);
  145. Note* m = dynamic_cast<Note*>(MidiMessage::parse(tmp, n));
  146. m->channel=channel;
  147. m->key=key;
  148. m->velocity=velocity;
  149. return m;
  150. }
  151. virtual int get_bytes(uint8_t* buffer) const {
  152. buffer[0]=type|((channel-1)%16);
  153. buffer[1]=(key%128);
  154. buffer[2]=(velocity%128);
  155. return 3;
  156. }
  157. };
  158. class NoteOn : public Note {
  159. public:
  160. NoteOn(int ch, int k, int vel) : Note(MidiMessage::NOTE_ON, ch, k, vel) {}
  161. virtual ~NoteOn() {}
  162. virtual std::string to_string() const{
  163. return "NoteOn("+str(channel)+", "+str(key)+", "+str(velocity)+")";
  164. }
  165. };
  166. class NoteOff : public Note {
  167. public:
  168. NoteOff(int ch, int k, int vel) : Note(MidiMessage::NOTE_OFF, ch, k, vel) {}
  169. virtual ~NoteOff() {}
  170. virtual std::string to_string() const{
  171. return "NoteOn("+str(channel)+", "+str(key)+", "+str(velocity)+")";
  172. }
  173. };
  174. class ControllerChange : public Note {
  175. public:
  176. ControllerChange(int ch, int k, int vel) : Note(MidiMessage::CONTROLLER_CHANGE, ch, k, vel) {}
  177. virtual ~ControllerChange() {}
  178. virtual std::string to_string() const{
  179. return "ControllerChange("+str(channel)+", "+str(key)+", "+str(velocity)+")";
  180. }
  181. };
  182. #endif // MIDIMESSAGE_H