drumstick 2.9.0
C++ MIDI libraries using Qt objects, idioms, and style.
alsaqueue.cpp
Go to the documentation of this file.
1/*
2 MIDI Sequencer C++ library
3 Copyright (C) 2006-2023, 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 <cmath>
22#include <drumstick/alsaevent.h>
23#include <drumstick/alsaqueue.h>
24#include <drumstick/alsatimer.h>
25
31namespace drumstick {
32namespace ALSA {
33
38const unsigned int SKEW_BASE = 0x10000;
39
68{
69 snd_seq_queue_info_malloc(&m_Info);
70}
71
76QueueInfo::QueueInfo(snd_seq_queue_info_t* other)
77{
78 snd_seq_queue_info_malloc(&m_Info);
79 snd_seq_queue_info_copy(m_Info, other);
80}
81
87{
88 snd_seq_queue_info_malloc(&m_Info);
89 snd_seq_queue_info_copy(m_Info, other.m_Info);
90}
91
96{
97 snd_seq_queue_info_free(m_Info);
98}
99
105{
106 return new QueueInfo(m_Info);
107}
108
115{
116 if (this == &other)
117 return *this;
118 snd_seq_queue_info_copy(m_Info, other.m_Info);
119 return *this;
120}
121
127{
128 return snd_seq_queue_info_get_queue(m_Info);
129}
130
136{
137 return QString(snd_seq_queue_info_get_name(m_Info));
138}
139
145{
146 return snd_seq_queue_info_get_owner(m_Info);
147}
148
154{
155 return (snd_seq_queue_info_get_locked(m_Info) != 0);
156}
157
163{
164 return snd_seq_queue_info_get_flags(m_Info);
165}
166
171void QueueInfo::setName(QString value)
172{
173 snd_seq_queue_info_set_name(m_Info, value.toLocal8Bit().data());
174}
175
180void QueueInfo::setOwner(int value)
181{
182 snd_seq_queue_info_set_owner(m_Info, value);
183}
184
189void QueueInfo::setFlags(unsigned int value)
190{
191 snd_seq_queue_info_set_flags(m_Info, value);
192}
193
198void QueueInfo::setLocked(bool locked)
199{
200 snd_seq_queue_info_set_locked(m_Info, locked ? 1 : 0);
201}
202
208{
209 return snd_seq_queue_info_sizeof();
210}
211
212
217{
218 snd_seq_queue_status_malloc(&m_Info);
219}
220
225QueueStatus::QueueStatus(snd_seq_queue_status_t* other)
226{
227 snd_seq_queue_status_malloc(&m_Info);
228 snd_seq_queue_status_copy(m_Info, other);
229}
230
236{
237 snd_seq_queue_status_malloc(&m_Info);
238 snd_seq_queue_status_copy(m_Info, other.m_Info);
239}
240
245{
246 snd_seq_queue_status_free(m_Info);
247}
248
254{
255 return new QueueStatus(m_Info);
256}
257
264{
265 if (this == &other)
266 return *this;
267 snd_seq_queue_status_copy(m_Info, other.m_Info);
268 return *this;
269}
270
276{
277 return snd_seq_queue_status_get_queue(m_Info);
278}
279
285{
286 return snd_seq_queue_status_get_events(m_Info);
287}
288
293const snd_seq_real_time_t* QueueStatus::getRealtime()
294{
295 return snd_seq_queue_status_get_real_time(m_Info);
296}
297
303{
304 return snd_seq_queue_status_get_status(m_Info);
305}
306
311snd_seq_tick_time_t QueueStatus::getTickTime()
312{
313 return snd_seq_queue_status_get_tick_time(m_Info);
314}
315
321{
322 return snd_seq_queue_status_sizeof();
323}
324
330{
331 return (snd_seq_queue_status_get_status(m_Info) != 0);
332}
333
339{
340 const snd_seq_real_time_t* time = snd_seq_queue_status_get_real_time(m_Info);
341 return (time->tv_sec * 1.0) + (time->tv_nsec * 1.0e-9);
342}
343
348{
349 snd_seq_queue_tempo_malloc(&m_Info);
350}
351
356QueueTempo::QueueTempo(snd_seq_queue_tempo_t* other)
357{
358 snd_seq_queue_tempo_malloc(&m_Info);
359 snd_seq_queue_tempo_copy(m_Info, other);
360}
361
367{
368 snd_seq_queue_tempo_malloc(&m_Info);
369 snd_seq_queue_tempo_copy(m_Info, other.m_Info);
370}
371
376{
377 snd_seq_queue_tempo_free(m_Info);
378}
379
385{
386 return new QueueTempo(m_Info);
387}
388
395{
396 if (this == &other)
397 return *this;
398 snd_seq_queue_tempo_copy(m_Info, other.m_Info);
399 return *this;
400}
401
407{
408 return snd_seq_queue_tempo_get_queue(m_Info);
409}
410
416{
417 return snd_seq_queue_tempo_get_ppq(m_Info);
418}
419
427{
428 return snd_seq_queue_tempo_get_skew(m_Info);
429}
430
438{
439 return snd_seq_queue_tempo_get_skew_base(m_Info);
440}
441
447{
448 return snd_seq_queue_tempo_get_tempo(m_Info);
449}
450
455void QueueTempo::setPPQ(int value)
456{
457 snd_seq_queue_tempo_set_ppq(m_Info, value);
458}
459
466void QueueTempo::setSkewValue(unsigned int value)
467{
468 snd_seq_queue_tempo_set_skew(m_Info, value);
469}
470
478void QueueTempo::setSkewBase(unsigned int value)
479{
480 snd_seq_queue_tempo_set_skew_base(m_Info, value);
481}
482
487void QueueTempo::setTempo(unsigned int value)
488{
489 snd_seq_queue_tempo_set_tempo(m_Info, value);
490}
491
497{
498 int itempo = getTempo();
499 if (itempo != 0)
500 return 6.0e7f / itempo;
501 return 0.0f;
502}
503
510{
511 float tempo = getNominalBPM();
512 return tempo * getSkewValue() / SKEW_BASE;
513}
514
520{
521 setSkewValue(floor(SKEW_BASE * value));
523}
524
530{
531 setTempo(floor(6.0e7f / value));
532}
533
539{
540 return snd_seq_queue_tempo_sizeof();
541}
542
547{
548 snd_seq_queue_timer_malloc(&m_Info);
549}
550
555QueueTimer::QueueTimer(snd_seq_queue_timer_t* other)
556{
557 snd_seq_queue_timer_malloc(&m_Info);
558 snd_seq_queue_timer_copy(m_Info, other);
559}
560
566{
567 snd_seq_queue_timer_malloc(&m_Info);
568 snd_seq_queue_timer_copy(m_Info, other.m_Info);
569}
570
575{
576 snd_seq_queue_timer_free(m_Info);
577}
578
584{
585 return new QueueTimer(m_Info);
586}
587
594{
595 if (this == &other)
596 return *this;
597 snd_seq_queue_timer_copy(m_Info, other.m_Info);
598 return *this;
599}
600
606{
607 return snd_seq_queue_timer_get_queue(m_Info);
608}
609
622snd_seq_queue_timer_type_t QueueTimer::getType()
623{
624 return snd_seq_queue_timer_get_type(m_Info);
625}
626
631const snd_timer_id_t* QueueTimer::getId()
632{
633 return snd_seq_queue_timer_get_id(m_Info);
634}
635
641{
642 return snd_seq_queue_timer_get_resolution(m_Info);
643}
644
656void QueueTimer::setType(snd_seq_queue_timer_type_t value)
657{
658 snd_seq_queue_timer_set_type(m_Info, value);
659}
660
665void QueueTimer::setId(snd_timer_id_t* value)
666{
667 snd_seq_queue_timer_set_id(m_Info, value);
668}
669
676{
677 setId(id.m_Info);
678}
679
684void QueueTimer::setResolution(unsigned int value)
685{
686 snd_seq_queue_timer_set_resolution(m_Info, value);
687}
688
694{
695 return snd_seq_queue_timer_sizeof();
696}
697
704 : QObject(parent)
705{
706 m_MidiClient = seq;
707 m_Id = DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_alloc_queue(m_MidiClient->getHandle()));
708 m_allocated = !(m_Id < 0);
709}
710
718 : QObject(parent)
719{
720 m_MidiClient = seq;
721 m_Info = info;
722 m_Id = DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_create_queue(m_MidiClient->getHandle(), m_Info.m_Info));
723 m_allocated = !(m_Id < 0);
724}
725
732MidiQueue::MidiQueue(MidiClient* seq, const QString name, QObject* parent)
733 : QObject(parent)
734{
735 m_MidiClient = seq;
736 m_Id = DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_alloc_named_queue(m_MidiClient->getHandle(), name.toLocal8Bit().data()));
737 m_allocated = !(m_Id < 0);
738}
739
748MidiQueue::MidiQueue(MidiClient* seq, const int queue_id, QObject* parent)
749 : QObject(parent)
750{
751 m_MidiClient = seq;
752 m_Id = queue_id;
753 m_allocated = false;
754}
755
760{
761 if ( m_allocated && (m_MidiClient->getHandle() != nullptr) )
762 {
763 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_free_queue(m_MidiClient->getHandle(), m_Id));
764 }
765}
766
772{
773 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_info(m_MidiClient->getHandle(), m_Id, m_Info.m_Info));
774 return m_Info;
775}
776
782{
783 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_status(m_MidiClient->getHandle(), m_Id, m_Status.m_Info));
784 return m_Status;
785}
786
792{
793 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_tempo(m_MidiClient->getHandle(), m_Id, m_Tempo.m_Info));
794 return m_Tempo;
795}
796
802{
803 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_timer(m_MidiClient->getHandle(), m_Id, m_Timer.m_Info));
804 return m_Timer;
805}
806
812{
813 m_Info = value;
814 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_info(m_MidiClient->getHandle(), m_Id, m_Info.m_Info));
815}
816
822{
823 m_Tempo = value;
824 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_tempo(m_MidiClient->getHandle(), m_Id, m_Tempo.m_Info));
825}
826
832{
833 m_Timer = value;
834 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_timer(m_MidiClient->getHandle(), m_Id, m_Timer.m_Info));
835}
836
843{
844 return DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_usage(m_MidiClient->getHandle(), m_Id));
845}
846
853{
854 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_usage(m_MidiClient->getHandle(), m_Id, used));
855}
856
863{
864 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_start_queue(m_MidiClient->getHandle(), m_Id, nullptr));
865 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(m_MidiClient->getHandle()));
866}
867
874{
875 if (m_MidiClient != nullptr && m_MidiClient->getHandle() != nullptr) {
876 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_stop_queue(m_MidiClient->getHandle(), m_Id, nullptr));
877 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(m_MidiClient->getHandle()));
878 }
879}
880
887{
888 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_continue_queue(m_MidiClient->getHandle(), m_Id, nullptr));
889 DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(m_MidiClient->getHandle()));
890}
891
896{
897 if (m_MidiClient != nullptr && m_MidiClient->getHandle() != nullptr)
898 snd_seq_drop_output(m_MidiClient->getHandle());
899}
900
905void MidiQueue::setTickPosition(snd_seq_tick_time_t pos)
906{
907 SystemEvent event(SND_SEQ_EVENT_SETPOS_TICK);
908 snd_seq_ev_set_queue_pos_tick(event.getHandle(), m_Id, pos);
909 event.setDirect();
910 m_MidiClient->outputDirect(&event);
911}
912
917void MidiQueue::setRealTimePosition(snd_seq_real_time_t* pos)
918{
919 SystemEvent event(SND_SEQ_EVENT_SETPOS_TIME);
920 snd_seq_ev_set_queue_pos_real(event.getHandle(), m_Id, pos);
921 event.setDirect();
922 m_MidiClient->outputDirect(&event);
923}
924
925} // namespace ALSA
926} // namespace drumstick
927
Classes managing ALSA Sequencer clients.
Classes managing ALSA Sequencer events.
Classes managing ALSA Sequencer queues.
Classes managing ALSA Timers.
The QObject class is the base class of all Qt objects.
Client management.
Definition: alsaclient.h:219
void setTimer(const QueueTimer &value)
Applies q QueueTimer object to the queue.
Definition: alsaqueue.cpp:831
void setInfo(const QueueInfo &value)
Applies a QueueInfo object to the queue.
Definition: alsaqueue.cpp:811
int getUsage()
Gets the queue usage flag.
Definition: alsaqueue.cpp:842
void setTickPosition(snd_seq_tick_time_t pos)
Sets the queue position in musical time (ticks).
Definition: alsaqueue.cpp:905
void continueRunning()
Start the queue without resetting the last position.
Definition: alsaqueue.cpp:886
QueueTimer & getTimer()
Gets a QueueTimer object reference.
Definition: alsaqueue.cpp:801
QueueStatus & getStatus()
Gets a QueueStatus object reference.
Definition: alsaqueue.cpp:781
void start()
Start the queue.
Definition: alsaqueue.cpp:862
void stop()
Stop the queue.
Definition: alsaqueue.cpp:873
MidiQueue(MidiClient *seq, QObject *parent=nullptr)
Constructor.
Definition: alsaqueue.cpp:703
void setRealTimePosition(snd_seq_real_time_t *pos)
Sets the queue position in real time (clock) units: seconds and nanoseconds.
Definition: alsaqueue.cpp:917
void clear()
Clear the queue, dropping any scheduled events.
Definition: alsaqueue.cpp:895
QueueInfo & getInfo()
Gets a QueueInfo object reference.
Definition: alsaqueue.cpp:771
virtual ~MidiQueue()
Destructor.
Definition: alsaqueue.cpp:759
QueueTempo & getTempo()
Gets a QueueTempo object reference.
Definition: alsaqueue.cpp:791
void setUsage(int used)
Sets the queue usage flag.
Definition: alsaqueue.cpp:852
void setTempo(const QueueTempo &value)
Applies a QueueTempo object to the queue.
Definition: alsaqueue.cpp:821
Queue information container.
Definition: alsaqueue.h:60
bool isLocked()
Returns the locking status of the queue.
Definition: alsaqueue.cpp:153
int getInfoSize() const
Gets the size of the ALSA queue info object.
Definition: alsaqueue.cpp:207
unsigned int getFlags()
Gets the flags of the queue.
Definition: alsaqueue.cpp:162
void setLocked(bool locked)
Sets the locked status of the queue.
Definition: alsaqueue.cpp:198
int getOwner()
Gets the owner's client id of the queue.
Definition: alsaqueue.cpp:144
virtual ~QueueInfo()
Destructor.
Definition: alsaqueue.cpp:95
QueueInfo()
Default constructor.
Definition: alsaqueue.cpp:67
int getId()
Gets the queue's numeric identifier.
Definition: alsaqueue.cpp:126
QueueInfo * clone()
Copy the current object and return the copy.
Definition: alsaqueue.cpp:104
void setFlags(unsigned int value)
Sets the bit flags of the queue.
Definition: alsaqueue.cpp:189
QString getName()
Gets the queue name.
Definition: alsaqueue.cpp:135
void setName(QString value)
Sets the queue name.
Definition: alsaqueue.cpp:171
QueueInfo & operator=(const QueueInfo &other)
Assignment operator.
Definition: alsaqueue.cpp:114
void setOwner(int value)
Sets the client ID of the owner.
Definition: alsaqueue.cpp:180
Queue status container.
Definition: alsaqueue.h:93
int getInfoSize() const
Gets the size of the ALSA status object.
Definition: alsaqueue.cpp:320
bool isRunning()
Gets the queue's running state.
Definition: alsaqueue.cpp:329
int getEvents()
Gets the number of queued events.
Definition: alsaqueue.cpp:284
int getId()
Gets the queue's numeric identifier.
Definition: alsaqueue.cpp:275
QueueStatus * clone()
Copy the current object and return the copy.
Definition: alsaqueue.cpp:253
const snd_seq_real_time_t * getRealtime()
Gets the real time (secods and nanoseconds) of the queue.
Definition: alsaqueue.cpp:293
QueueStatus()
Default constructor.
Definition: alsaqueue.cpp:216
snd_seq_tick_time_t getTickTime()
Gets the musical time (ticks) of the queue.
Definition: alsaqueue.cpp:311
double getClockTime()
Gets the clock time in seconds of the queue.
Definition: alsaqueue.cpp:338
QueueStatus & operator=(const QueueStatus &other)
Assignment operator.
Definition: alsaqueue.cpp:263
virtual ~QueueStatus()
Destructor.
Definition: alsaqueue.cpp:244
unsigned int getStatusBits()
Gets the running status bits.
Definition: alsaqueue.cpp:302
Queue tempo container.
Definition: alsaqueue.h:130
int getInfoSize() const
Gets the size of the ALSA queue tempo object.
Definition: alsaqueue.cpp:538
void setSkewValue(unsigned int value)
Sets the tempo skew numerator.
Definition: alsaqueue.cpp:466
int getId()
Gets the queue's numeric identifier.
Definition: alsaqueue.cpp:406
void setPPQ(int value)
Sets the queue resolution in parts per quarter note.
Definition: alsaqueue.cpp:455
unsigned int getTempo()
Gets the queue's tempo in microseconds per beat.
Definition: alsaqueue.cpp:446
QueueTempo()
Default constructor.
Definition: alsaqueue.cpp:347
void setTempo(unsigned int value)
Sets the queue tempo in microseconds per beat.
Definition: alsaqueue.cpp:487
float getRealBPM()
Gets the queue's real BPM tempo in beats per minute.
Definition: alsaqueue.cpp:509
unsigned int getSkewValue()
Gets the tempo skew numerator.
Definition: alsaqueue.cpp:426
float getNominalBPM()
Gets the queue's nominal BPM tempo (in beats per minute)
Definition: alsaqueue.cpp:496
unsigned int getSkewBase()
Gets the tempo skew base.
Definition: alsaqueue.cpp:437
QueueTempo * clone()
Copy the current object returning the copied object.
Definition: alsaqueue.cpp:384
void setSkewBase(unsigned int value)
Sets the tempo skew base.
Definition: alsaqueue.cpp:478
void setNominalBPM(float value)
Sets the queue's nominal tempo in BPM (beats per minute).
Definition: alsaqueue.cpp:529
virtual ~QueueTempo()
Destructor.
Definition: alsaqueue.cpp:375
int getPPQ()
Gets the PPQ (parts per quarter note) resolution of the queue.
Definition: alsaqueue.cpp:415
QueueTempo & operator=(const QueueTempo &other)
Assignment operator.
Definition: alsaqueue.cpp:394
void setTempoFactor(float value)
Sets the queue's tempo skew factor.
Definition: alsaqueue.cpp:519
Queue timer container.
Definition: alsaqueue.h:170
int getInfoSize() const
Gets the size of the ALSA queue timer object.
Definition: alsaqueue.cpp:693
snd_seq_queue_timer_type_t getType()
Gets the timer type.
Definition: alsaqueue.cpp:622
const snd_timer_id_t * getId()
Gets the timer identifier record.
Definition: alsaqueue.cpp:631
QueueTimer()
Default constructor.
Definition: alsaqueue.cpp:546
QueueTimer & operator=(const QueueTimer &other)
Assignment operator.
Definition: alsaqueue.cpp:593
void setResolution(unsigned int value)
Sets the timer resolution.
Definition: alsaqueue.cpp:684
QueueTimer * clone()
Copy the current object and return the copy.
Definition: alsaqueue.cpp:583
unsigned int getResolution()
Gets the timer resolution.
Definition: alsaqueue.cpp:640
int getQueueId()
The queue's numeric identifier.
Definition: alsaqueue.cpp:605
void setId(snd_timer_id_t *value)
Sets the timer identifier record.
Definition: alsaqueue.cpp:665
void setType(snd_seq_queue_timer_type_t value)
Sets the timer type.
Definition: alsaqueue.cpp:656
virtual ~QueueTimer()
Destructor.
Definition: alsaqueue.cpp:574
snd_seq_event_t * getHandle()
Gets the handle of the event.
Definition: alsaevent.h:135
ALSA Timer identifier container.
Definition: alsatimer.h:96
Error checking functions and macros.
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
Definition: alsaclient.cpp:286
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
#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 unsigned int SKEW_BASE
This is the value for the base skew used in ALSA.
Definition: alsaqueue.cpp:38
Drumstick common.
Definition: alsaclient.cpp:68