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>
21 #include <drumstick/alsaclient.h>
22 #include <drumstick/alsaevent.h>
23 #include <drumstick/alsaqueue.h>
24 #include <drumstick/alsatimer.h>
25 
31 namespace drumstick {
32 namespace ALSA {
33 
38 const unsigned int SKEW_BASE = 0x10000;
39 
68 {
69  snd_seq_queue_info_malloc(&m_Info);
70 }
71 
76 QueueInfo::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 
162 unsigned int QueueInfo::getFlags()
163 {
164  return snd_seq_queue_info_get_flags(m_Info);
165 }
166 
171 void QueueInfo::setName(QString value)
172 {
173  snd_seq_queue_info_set_name(m_Info, value.toLocal8Bit().data());
174 }
175 
180 void QueueInfo::setOwner(int value)
181 {
182  snd_seq_queue_info_set_owner(m_Info, value);
183 }
184 
189 void QueueInfo::setFlags(unsigned int value)
190 {
191  snd_seq_queue_info_set_flags(m_Info, value);
192 }
193 
198 void 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 
225 QueueStatus::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 
293 const 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 
311 snd_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 
356 QueueTempo::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 
446 unsigned int QueueTempo::getTempo()
447 {
448  return snd_seq_queue_tempo_get_tempo(m_Info);
449 }
450 
455 void QueueTempo::setPPQ(int value)
456 {
457  snd_seq_queue_tempo_set_ppq(m_Info, value);
458 }
459 
466 void QueueTempo::setSkewValue(unsigned int value)
467 {
468  snd_seq_queue_tempo_set_skew(m_Info, value);
469 }
470 
478 void QueueTempo::setSkewBase(unsigned int value)
479 {
480  snd_seq_queue_tempo_set_skew_base(m_Info, value);
481 }
482 
487 void 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 
519 void QueueTempo::setTempoFactor(float value)
520 {
521  setSkewValue(floor(SKEW_BASE * value));
523 }
524 
529 void QueueTempo::setNominalBPM(float value)
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 
555 QueueTimer::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 
622 snd_seq_queue_timer_type_t QueueTimer::getType()
623 {
624  return snd_seq_queue_timer_get_type(m_Info);
625 }
626 
631 const 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 
656 void QueueTimer::setType(snd_seq_queue_timer_type_t value)
657 {
658  snd_seq_queue_timer_set_type(m_Info, value);
659 }
660 
665 void QueueTimer::setId(snd_timer_id_t* value)
666 {
667  snd_seq_queue_timer_set_id(m_Info, value);
668 }
669 
675 void QueueTimer::setId(const TimerId& id)
676 {
677  setId(id.m_Info);
678 }
679 
684 void 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 
732 MidiQueue::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 
748 MidiQueue::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 
811 void MidiQueue::setInfo(const QueueInfo& value)
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 
821 void MidiQueue::setTempo(const QueueTempo& value)
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 
831 void MidiQueue::setTimer(const QueueTimer& value)
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 
852 void MidiQueue::setUsage(int used)
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 
905 void 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 
917 void 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