drumstick 2.0.0
alsaevent.cpp
Go to the documentation of this file.
1/*
2 MIDI Sequencer C++ library
3 Copyright (C) 2006-2020, 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#include "errorcheck.h"
20#include <drumstick/alsaevent.h>
25
31
32namespace drumstick { namespace ALSA {
33
94
95
100{
101 snd_seq_ev_clear( &m_event );
102}
103
109{
110 snd_seq_ev_clear( &m_event );
111 m_event = *event;
112}
113
119{
120 snd_seq_ev_clear( &m_event );
121 m_event = other.m_event;
122}
123
131{
132 m_event = other.m_event;
133 return *this;
134}
135
141bool
143{
144 snd_seq_event_type_t te = event->getSequencerType();
145 return ( te == SND_SEQ_EVENT_PORT_SUBSCRIBED ||
146 te == SND_SEQ_EVENT_PORT_UNSUBSCRIBED );
147}
148
154bool
156{
157 snd_seq_event_type_t te = event->getSequencerType();
158 return ( te == SND_SEQ_EVENT_PORT_START ||
159 te == SND_SEQ_EVENT_PORT_EXIT ||
160 te == SND_SEQ_EVENT_PORT_CHANGE );
161}
162
168bool
170{
171 snd_seq_event_type_t te = event->getSequencerType();
172 return ( te == SND_SEQ_EVENT_CLIENT_START ||
173 te == SND_SEQ_EVENT_CLIENT_EXIT ||
174 te == SND_SEQ_EVENT_CLIENT_CHANGE );
175}
176
182bool
184{
185 snd_seq_event_type_t te = event->getSequencerType();
186 return ( te == SND_SEQ_EVENT_PORT_START ||
187 te == SND_SEQ_EVENT_PORT_EXIT ||
188 te == SND_SEQ_EVENT_PORT_CHANGE ||
189 te == SND_SEQ_EVENT_CLIENT_START ||
190 te == SND_SEQ_EVENT_CLIENT_EXIT ||
191 te == SND_SEQ_EVENT_CLIENT_CHANGE ||
192 te == SND_SEQ_EVENT_PORT_SUBSCRIBED ||
193 te == SND_SEQ_EVENT_PORT_UNSUBSCRIBED );
194}
195
202bool
204{
205 snd_seq_event_type_t te = event->getSequencerType();
206 return ( te == SND_SEQ_EVENT_NOTEOFF ||
207 te == SND_SEQ_EVENT_NOTEON ||
208 te == SND_SEQ_EVENT_NOTE ||
209 te == SND_SEQ_EVENT_KEYPRESS ||
210 te == SND_SEQ_EVENT_CONTROLLER ||
211 te == SND_SEQ_EVENT_CONTROL14 ||
212 te == SND_SEQ_EVENT_PGMCHANGE ||
213 te == SND_SEQ_EVENT_CHANPRESS ||
214 te == SND_SEQ_EVENT_PITCHBEND );
215}
216
221void SequencerEvent::setSequencerType(const snd_seq_event_type_t eventType)
222{
223 m_event.type = eventType;
224}
225
232void SequencerEvent::setDestination(const unsigned char client, const unsigned char port)
233{
234 snd_seq_ev_set_dest(&m_event, client, port);
235}
236
242void SequencerEvent::setSource(const unsigned char port)
243{
244 snd_seq_ev_set_source(&m_event, port);
245}
246
251{
252 snd_seq_ev_set_subs(&m_event);
253}
254
259{
260 snd_seq_ev_set_broadcast(&m_event);
261}
262
268{
269 snd_seq_ev_set_direct(&m_event);
270}
271
278void SequencerEvent::scheduleTick(int queue, int tick, bool relative)
279{
280 snd_seq_ev_schedule_tick(&m_event, queue, relative, tick);
281}
282
290void SequencerEvent::scheduleReal(int queue, ulong secs, ulong nanos, bool relative)
291{
292 snd_seq_real_time_t rtime;
293 rtime.tv_sec = secs;
294 rtime.tv_nsec = nanos;
295 snd_seq_ev_schedule_real(&m_event, queue, relative, &rtime);
296}
297
304void SequencerEvent::setPriority(const bool high)
305{
306 snd_seq_ev_set_priority(&m_event, high);
307}
308
314void SequencerEvent::setTag(const unsigned char aTag)
315{
316#if SND_LIB_VERSION > 0x010008
317 snd_seq_ev_set_tag(&m_event, aTag);
318#else
319 m_event.tag = aTag;
320#endif
321}
322
329unsigned int SequencerEvent::getRaw32(const unsigned int n) const
330{
331 if (n < 3) return m_event.data.raw32.d[n];
332 return 0;
333}
334
340void SequencerEvent::setRaw32(const unsigned int n, const unsigned int value)
341{
342 if (n < 3) m_event.data.raw32.d[n] = value;
343}
344
351unsigned char SequencerEvent::getRaw8(const unsigned int n) const
352{
353 if (n < 12) return m_event.data.raw8.d[n];
354 return 0;
355}
356
362void SequencerEvent::setRaw8(const unsigned int n, const unsigned char value)
363{
364 if (n < 12) m_event.data.raw8.d[n] = value;
365}
366
372{
373 snd_seq_free_event(&m_event);
374}
375
381{
382 return snd_seq_event_length(&m_event);
383}
384
390{
391 return new SequencerEvent(&m_event);
392}
393
399{
400 return new ChannelEvent(&m_event);
401}
402
408{
409 return new KeyEvent(&m_event);
410}
411
419NoteEvent::NoteEvent(int ch, int key, int vel, int dur) : KeyEvent()
420{
421 snd_seq_ev_set_note(&m_event, ch, key, vel, dur);
422}
423
429{
430 return new NoteEvent(&m_event);
431}
432
439NoteOnEvent::NoteOnEvent(int ch, int key, int vel) : KeyEvent()
440{
441 snd_seq_ev_set_noteon(&m_event, ch, key, vel);
442}
443
449{
450 return new NoteOnEvent(&m_event);
451}
452
459NoteOffEvent::NoteOffEvent(int ch, int key, int vel) : KeyEvent()
460{
461 snd_seq_ev_set_noteoff(&m_event, ch, key, vel);
462}
463
469{
470 return new NoteOffEvent(&m_event);
471}
472
479KeyPressEvent::KeyPressEvent(int ch, int key, int vel) : KeyEvent()
480{
481 snd_seq_ev_set_keypress(&m_event, ch, key, vel);
482}
483
489{
490 return new KeyPressEvent(&m_event);
491}
492
500{
501 snd_seq_ev_set_controller(&m_event, ch, cc, val);
502}
503
512
519{
520 snd_seq_ev_set_pgmchange(&m_event, ch, val);
521}
522
531
538{
539 snd_seq_ev_set_pitchbend(&m_event, ch, val);
540}
541
547{
548 return new PitchBendEvent(&m_event);
549}
550
557{
558 snd_seq_ev_set_chanpress(&m_event, ch, val);
559}
560
566{
567 return new ChanPressEvent(&m_event);
568}
569
575{
576 m_data.clear();
577 snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() );
578}
579
584VariableEvent::VariableEvent(const snd_seq_event_t* event)
585 : SequencerEvent(event)
586{
587 m_data = QByteArray((char *) event->data.ext.ptr,
588 event->data.ext.len);
589 snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() );
590}
591
596VariableEvent::VariableEvent(const QByteArray& data)
598{
599 m_data = data;
600 snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() );
601}
602
608 : SequencerEvent(other)
609{
610 m_data = other.m_data;
611 snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() );
612}
613
619VariableEvent::VariableEvent(const unsigned int datalen, char* dataptr)
621{
622 m_data = QByteArray(dataptr, datalen);
623 snd_seq_ev_set_variable( &m_event, m_data.size(), m_data.data() );
624}
625
632{
633 m_event = other.m_event;
634 m_data = other.m_data;
635 snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() );
636 return *this;
637}
638
644{
645 return new VariableEvent(&m_event);
646}
647
652 : VariableEvent()
653{
654 snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() );
655}
656
661SysExEvent::SysExEvent(const snd_seq_event_t* event)
662 : VariableEvent(event)
663{
664 snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() );
665}
666
671SysExEvent::SysExEvent(const QByteArray& data)
672 : VariableEvent(data)
673{
674 snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() );
675}
676
682 : VariableEvent(other)
683{
684 snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() );
685}
686
692SysExEvent::SysExEvent(const unsigned int datalen, char* dataptr)
693 : VariableEvent( datalen, dataptr )
694{
695 snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() );
696}
697
703{
704 return new SysExEvent(&m_event);
705}
706
711 : VariableEvent(), m_textType(1)
712{
713 setSequencerType(SND_SEQ_EVENT_USR_VAR0);
714}
715
720TextEvent::TextEvent(const snd_seq_event_t* event)
721 : VariableEvent(event), m_textType(1)
722{
723 setSequencerType(SND_SEQ_EVENT_USR_VAR0);
724}
725
731TextEvent::TextEvent(const QString& text, const int textType)
732 : VariableEvent(text.toUtf8()), m_textType(textType)
733{
734 setSequencerType(SND_SEQ_EVENT_USR_VAR0);
735}
736
742 : VariableEvent(other)
743{
744 setSequencerType(SND_SEQ_EVENT_USR_VAR0);
745 m_textType = other.getTextType();
746}
747
753TextEvent::TextEvent(const unsigned int datalen, char* dataptr)
754 : VariableEvent(datalen, dataptr), m_textType(1)
755{
756 setSequencerType(SND_SEQ_EVENT_USR_VAR0);
757}
758
763QString TextEvent::getText() const
764{
765 return QString::fromUtf8(m_data.data(), m_data.size());
766}
767
773{
774 return m_textType;
775}
776
782{
783 return new TextEvent(&m_event);
784}
785
790SystemEvent::SystemEvent(const snd_seq_event_type_t type) : SequencerEvent()
791{
792 snd_seq_ev_set_fixed(&m_event);
793 setSequencerType(type);
794}
795
801{
802 return new SystemEvent(&m_event);
803}
804
811QueueControlEvent::QueueControlEvent(snd_seq_event_type_t type, int queue, int value)
813{
814 snd_seq_ev_set_queue_control(&m_event, type, queue, value);
815}
816
825
831ValueEvent::ValueEvent(const snd_seq_event_type_t type, int val) : SequencerEvent()
832{
833 snd_seq_ev_set_fixed(&m_event);
834 setSequencerType(type);
835 setValue(val);
836}
837
843{
844 return new ValueEvent(&m_event);
845}
846
853{
854 snd_seq_ev_set_queue_tempo(&m_event, queue, tempo);
855}
856
862{
863 return new TempoEvent(&m_event);
864}
865
871{
872 return new ClientEvent(&m_event);
873}
874
880{
881 return new PortEvent(&m_event);
882}
883
892
897{
898 snd_seq_remove_events_malloc(&m_Info);
899}
900
906{
907 snd_seq_remove_events_malloc(&m_Info);
908 snd_seq_remove_events_copy(m_Info, other.m_Info);
909}
910
915RemoveEvents::RemoveEvents(snd_seq_remove_events_t* other)
916{
917 snd_seq_remove_events_malloc(&m_Info);
918 snd_seq_remove_events_copy(m_Info, other);
919}
920
925{
926 snd_seq_remove_events_free(m_Info);
927}
928
935{
936 return new RemoveEvents(m_Info);
937}
938
946{
947 if (this == &other)
948 return *this;
949 snd_seq_remove_events_copy(m_Info, other.m_Info);
950 return *this;
951}
952
957int
959{
960 return snd_seq_remove_events_sizeof();
961}
962
968int
970{
971 return snd_seq_remove_events_get_channel(m_Info);
972}
973
979unsigned int
981{
982 return snd_seq_remove_events_get_condition(m_Info);
983}
984
990const snd_seq_addr_t*
992{
993 return snd_seq_remove_events_get_dest(m_Info);
994}
995
1001int
1003{
1004 return snd_seq_remove_events_get_event_type(m_Info);
1005}
1006
1012int
1014{
1015 return snd_seq_remove_events_get_queue(m_Info);
1016}
1017
1023int
1025{
1026 return snd_seq_remove_events_get_tag(m_Info);
1027}
1028
1034const snd_seq_timestamp_t*
1036{
1037 return snd_seq_remove_events_get_time(m_Info);
1038}
1039
1045void
1047{
1048 snd_seq_remove_events_set_channel(m_Info, chan);
1049}
1050
1069void
1071{
1072 snd_seq_remove_events_set_condition(m_Info, cond);
1073}
1074
1080void
1081RemoveEvents::setDest(const snd_seq_addr_t* dest)
1082{
1083 snd_seq_remove_events_set_dest(m_Info, dest);
1084}
1085
1091void
1093{
1094 snd_seq_remove_events_set_event_type(m_Info, type);
1095}
1096
1102void
1104{
1105 snd_seq_remove_events_set_queue(m_Info, queue);
1106}
1107
1113void
1115{
1116 snd_seq_remove_events_set_tag(m_Info, tag);
1117}
1118
1124void
1125RemoveEvents::setTime(const snd_seq_timestamp_t* time)
1126{
1127 snd_seq_remove_events_set_time(m_Info, time);
1128}
1129
1135MidiCodec::MidiCodec( int bufsize, QObject* parent ) : QObject(parent)
1136{
1137 DRUMSTICK_ALSA_CHECK_ERROR(snd_midi_event_new(bufsize, &m_Info));
1138}
1139
1144{
1145 snd_midi_event_free(m_Info);
1146}
1147
1151void
1153{
1154 snd_midi_event_init(m_Info);
1155}
1156
1164long
1165MidiCodec::decode(unsigned char *buf,
1166 long count,
1167 const snd_seq_event_t *ev)
1168{
1169 return DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_decode(m_Info, buf, count, ev));
1170}
1171
1179long
1180MidiCodec::encode(const unsigned char *buf,
1181 long count,
1182 snd_seq_event_t *ev)
1183{
1184 return DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_encode(m_Info, buf, count, ev));
1185}
1186
1193long
1195 snd_seq_event_t *ev)
1196{
1197 return DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_encode_byte(m_Info, c, ev));
1198}
1199
1204void
1206{
1207 snd_midi_event_no_status(m_Info, enable ? 0 : 1);
1208}
1209
1213void
1215{
1216 snd_midi_event_reset_decode(m_Info);
1217}
1218
1222void
1224{
1225 snd_midi_event_reset_encode(m_Info);
1226}
1227
1232void
1234{
1235 DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_resize_buffer(m_Info, bufsize));
1236}
1237
1238} // namespace ALSA
1239} // namespace drumstick
1240
Classes managing ALSA Sequencer events.
The QEvent class is the base class of all event classes.
The QObject class is the base class of all Qt objects.
virtual ChanPressEvent * clone() const override
Clone this object returning a pointer to the new object.
ChanPressEvent()
Default constructor.
Definition alsaevent.h:442
ChannelEvent()
Default constructor.
Definition alsaevent.h:152
virtual ChannelEvent * clone() const override
Clone this object returning a pointer to the new object.
ClientEvent()
Default constructor.
Definition alsaevent.h:722
virtual ClientEvent * clone() const override
Clone this object returning a pointer to the new object.
virtual ControllerEvent * clone() const override
Clone this object returning a pointer to the new object.
ControllerEvent()
Default constructor.
Definition alsaevent.h:331
virtual KeyEvent * clone() const override
Clone this object returning a pointer to the new object.
KeyEvent()
Default constructor.
Definition alsaevent.h:181
KeyPressEvent()
Default constructor.
Definition alsaevent.h:308
virtual KeyPressEvent * clone() const override
Clone this object returning a pointer to the new object.
void init()
CODEC initialization.
long encode(const unsigned char *buf, long count, snd_seq_event_t *ev)
Encode from byte stream.
void resetEncoder()
Reset MIDI encode parser.
void resizeBuffer(int bufsize)
Resize the CODEC buffer.
void enableRunningStatus(bool enable)
Enable MIDI running status (command merge).
MidiCodec(int bufsize, QObject *parent=nullptr)
MidiCodec constructor.
long decode(unsigned char *buf, long count, const snd_seq_event_t *ev)
Decode from event to bytes.
void resetDecoder()
Reset MIDI decode parser.
NoteEvent()
Default constructor.
Definition alsaevent.h:225
virtual NoteEvent * clone() const override
Clone this object returning a pointer to the new object.
NoteOffEvent()
Default constructor.
Definition alsaevent.h:285
virtual NoteOffEvent * clone() const override
Clone this object returning a pointer to the new object.
virtual NoteOnEvent * clone() const override
Clone this object returning a pointer to the new object.
NoteOnEvent()
Default constructor.
Definition alsaevent.h:262
virtual PitchBendEvent * clone() const override
Clone this object returning a pointer to the new object.
PitchBendEvent()
Default constructor.
Definition alsaevent.h:410
PortEvent()
Default constructor.
Definition alsaevent.h:743
virtual PortEvent * clone() const override
Clone this object returning a pointer to the new object.
virtual ProgramChangeEvent * clone() const override
Clone this object returning a pointer to the new object.
ProgramChangeEvent()
Default constructor.
Definition alsaevent.h:378
virtual QueueControlEvent * clone() const override
Clone this object returning a pointer to the new object.
QueueControlEvent()
Default constructor.
Definition alsaevent.h:555
Auxiliary class to remove events from an ALSA queue.
Definition alsaevent.h:762
virtual ~RemoveEvents()
Destructor.
int getSizeOfInfo() const
Gets the allocated size of the ALSA remove events object.
void setEventType(int type)
Sets the event type.
void setTag(int tag)
Sets the numeric tag.
RemoveEvents & operator=(const RemoveEvents &other)
Assignment operator.
const snd_seq_timestamp_t * getTime()
Gets the timestamp.
RemoveEvents()
Default constructor.
int getQueue()
Gets the queue number.
void setCondition(unsigned int cond)
Sets the flags of the conditional event's removal.
void setQueue(int queue)
Sets the queue number.
void setTime(const snd_seq_timestamp_t *time)
Sets the timestamp.
void setChannel(int chan)
Gets the MIDI channel.
int getEventType()
Gets the event type.
RemoveEvents * clone()
Create a new object copied from this object and return a pointer to the copy.
void setDest(const snd_seq_addr_t *dest)
Set the destination address.
int getTag()
Gets the numeric tag.
const snd_seq_addr_t * getDest()
Gets the destination.
int getChannel()
Gets the MIDI channel.
unsigned int getCondition()
Gets the condition.
Base class for the event's hierarchy.
Definition alsaevent.h:58
snd_seq_event_t m_event
ALSA sequencer event record.
Definition alsaevent.h:142
static bool isConnectionChange(const SequencerEvent *event)
Checks if the event's type is of type connection change.
void setSequencerType(const snd_seq_event_type_t eventType)
Sets the event's ALSA sequencer type.
int getEncodedLength()
Gets the encoded length of the event record.
static bool isChannel(const SequencerEvent *event)
Checks if the event's type is a Channel Voice message.
void scheduleTick(const int queue, const int tick, const bool relative)
Sets the event to be scheduled in musical time (ticks) units.
void setDirect()
Sets the event to be immediately delivered, not queued/scheduled.
virtual SequencerEvent * clone() const
Clone this object returning a pointer to the new object.
unsigned char getRaw8(const unsigned int n) const
Gets an event's raw 8 bits parameter.
void free() __attribute__((deprecated))
Releases the event record.
void setRaw32(const unsigned int n, const unsigned int value)
Sets an event's raw 32 bits parameter.
void scheduleReal(const int queue, const ulong secs, const ulong nanos, const bool relative)
Sets the event to be scheduled in real (clock) time units.
SequencerEvent()
Default constructor.
Definition alsaevent.cpp:99
unsigned int getRaw32(const unsigned int n) const
Gets an event's raw 32 bits parameter.
void setRaw8(const unsigned int n, const unsigned char value)
Sets an event's raw 8 bits parameter.
static bool isSubscription(const SequencerEvent *event)
Checks if the event's type is a subscription.
void setSubscribers()
Sets the event's destination to be all the subscribers of the source port.
void setDestination(const unsigned char client, const unsigned char port)
Sets the client:port destination of the event.
static bool isPort(const SequencerEvent *event)
Checks if the event's type is of type port.
void setSource(const unsigned char port)
Sets the event's source port ID.
static bool isClient(const SequencerEvent *event)
Checks if the event's type is of type client.
void setTag(const unsigned char aTag)
Sets the event's tag.
void setPriority(const bool high)
Sets the priority of the event.
SequencerEvent & operator=(const SequencerEvent &other)
Assignment operator.
void setBroadcast()
Sets the event's destination to be all queues/clients/ports/channels.
virtual SubscriptionEvent * clone() const override
Clone this object returning a pointer to the new object.
SubscriptionEvent()
Default constructor.
Definition alsaevent.h:676
SysExEvent()
Default constructor.
virtual SysExEvent * clone() const override
Clone this object returning a pointer to the new object.
SystemEvent()
Default constructor.
Definition alsaevent.h:536
virtual SystemEvent * clone() const override
Clone this object returning a pointer to the new object.
TempoEvent()
Default constructor.
Definition alsaevent.h:659
virtual TempoEvent * clone() const override
Clone this object returning a pointer to the new object.
TextEvent()
Default constructor.
virtual TextEvent * clone() const override
Clone this object returning a pointer to the new object.
QString getText() const
Gets the event's text content.
int getTextType() const
Gets the event's SMF text type.
virtual ValueEvent * clone() const override
Clone this object returning a pointer to the new object.
void setValue(const int v)
Sets the event's value.
Definition alsaevent.h:648
ValueEvent()
Default constructor.
Definition alsaevent.h:632
virtual VariableEvent * clone() const override
Clone this object returning a pointer to the new object.
VariableEvent & operator=(const VariableEvent &other)
Assignment operator.
VariableEvent()
Default constructor.
Error checking functions and macros.
#define DRUMSTICK_ALSA_CHECK_WARNING(x)
This macro calls the check warning function.
Definition errorcheck.h:86
#define DRUMSTICK_ALSA_CHECK_ERROR(x)
This macro calls the check error function.
Definition errorcheck.h:80
const QEvent::Type SequencerEventType
Constant SequencerEventType is the QEvent::type() of any SequencerEvent object to be used to check th...
Definition alsaevent.h:49
Drumstick common.