drumstick  2.9.0
C++MIDIlibrariesusingQtobjects,idioms,andstyle.
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 
unsigned int getTempo()
Gets the queue&#39;s tempo in microseconds per beat.
Definition: alsaqueue.cpp:446
unsigned int getSkewValue()
Gets the tempo skew numerator.
Definition: alsaqueue.cpp:426
virtual ~QueueInfo()
Destructor.
Definition: alsaqueue.cpp:95
Error checking functions and macros.
int getId()
Gets the queue&#39;s numeric identifier.
Definition: alsaqueue.cpp:275
void setInfo(const QueueInfo &value)
Applies a QueueInfo object to the queue.
Definition: alsaqueue.cpp:811
int getInfoSize() const
Gets the size of the ALSA queue timer object.
Definition: alsaqueue.cpp:693
virtual ~MidiQueue()
Destructor.
Definition: alsaqueue.cpp:759
void stop()
Stop the queue.
Definition: alsaqueue.cpp:873
void setUsage(int used)
Sets the queue usage flag.
Definition: alsaqueue.cpp:852
Classes managing ALSA Sequencer clients.
void setResolution(unsigned int value)
Sets the timer resolution.
Definition: alsaqueue.cpp:684
void setPPQ(int value)
Sets the queue resolution in parts per quarter note.
Definition: alsaqueue.cpp:455
snd_seq_queue_timer_type_t getType()
Gets the timer type.
Definition: alsaqueue.cpp:622
void setFlags(unsigned int value)
Sets the bit flags of the queue.
Definition: alsaqueue.cpp:189
void setTempo(unsigned int value)
Sets the queue tempo in microseconds per beat.
Definition: alsaqueue.cpp:487
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
Definition: alsaclient.cpp:286
Queue information container.
Definition: alsaqueue.h:59
#define DRUMSTICK_ALSA_CHECK_WARNING(x)
This macro calls the check warning function.
Definition: errorcheck.h:86
QueueStatus & operator=(const QueueStatus &other)
Assignment operator.
Definition: alsaqueue.cpp:263
virtual ~QueueStatus()
Destructor.
Definition: alsaqueue.cpp:244
float getNominalBPM()
Gets the queue&#39;s nominal BPM tempo (in beats per minute)
Definition: alsaqueue.cpp:496
QueueTimer * clone()
Copy the current object and return the copy.
Definition: alsaqueue.cpp:583
unsigned int getFlags()
Gets the flags of the queue.
Definition: alsaqueue.cpp:162
QueueTempo()
Default constructor.
Definition: alsaqueue.cpp:347
virtual ~QueueTimer()
Destructor.
Definition: alsaqueue.cpp:574
QueueTimer()
Default constructor.
Definition: alsaqueue.cpp:546
float getRealBPM()
Gets the queue&#39;s real BPM tempo in beats per minute.
Definition: alsaqueue.cpp:509
QueueInfo * clone()
Copy the current object and return the copy.
Definition: alsaqueue.cpp:104
void setRealTimePosition(snd_seq_real_time_t *pos)
Sets the queue position in real time (clock) units: seconds and nanoseconds.
Definition: alsaqueue.cpp:917
The QObject class is the base class of all Qt objects.
snd_seq_tick_time_t getTickTime()
Gets the musical time (ticks) of the queue.
Definition: alsaqueue.cpp:311
int getInfoSize() const
Gets the size of the ALSA status object.
Definition: alsaqueue.cpp:320
void setOwner(int value)
Sets the client ID of the owner.
Definition: alsaqueue.cpp:180
Queue tempo container.
Definition: alsaqueue.h:129
int getPPQ()
Gets the PPQ (parts per quarter note) resolution of the queue.
Definition: alsaqueue.cpp:415
Classes managing ALSA Timers.
QueueInfo & getInfo()
Gets a QueueInfo object reference.
Definition: alsaqueue.cpp:771
void setLocked(bool locked)
Sets the locked status of the queue.
Definition: alsaqueue.cpp:198
Queue timer container.
Definition: alsaqueue.h:169
unsigned int getSkewBase()
Gets the tempo skew base.
Definition: alsaqueue.cpp:437
void clear()
Clear the queue, dropping any scheduled events.
Definition: alsaqueue.cpp:895
int getId()
Gets the queue&#39;s numeric identifier.
Definition: alsaqueue.cpp:126
void setTimer(const QueueTimer &value)
Applies q QueueTimer object to the queue.
Definition: alsaqueue.cpp:831
QueueTempo * clone()
Copy the current object returning the copied object.
Definition: alsaqueue.cpp:384
bool isLocked()
Returns the locking status of the queue.
Definition: alsaqueue.cpp:153
int getId()
Gets the queue&#39;s numeric identifier.
Definition: alsaqueue.cpp:406
QueueTimer & getTimer()
Gets a QueueTimer object reference.
Definition: alsaqueue.cpp:801
Drumstick common.
Definition: alsaclient.cpp:68
snd_seq_event_t * getHandle()
Gets the handle of the event.
Definition: alsaevent.h:135
void start()
Start the queue.
Definition: alsaqueue.cpp:862
double getClockTime()
Gets the clock time in seconds of the queue.
Definition: alsaqueue.cpp:338
QueueInfo()
Default constructor.
Definition: alsaqueue.cpp:67
void setTickPosition(snd_seq_tick_time_t pos)
Sets the queue position in musical time (ticks).
Definition: alsaqueue.cpp:905
QueueTempo & operator=(const QueueTempo &other)
Assignment operator.
Definition: alsaqueue.cpp:394
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
int getQueueId()
The queue&#39;s numeric identifier.
Definition: alsaqueue.cpp:605
bool isRunning()
Gets the queue&#39;s running state.
Definition: alsaqueue.cpp:329
ALSA Timer identifier container.
Definition: alsatimer.h:95
void setTempo(const QueueTempo &value)
Applies a QueueTempo object to the queue.
Definition: alsaqueue.cpp:821
const unsigned int SKEW_BASE
This is the value for the base skew used in ALSA.
Definition: alsaqueue.cpp:38
void setSkewValue(unsigned int value)
Sets the tempo skew numerator.
Definition: alsaqueue.cpp:466
QueueTempo & getTempo()
Gets a QueueTempo object reference.
Definition: alsaqueue.cpp:791
int getOwner()
Gets the owner&#39;s client id of the queue.
Definition: alsaqueue.cpp:144
QueueTimer & operator=(const QueueTimer &other)
Assignment operator.
Definition: alsaqueue.cpp:593
void setSkewBase(unsigned int value)
Sets the tempo skew base.
Definition: alsaqueue.cpp:478
unsigned int getResolution()
Gets the timer resolution.
Definition: alsaqueue.cpp:640
void setTempoFactor(float value)
Sets the queue&#39;s tempo skew factor.
Definition: alsaqueue.cpp:519
QueueStatus & getStatus()
Gets a QueueStatus object reference.
Definition: alsaqueue.cpp:781
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
QueueStatus()
Default constructor.
Definition: alsaqueue.cpp:216
int getEvents()
Gets the number of queued events.
Definition: alsaqueue.cpp:284
void setType(snd_seq_queue_timer_type_t value)
Sets the timer type.
Definition: alsaqueue.cpp:656
int getUsage()
Gets the queue usage flag.
Definition: alsaqueue.cpp:842
unsigned int getStatusBits()
Gets the running status bits.
Definition: alsaqueue.cpp:302
QueueInfo & operator=(const QueueInfo &other)
Assignment operator.
Definition: alsaqueue.cpp:114
QString getName()
Gets the queue name.
Definition: alsaqueue.cpp:135
const snd_timer_id_t * getId()
Gets the timer identifier record.
Definition: alsaqueue.cpp:631
virtual ~QueueTempo()
Destructor.
Definition: alsaqueue.cpp:375
MidiQueue(MidiClient *seq, QObject *parent=nullptr)
Constructor.
Definition: alsaqueue.cpp:703
Classes managing ALSA Sequencer queues.
Queue status container.
Definition: alsaqueue.h:92
Classes managing ALSA Sequencer events.
int getInfoSize() const
Gets the size of the ALSA queue tempo object.
Definition: alsaqueue.cpp:538
Client management.
Definition: alsaclient.h:218
void setId(snd_timer_id_t *value)
Sets the timer identifier record.
Definition: alsaqueue.cpp:665
void setNominalBPM(float value)
Sets the queue&#39;s nominal tempo in BPM (beats per minute).
Definition: alsaqueue.cpp:529
int getInfoSize() const
Gets the size of the ALSA queue info object.
Definition: alsaqueue.cpp:207
void continueRunning()
Start the queue without resetting the last position.
Definition: alsaqueue.cpp:886
void setName(QString value)
Sets the queue name.
Definition: alsaqueue.cpp:171
#define DRUMSTICK_ALSA_CHECK_ERROR(x)
This macro calls the check error function.
Definition: errorcheck.h:80