1 /* 2 MIDI Sequencer C++ library 3 Copyright (C) 2006-2021, Pedro Lopez-Cabanillas <plcl@users.sf.net> 4 5 This library is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef DRUMSTICK_ALSAEVENT_H 20 #define DRUMSTICK_ALSAEVENT_H 21 22 extern "C" { 23 #include <alsa/asoundlib.h> 24 } 25 26 #include <QObject> 27 #include <QEvent> 28 #include "macros.h" 29 30 namespace drumstick { namespace ALSA { 31 32 /** 33 * @file alsaevent.h 34 * Classes managing ALSA Sequencer events. 35 * 36 * @addtogroup ALSAEvent ALSA Sequencer Events 37 * @{ 38 */ 39 40 /** 41 * 8-bit unsigned number to be used as a MIDI message parameter 42 */ 43 typedef quint8 MidiByte; 44 45 /** 46 * Constant SequencerEventType is the QEvent::type() of any SequencerEvent 47 * object to be used to check the argument in QObject::customEvent(). 48 */ 49 const QEvent::Type SequencerEventType = QEvent::Type(QEvent::User + 4154); // :-) 50 51 /** 52 * Base class for the event's hierarchy 53 * 54 * All event classes share this base class. It provides several common 55 * properties and methods. 56 */ 57 class DRUMSTICK_EXPORT SequencerEvent : public QEvent 58 { 59 public: 60 SequencerEvent(); 61 SequencerEvent(const SequencerEvent& other); 62 explicit SequencerEvent(const snd_seq_event_t* event); 63 64 SequencerEvent& operator=(const SequencerEvent& other); 65 void setSequencerType(const snd_seq_event_type_t eventType); 66 /** 67 * Gets the sequencer event type. 68 * @return The sequencer event type. 69 * @see setSequencerType() 70 */ getSequencerType()71 snd_seq_event_type_t getSequencerType() const { return m_event.type; } 72 void setDestination(const unsigned char client, const unsigned char port); 73 void setSource(const unsigned char port); 74 /** 75 * Gets the source client id. 76 * @return The source client id. 77 * @see setSource() 78 */ getSourceClient()79 unsigned char getSourceClient() const { return m_event.source.client; } 80 /** 81 * Gets the source port id. 82 * @return The source port id. 83 * @see setSource() 84 */ getSourcePort()85 unsigned char getSourcePort() const { return m_event.source.port; } 86 /** 87 * Gets the tick time of the event. 88 * @return The tick time. 89 * @see scheduleTick() 90 */ getTick()91 snd_seq_tick_time_t getTick() const { return m_event.time.tick; } 92 /** 93 * Gets the seconds of the event's real time. 94 * @return The seconds of the time. 95 * @see scheduleReal(), getRealTimeNanos() 96 */ getRealTimeSecs()97 unsigned int getRealTimeSecs() const { return m_event.time.time.tv_sec; } 98 /** 99 * Gets the nanoseconds of the event's real time. 100 * @return The nanoseconds of the time. 101 * @see scheduleReal(), getRealTimeSecs() 102 */ getRealTimeNanos()103 unsigned int getRealTimeNanos() const { return m_event.time.time.tv_nsec; } 104 void setSubscribers(); 105 void setBroadcast(); 106 void setDirect(); 107 void scheduleTick(const int queue, const int tick, const bool relative); 108 void scheduleReal(const int queue, const ulong secs, const ulong nanos, const bool relative); 109 void setPriority(const bool high); 110 /** 111 * Gets the tag of the event 112 * @return The event's tag 113 * @see setTag() 114 */ getTag()115 unsigned char getTag() const { return m_event.tag; } 116 void setTag(const unsigned char aTag); 117 unsigned int getRaw32(const unsigned int n) const; 118 void setRaw32(const unsigned int n, const unsigned int value); 119 unsigned char getRaw8(const unsigned int n) const; 120 void setRaw8(const unsigned int n, const unsigned char value); 121 /** 122 * Gets the handle of the event 123 * @return The event's handle 124 */ getHandle()125 snd_seq_event_t* getHandle() { return &m_event; } 126 int getEncodedLength(); 127 128 static bool isSubscription(const SequencerEvent* event); 129 static bool isPort(const SequencerEvent* event); 130 static bool isClient(const SequencerEvent* event); 131 static bool isConnectionChange(const SequencerEvent* event); 132 static bool isChannel(const SequencerEvent* event); 133 virtual SequencerEvent* clone() const; 134 135 protected: 136 Q_DECL_DEPRECATED void free(); 137 138 /** 139 * ALSA sequencer event record. 140 * @see https://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__event.html 141 */ 142 snd_seq_event_t m_event; 143 }; 144 145 /** 146 * Base class for the events having a Channel property 147 */ 148 class DRUMSTICK_EXPORT ChannelEvent : public SequencerEvent 149 { 150 public: 151 /** Default constructor */ ChannelEvent()152 ChannelEvent() : SequencerEvent() {} 153 /** 154 * Constructor from an ALSA event record 155 * @param event an ALSA event record 156 */ ChannelEvent(const snd_seq_event_t * event)157 explicit ChannelEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} 158 /** 159 * Sets the channel of the event 160 * @param c A channel, between 0 and 15. 161 * @see getChannel() 162 */ setChannel(const MidiByte c)163 void setChannel(const MidiByte c) { m_event.data.note.channel = (c & 0xf); } 164 /** 165 * Gets the event's channel 166 * @return The event's channel 167 * @see setChannel() 168 */ getChannel()169 int getChannel() const { return m_event.data.note.channel; } 170 171 virtual ChannelEvent* clone() const override; 172 }; 173 174 /** 175 * Base class for the events having Key and Velocity properties. 176 */ 177 class DRUMSTICK_EXPORT KeyEvent : public ChannelEvent 178 { 179 public: 180 /** Default constructor */ KeyEvent()181 KeyEvent() : ChannelEvent() {} 182 /** 183 * Constructor from an ALSA event record 184 * @param event an ALSA event record 185 */ KeyEvent(const snd_seq_event_t * event)186 explicit KeyEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} 187 /** 188 * Gets the MIDI note of this event. 189 * @return The event's MIDI note. 190 * @see setKey() 191 */ getKey()192 int getKey() const { return m_event.data.note.note; } 193 /** 194 * Sets the MIDI note of this event. 195 * @param b A MIDI note, between 0 and 127. 196 * @see getKey() 197 */ setKey(const MidiByte b)198 void setKey(const MidiByte b) { m_event.data.note.note = b; } 199 /** 200 * Gets the note velocity of this event. 201 * @return The event's note velocity. 202 * @see setVelocity() 203 */ getVelocity()204 int getVelocity() const { return m_event.data.note.velocity; } 205 /** 206 * Sets the note velocity of this event. 207 * @param b A velocity value, between 0 and 127. 208 * @see getVelocity() 209 */ setVelocity(const MidiByte b)210 void setVelocity(const MidiByte b) { m_event.data.note.velocity = b; } 211 212 virtual KeyEvent* clone() const override; 213 }; 214 215 /** 216 * Class representing a note event with duration 217 * 218 * Note events are converted into two MIDI events, a note-on and a note-off 219 * over the wire. 220 */ 221 class DRUMSTICK_EXPORT NoteEvent : public KeyEvent 222 { 223 public: 224 /** Default constructor */ NoteEvent()225 NoteEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_NOTE; } 226 /** 227 * Constructor from an ALSA event record 228 * @param event an ALSA event record 229 */ NoteEvent(const snd_seq_event_t * event)230 explicit NoteEvent(const snd_seq_event_t* event) : KeyEvent(event) {} 231 /** 232 * Constructor 233 * @param ch MIDI Channel 234 * @param key a MIDI note number 235 * @param vel a MIDI velocity value 236 * @param dur duration of the note in ticks 237 */ 238 NoteEvent(const int ch, const int key, const int vel, const int dur); 239 /** 240 * Gets the note's duration 241 * @return The duration of the event 242 * @see setDuration() 243 */ getDuration()244 ulong getDuration() const { return m_event.data.note.duration; } 245 /** 246 * Sets the note's duration 247 * @param d The duration of the event 248 * @see getDuration() 249 */ setDuration(const ulong d)250 void setDuration(const ulong d) { m_event.data.note.duration = d; } 251 252 virtual NoteEvent* clone() const override; 253 }; 254 255 /** 256 * Event representing a note-on MIDI event 257 */ 258 class DRUMSTICK_EXPORT NoteOnEvent : public KeyEvent 259 { 260 public: 261 /** Default constructor */ NoteOnEvent()262 NoteOnEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_NOTEON; } 263 /** 264 * Constructor from an ALSA event record 265 * @param event an ALSA event record 266 */ NoteOnEvent(const snd_seq_event_t * event)267 explicit NoteOnEvent(const snd_seq_event_t* event) : KeyEvent(event) {} 268 /** 269 * Constructor 270 * @param ch MIDI Channel 271 * @param key a MIDI note number 272 * @param vel a MIDI velocity value 273 */ 274 NoteOnEvent(const int ch, const int key, const int vel); 275 virtual NoteOnEvent* clone() const override; 276 }; 277 278 /** 279 * Event representing a note-off MIDI event 280 */ 281 class DRUMSTICK_EXPORT NoteOffEvent : public KeyEvent 282 { 283 public: 284 /** Default constructor */ NoteOffEvent()285 NoteOffEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_NOTEOFF; } 286 /** 287 * Constructor from an ALSA event record 288 * @param event an ALSA event record 289 */ NoteOffEvent(const snd_seq_event_t * event)290 explicit NoteOffEvent(const snd_seq_event_t* event) : KeyEvent(event) {} 291 /** 292 * Constructor 293 * @param ch MIDI Channel 294 * @param key a MIDI note number 295 * @param vel a MIDI velocity value 296 */ 297 NoteOffEvent(const int ch, const int key, const int vel); 298 virtual NoteOffEvent* clone() const override; 299 }; 300 301 /** 302 * Event representing a MIDI key pressure, or polyphonic after-touch event 303 */ 304 class DRUMSTICK_EXPORT KeyPressEvent : public KeyEvent 305 { 306 public: 307 /** Default constructor */ KeyPressEvent()308 KeyPressEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_KEYPRESS; } 309 /** 310 * Constructor from an ALSA event record 311 * @param event an ALSA event record 312 */ KeyPressEvent(const snd_seq_event_t * event)313 explicit KeyPressEvent(const snd_seq_event_t* event) : KeyEvent(event) {} 314 /** 315 * Constructor 316 * @param ch MIDI Channel 317 * @param key a MIDI note number 318 * @param vel a MIDI velocity value 319 */ 320 KeyPressEvent(const int ch, const int key, const int vel); 321 virtual KeyPressEvent* clone() const override; 322 }; 323 324 /** 325 * Event representing a MIDI control change event 326 */ 327 class DRUMSTICK_EXPORT ControllerEvent : public ChannelEvent 328 { 329 public: 330 /** Default constructor */ ControllerEvent()331 ControllerEvent() : ChannelEvent() {} 332 /** 333 * Constructor from an ALSA event record 334 * @param event an ALSA event record 335 */ ControllerEvent(const snd_seq_event_t * event)336 explicit ControllerEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} 337 /** 338 * Constructor 339 * @param ch MIDI Channel 340 * @param cc a MIDI controller 341 * @param val a value 342 */ 343 ControllerEvent(const int ch, const int cc, const int val); 344 /** 345 * Gets the controller event's parameter. 346 * @return The controller event's parameter. 347 * @see setParam() 348 */ getParam()349 uint getParam() const { return m_event.data.control.param; } 350 /** 351 * Sets the controller event's parameter. 352 * @param p The controller event's parameter. 353 * @see getParam() 354 */ setParam(const uint p)355 void setParam( const uint p ) { m_event.data.control.param = p; } 356 /** 357 * Gets the controller event's value. 358 * @return The controller event's value. 359 * @see setValue() 360 */ getValue()361 int getValue() const { return m_event.data.control.value; } 362 /** 363 * Sets the controller event's value. 364 * @param v The controller event's value. 365 * @see getValue() 366 */ setValue(const int v)367 void setValue( const int v ) { m_event.data.control.value = v; } 368 virtual ControllerEvent* clone() const override; 369 }; 370 371 /** 372 * Event representing a MIDI program change event 373 */ 374 class DRUMSTICK_EXPORT ProgramChangeEvent : public ChannelEvent 375 { 376 public: 377 /** Default constructor */ ProgramChangeEvent()378 ProgramChangeEvent() : ChannelEvent() { m_event.type = SND_SEQ_EVENT_PGMCHANGE; } 379 /** 380 * Constructor from an ALSA event record 381 * @param event an ALSA event record 382 */ ProgramChangeEvent(const snd_seq_event_t * event)383 explicit ProgramChangeEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} 384 /** 385 * Constructor 386 * @param ch MIDI Channel 387 * @param val a value 388 */ 389 ProgramChangeEvent(const int ch, const int val); 390 /** 391 * Gets the MIDI program number 392 * @return the MIDI program number 393 */ getValue()394 int getValue() const { return m_event.data.control.value; } 395 /** 396 * Sets the MIDI program number 397 * @param v the MIDI program number 398 */ setValue(const int v)399 void setValue( const int v ) { m_event.data.control.value = v; } 400 virtual ProgramChangeEvent* clone() const override; 401 }; 402 403 /** 404 * Event representing a MIDI bender, or pitch wheel event 405 */ 406 class DRUMSTICK_EXPORT PitchBendEvent : public ChannelEvent 407 { 408 public: 409 /** Default constructor */ PitchBendEvent()410 PitchBendEvent() : ChannelEvent() { m_event.type = SND_SEQ_EVENT_PITCHBEND; } 411 /** 412 * Constructor from an ALSA event record 413 * @param event an ALSA event record 414 */ PitchBendEvent(const snd_seq_event_t * event)415 explicit PitchBendEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} 416 /** 417 * Constructor 418 * @param ch MIDI Channel 419 * @param val a value 420 */ 421 PitchBendEvent(const int ch, const int val); 422 /** 423 * Gets the MIDI pitch bend value, zero centered from -8192 to 8191 424 * @return the MIDI pitch bend value 425 */ getValue()426 int getValue() const { return m_event.data.control.value; } 427 /** 428 * Sets the MIDI pitch bend value, zero centered from -8192 to 8191 429 * @param v the MIDI pitch bend value 430 */ setValue(const int v)431 void setValue( const int v ) { m_event.data.control.value = v; } 432 virtual PitchBendEvent* clone() const override; 433 }; 434 435 /** 436 * Event representing a MIDI channel pressure or after-touch event 437 */ 438 class DRUMSTICK_EXPORT ChanPressEvent : public ChannelEvent 439 { 440 public: 441 /** Default constructor */ ChanPressEvent()442 ChanPressEvent() : ChannelEvent() { m_event.type = SND_SEQ_EVENT_CHANPRESS; } 443 /** 444 * Constructor from an ALSA event record 445 * @param event an ALSA event record 446 */ ChanPressEvent(const snd_seq_event_t * event)447 explicit ChanPressEvent( const snd_seq_event_t* event ) : ChannelEvent(event) {} 448 /** 449 * Constructor 450 * @param ch MIDI Channel 451 * @param val a value 452 */ 453 ChanPressEvent( const int ch, const int val ); 454 /** 455 * Gets the channel aftertouch value 456 * @return the channel aftertouch value 457 */ getValue()458 int getValue() const { return m_event.data.control.value; } 459 /** 460 * Sets the channel aftertouch value 461 * @param v the channel aftertouch value 462 */ setValue(const int v)463 void setValue( const int v ) { m_event.data.control.value = v; } 464 virtual ChanPressEvent* clone() const override; 465 }; 466 467 /** 468 * Base class for variable length events 469 */ 470 class DRUMSTICK_EXPORT VariableEvent : public SequencerEvent 471 { 472 public: 473 VariableEvent(); 474 explicit VariableEvent(const snd_seq_event_t* event); 475 explicit VariableEvent(const QByteArray& data); 476 VariableEvent(const VariableEvent& other); 477 VariableEvent(const unsigned int datalen, char* dataptr); 478 VariableEvent& operator=(const VariableEvent& other); 479 /** 480 * Gets the data length 481 * @return the data length 482 */ getLength()483 unsigned int getLength() const { return m_event.data.ext.len; } 484 /** 485 * Gets the data pointer 486 * @return the data pointer 487 */ getData()488 const char* getData() const { return static_cast<const char*>(m_event.data.ext.ptr); } 489 virtual VariableEvent* clone() const override; 490 protected: 491 QByteArray m_data; 492 }; 493 494 /** 495 * Event representing a MIDI system exclusive event 496 */ 497 class DRUMSTICK_EXPORT SysExEvent : public VariableEvent 498 { 499 public: 500 SysExEvent(); 501 explicit SysExEvent(const snd_seq_event_t* event); 502 explicit SysExEvent(const QByteArray& data); 503 SysExEvent(const SysExEvent& other); 504 SysExEvent(const unsigned int datalen, char* dataptr); 505 virtual SysExEvent* clone() const override; 506 }; 507 508 /** 509 * Event representing a SMF text event 510 * 511 * This event type is not intended to be transmitted over the wire to an 512 * external device, but it is useful for sequencer programs or MIDI applications 513 */ 514 class DRUMSTICK_EXPORT TextEvent : public VariableEvent 515 { 516 public: 517 TextEvent(); 518 explicit TextEvent(const snd_seq_event_t* event); 519 explicit TextEvent(const QString& text, const int textType = 1); 520 TextEvent(const TextEvent& other); 521 TextEvent(const unsigned int datalen, char* dataptr); 522 QString getText() const; 523 int getTextType() const; 524 virtual TextEvent* clone() const override; 525 protected: 526 int m_textType; 527 }; 528 529 /** 530 * Generic event 531 */ 532 class DRUMSTICK_EXPORT SystemEvent : public SequencerEvent 533 { 534 public: 535 /** Default constructor */ SystemEvent()536 SystemEvent() : SequencerEvent() {} 537 /** 538 * Constructor from an ALSA event record 539 * @param event an ALSA event record 540 */ SystemEvent(const snd_seq_event_t * event)541 explicit SystemEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} 542 explicit SystemEvent(const snd_seq_event_type_t type); 543 virtual SystemEvent* clone() const override; 544 }; 545 546 /** 547 * ALSA Event representing a queue control command 548 * 549 * This event is used to schedule changes to the ALSA queues 550 */ 551 class DRUMSTICK_EXPORT QueueControlEvent : public SequencerEvent 552 { 553 public: 554 /** Default constructor */ QueueControlEvent()555 QueueControlEvent() : SequencerEvent() {} 556 /** 557 * Constructor from an ALSA event record 558 * @param event an ALSA event record 559 */ QueueControlEvent(const snd_seq_event_t * event)560 explicit QueueControlEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} 561 QueueControlEvent(const snd_seq_event_type_t type, const int queue, const int value); 562 /** 563 * Gets the queue number 564 * @return the queue number 565 */ getQueue()566 int getQueue() const { return m_event.data.queue.queue; } 567 /** 568 * Sets the queue number 569 * @param q the queue number 570 */ setQueue(const uchar q)571 void setQueue(const uchar q) { m_event.data.queue.queue = q; } 572 /** 573 * Gets the event's value 574 * @return the event's value 575 */ getValue()576 int getValue() const { return m_event.data.queue.param.value; } 577 /** 578 * Sets the event's value 579 * @param val the event's value 580 */ setValue(const int val)581 void setValue(const int val) { m_event.data.queue.param.value = val; } 582 /** 583 * Gets the queue position 584 * @return the queue position 585 */ getPosition()586 uint getPosition() const { return m_event.data.queue.param.position; } 587 /** 588 * Sets the queue position 589 * @param pos the queue position 590 */ setPosition(const uint pos)591 void setPosition(const uint pos) { m_event.data.queue.param.position = pos; } 592 /** 593 * Gets the musical time in ticks 594 * @return the musical time in ticks 595 */ getTickTime()596 snd_seq_tick_time_t getTickTime() const { return m_event.data.queue.param.time.tick; } 597 /** 598 * Sets the musical time in ticks 599 * @param t the musical time in ticks 600 */ setTickTime(const snd_seq_tick_time_t t)601 void setTickTime(const snd_seq_tick_time_t t) { m_event.data.queue.param.time.tick = t; } 602 /** 603 * Gets the skew base 604 * @return the skew base 605 */ getSkewBase()606 uint getSkewBase() const { return m_event.data.queue.param.skew.base; } 607 /** 608 * Sets the skew base, should be 65536 609 * @param base the skew base, should be 65536 610 */ setSkewBase(const uint base)611 void setSkewBase(const uint base) { m_event.data.queue.param.skew.base = base; } 612 /** 613 * Gets the skew value 614 * @return the skew value 615 */ getSkewValue()616 uint getSkewValue() const { return m_event.data.queue.param.skew.value; } 617 /** 618 * Sets the skew value 619 * @param val the skew value 620 */ setSkewValue(const uint val)621 void setSkewValue(const uint val) {m_event.data.queue.param.skew.value = val; } 622 virtual QueueControlEvent* clone() const override; 623 }; 624 625 /** 626 * Generic event having a value property 627 */ 628 class DRUMSTICK_EXPORT ValueEvent : public SequencerEvent 629 { 630 public: 631 /** Default constructor */ ValueEvent()632 ValueEvent() : SequencerEvent() {} 633 /** 634 * Constructor from an ALSA event record 635 * @param event an ALSA event record 636 */ ValueEvent(const snd_seq_event_t * event)637 explicit ValueEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} 638 ValueEvent(const snd_seq_event_type_t type, const int val); 639 /** 640 * Gets the event's value 641 * @return the event's value 642 */ getValue()643 int getValue() const { return m_event.data.control.value; } 644 /** 645 * Sets the event's value 646 * @param v the event's value 647 */ setValue(const int v)648 void setValue( const int v ) { m_event.data.control.value = v; } 649 virtual ValueEvent* clone() const override; 650 }; 651 652 /** 653 * ALSA Event representing a tempo change for an ALSA queue 654 */ 655 class DRUMSTICK_EXPORT TempoEvent : public QueueControlEvent 656 { 657 public: 658 /** Default constructor */ TempoEvent()659 TempoEvent() : QueueControlEvent() {} 660 /** 661 * Constructor from an ALSA event record 662 * @param event an ALSA event record 663 */ TempoEvent(const snd_seq_event_t * event)664 explicit TempoEvent(const snd_seq_event_t* event) : QueueControlEvent(event) {} 665 TempoEvent(const int queue, const int tempo); 666 virtual TempoEvent* clone() const override; 667 }; 668 669 /** 670 * ALSA Event representing a subscription between two ALSA clients and ports 671 */ 672 class DRUMSTICK_EXPORT SubscriptionEvent : public SequencerEvent 673 { 674 public: 675 /** Default constructor */ SubscriptionEvent()676 SubscriptionEvent() : SequencerEvent() {} 677 /** 678 * Constructor from an ALSA event record 679 * @param event an ALSA event record 680 */ SubscriptionEvent(const snd_seq_event_t * event)681 explicit SubscriptionEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} 682 /** 683 * Returns true if the event was a subscribed port 684 * @return whether the event was a subscribed port 685 */ subscribed()686 bool subscribed() const { return (m_event.type == SND_SEQ_EVENT_PORT_SUBSCRIBED); } 687 /** 688 * Returns true if the event was an unsubscribed port 689 * @return whether the event was an unsubscribed port 690 */ unsubscribed()691 bool unsubscribed() const { return (m_event.type == SND_SEQ_EVENT_PORT_UNSUBSCRIBED); } 692 /** 693 * Gets the sender client number 694 * @return the sender client number 695 */ getSenderClient()696 int getSenderClient() const { return m_event.data.connect.sender.client; } 697 /** 698 * Gets the sender port number 699 * @return the sender port number 700 */ getSenderPort()701 int getSenderPort() const { return m_event.data.connect.sender.port; } 702 /** 703 * Gets the destination client number 704 * @return the destination client number 705 */ getDestClient()706 int getDestClient() const { return m_event.data.connect.dest.client; } 707 /** 708 * Gets the destination port number 709 * @return the destination port number 710 */ getDestPort()711 int getDestPort() const { return m_event.data.connect.dest.port; } 712 virtual SubscriptionEvent* clone() const override; 713 }; 714 715 /** 716 * ALSA Event representing a change on some ALSA sequencer client on the system 717 */ 718 class DRUMSTICK_EXPORT ClientEvent : public SequencerEvent 719 { 720 public: 721 /** Default constructor */ ClientEvent()722 ClientEvent() : SequencerEvent() {} 723 /** 724 * Constructor from an ALSA event record 725 * @param event an ALSA event record 726 */ ClientEvent(const snd_seq_event_t * event)727 explicit ClientEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} 728 /** 729 * Gets the client number 730 * @return the client number 731 */ getClient()732 int getClient() const { return m_event.data.addr.client; } 733 virtual ClientEvent* clone() const override; 734 }; 735 736 /** 737 * ALSA Event representing a change on some ALSA sequencer port on the system 738 */ 739 class DRUMSTICK_EXPORT PortEvent : public ClientEvent 740 { 741 public: 742 /** Default constructor */ PortEvent()743 PortEvent() : ClientEvent() {} 744 /** 745 * Constructor from an ALSA event record 746 * @param event an ALSA event record 747 */ PortEvent(const snd_seq_event_t * event)748 explicit PortEvent(const snd_seq_event_t* event) : ClientEvent(event) {} 749 /** 750 * Gets the port number 751 * @return the port number 752 */ getPort()753 int getPort() const { return m_event.data.addr.port; } 754 virtual PortEvent* clone() const override; 755 }; 756 757 /** 758 * Auxiliary class to remove events from an ALSA queue 759 * @see MidiClient::removeEvents() 760 */ 761 class DRUMSTICK_EXPORT RemoveEvents 762 { 763 public: 764 friend class MidiClient; 765 766 public: 767 RemoveEvents(); 768 RemoveEvents(const RemoveEvents& other); 769 explicit RemoveEvents(snd_seq_remove_events_t* other); 770 virtual ~RemoveEvents(); 771 RemoveEvents* clone(); 772 RemoveEvents& operator=(const RemoveEvents& other); 773 int getSizeOfInfo() const; 774 775 int getChannel(); 776 unsigned int getCondition(); 777 const snd_seq_addr_t* getDest(); 778 int getEventType(); 779 int getQueue(); 780 int getTag(); 781 const snd_seq_timestamp_t* getTime(); 782 void setChannel(int chan); 783 void setCondition(unsigned int cond); 784 void setDest(const snd_seq_addr_t* dest); 785 void setEventType(int type); 786 void setQueue(int queue); 787 void setTag(int tag); 788 void setTime(const snd_seq_timestamp_t* time); 789 790 private: 791 snd_seq_remove_events_t* m_Info; 792 }; 793 794 /** 795 * Auxiliary class to translate between raw MIDI streams and ALSA events 796 */ 797 class DRUMSTICK_EXPORT MidiCodec : public QObject 798 { 799 Q_OBJECT 800 public: 801 explicit MidiCodec(int bufsize, QObject* parent = nullptr); 802 ~MidiCodec(); 803 804 void init(); 805 long decode(unsigned char *buf, 806 long count, 807 const snd_seq_event_t *ev); 808 long encode(const unsigned char *buf, 809 long count, 810 snd_seq_event_t *ev); 811 long encode(int c, 812 snd_seq_event_t *ev); 813 void enableRunningStatus(bool enable); 814 void resetEncoder(); 815 void resetDecoder(); 816 void resizeBuffer(int bufsize); 817 private: 818 snd_midi_event_t* m_Info; 819 }; 820 821 /** @} */ 822 823 }} /* namespace drumstick::ALSA */ 824 825 #endif //DRUMSTICK_ALSAEVENT_H 826