drumstick 2.10.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-2024, 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
30
31namespace drumstick {
32namespace ALSA {
33
38const unsigned int SKEW_BASE = 0x10000;
39
63
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.
void setInfo(const QueueInfo &value)
Applies a QueueInfo object to the queue.
int getUsage()
Gets the queue usage flag.
void setTickPosition(snd_seq_tick_time_t pos)
Sets the queue position in musical time (ticks).
void continueRunning()
Start the queue without resetting the last position.
QueueTimer & getTimer()
Gets a QueueTimer object reference.
QueueStatus & getStatus()
Gets a QueueStatus object reference.
void start()
Start the queue.
void stop()
Stop the queue.
MidiQueue(MidiClient *seq, QObject *parent=nullptr)
Constructor.
void setRealTimePosition(snd_seq_real_time_t *pos)
Sets the queue position in real time (clock) units: seconds and nanoseconds.
void clear()
Clear the queue, dropping any scheduled events.
QueueInfo & getInfo()
Gets a QueueInfo object reference.
virtual ~MidiQueue()
Destructor.
QueueTempo & getTempo()
Gets a QueueTempo object reference.
void setUsage(int used)
Sets the queue usage flag.
void setTempo(const QueueTempo &value)
Applies a QueueTempo object to the queue.
Queue information container.
Definition alsaqueue.h:60
bool isLocked()
Returns the locking status of the queue.
int getInfoSize() const
Gets the size of the ALSA queue info object.
unsigned int getFlags()
Gets the flags of the queue.
void setLocked(bool locked)
Sets the locked status of the queue.
int getOwner()
Gets the owner's client id of the queue.
virtual ~QueueInfo()
Destructor.
Definition alsaqueue.cpp:95
QueueInfo()
Default constructor.
Definition alsaqueue.cpp:67
int getId()
Gets the queue's numeric identifier.
QueueInfo * clone()
Copy the current object and return the copy.
void setFlags(unsigned int value)
Sets the bit flags of the queue.
QString getName()
Gets the queue name.
void setName(QString value)
Sets the queue name.
QueueInfo & operator=(const QueueInfo &other)
Assignment operator.
void setOwner(int value)
Sets the client ID of the owner.
Queue status container.
Definition alsaqueue.h:93
int getInfoSize() const
Gets the size of the ALSA status object.
bool isRunning()
Gets the queue's running state.
int getEvents()
Gets the number of queued events.
int getId()
Gets the queue's numeric identifier.
QueueStatus * clone()
Copy the current object and return the copy.
const snd_seq_real_time_t * getRealtime()
Gets the real time (secods and nanoseconds) of the queue.
QueueStatus()
Default constructor.
snd_seq_tick_time_t getTickTime()
Gets the musical time (ticks) of the queue.
double getClockTime()
Gets the clock time in seconds of the queue.
QueueStatus & operator=(const QueueStatus &other)
Assignment operator.
virtual ~QueueStatus()
Destructor.
unsigned int getStatusBits()
Gets the running status bits.
Queue tempo container.
Definition alsaqueue.h:130
int getInfoSize() const
Gets the size of the ALSA queue tempo object.
void setSkewValue(unsigned int value)
Sets the tempo skew numerator.
int getId()
Gets the queue's numeric identifier.
void setPPQ(int value)
Sets the queue resolution in parts per quarter note.
unsigned int getTempo()
Gets the queue's tempo in microseconds per beat.
QueueTempo()
Default constructor.
void setTempo(unsigned int value)
Sets the queue tempo in microseconds per beat.
float getRealBPM()
Gets the queue's real BPM tempo in beats per minute.
unsigned int getSkewValue()
Gets the tempo skew numerator.
float getNominalBPM()
Gets the queue's nominal BPM tempo (in beats per minute)
unsigned int getSkewBase()
Gets the tempo skew base.
QueueTempo * clone()
Copy the current object returning the copied object.
void setSkewBase(unsigned int value)
Sets the tempo skew base.
void setNominalBPM(float value)
Sets the queue's nominal tempo in BPM (beats per minute).
virtual ~QueueTempo()
Destructor.
int getPPQ()
Gets the PPQ (parts per quarter note) resolution of the queue.
QueueTempo & operator=(const QueueTempo &other)
Assignment operator.
void setTempoFactor(float value)
Sets the queue's tempo skew factor.
Queue timer container.
Definition alsaqueue.h:170
int getInfoSize() const
Gets the size of the ALSA queue timer object.
snd_seq_queue_timer_type_t getType()
Gets the timer type.
const snd_timer_id_t * getId()
Gets the timer identifier record.
QueueTimer()
Default constructor.
QueueTimer & operator=(const QueueTimer &other)
Assignment operator.
void setResolution(unsigned int value)
Sets the timer resolution.
QueueTimer * clone()
Copy the current object and return the copy.
unsigned int getResolution()
Gets the timer resolution.
int getQueueId()
The queue's numeric identifier.
void setId(snd_timer_id_t *value)
Sets the timer identifier record.
void setType(snd_seq_queue_timer_type_t value)
Sets the timer type.
virtual ~QueueTimer()
Destructor.
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.
#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
Drumstick ALSA library wrapper.
const unsigned int SKEW_BASE
This is the value for the base skew used in ALSA.
Definition alsaqueue.cpp:38
Drumstick common.