void ALSADrv_MIDI_SetTempo(int tempo, int division) { double tps; snd_seq_queue_tempo_t * t; int result; if (queueRunning) { snd_seq_stop_queue(seq, seq_queue, NULL); while ((result = snd_seq_drain_output(seq)) > 0) ; if (result < 0) { fprintf(stderr, "ALSA could not drain output: err %d\n", result); } } snd_seq_queue_tempo_alloca(&t); snd_seq_queue_tempo_set_tempo(t, 60000000 / tempo); snd_seq_queue_tempo_set_ppq(t, division); snd_seq_set_queue_tempo(seq, seq_queue, t); tps = ( (double) tempo * (double) division ) / 60.0; threadQueueTicks = (int) ceil(tps / (double) THREAD_QUEUE_INTERVAL); if (queueRunning) { snd_seq_start_queue(seq, seq_queue, NULL); while ((result = snd_seq_drain_output(seq)) > 0) ; if (result < 0) { fprintf(stderr, "ALSA could not drain output: err %d\n", result); } } }
// set the tempo and pulse per quarter note void set_tempo(snd_seq_t *handle, int q) { snd_seq_queue_tempo_t *tempo; snd_seq_queue_tempo_alloca(&tempo); perror("snd_seq_queue_tempo_alloca"); snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM perror("snd_seq_queue_tempo_set_tempo"); snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ perror("snd_seq_queue_tempo_set_ppq"); snd_seq_set_queue_tempo(handle, q, tempo); perror("snd_seq_set_queue_tempo"); }
void mastermidibus::set_ppqn (int ppqn) { #ifdef SEQ64_HAVE_LIBASOUND automutex locker(m_mutex); m_ppqn = ppqn; snd_seq_queue_tempo_t * tempo; snd_seq_queue_tempo_alloca(&tempo); /* allocate tempo struct */ snd_seq_get_queue_tempo(m_alsa_seq, m_queue, tempo); snd_seq_queue_tempo_set_ppq(tempo, m_ppqn); snd_seq_set_queue_tempo(m_alsa_seq, m_queue, tempo); #endif }
MidiAlsaSeq::MidiAlsaSeq() : MidiClient(), m_seqMutex(), m_seqHandle( NULL ), m_queueID( -1 ), m_quit( false ), m_portListUpdateTimer( this ) { int err; if( ( err = snd_seq_open( &m_seqHandle, probeDevice().toLatin1().constData(), SND_SEQ_OPEN_DUPLEX, 0 ) ) < 0 ) { fprintf( stderr, "cannot open sequencer: %s\n", snd_strerror( err ) ); return; } snd_seq_set_client_name( m_seqHandle, "LMMS" ); m_queueID = snd_seq_alloc_queue( m_seqHandle ); snd_seq_queue_tempo_t * tempo; snd_seq_queue_tempo_malloc( &tempo ); snd_seq_queue_tempo_set_tempo( tempo, 6000000 / Engine::getSong()->getTempo() ); snd_seq_queue_tempo_set_ppq( tempo, 16 ); snd_seq_set_queue_tempo( m_seqHandle, m_queueID, tempo ); snd_seq_queue_tempo_free( tempo ); snd_seq_start_queue( m_seqHandle, m_queueID, NULL ); changeQueueTempo( Engine::getSong()->getTempo() ); connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), this, SLOT( changeQueueTempo( bpm_t ) ) ); // initial list-update updatePortList(); connect( &m_portListUpdateTimer, SIGNAL( timeout() ), this, SLOT( updatePortList() ) ); // we check for port-changes every second m_portListUpdateTimer.start( 1000 ); // use a pipe to detect shutdown if( pipe( m_pipe ) == -1 ) { perror( __FILE__ ": pipe" ); } start( QThread::IdlePriority ); }
void MidiQueue::setTempo(double bpm) { const unsigned int tempo = convertBPMToMicroseconds(bpm); snd_seq_queue_tempo_t* queueTempo = nullptr; snd_seq_queue_tempo_alloca(&queueTempo); snd_seq_queue_tempo_set_tempo(queueTempo, tempo); snd_seq_queue_tempo_set_ppq(queueTempo, kPPQN); snd_seq_set_queue_tempo(_sequencer, _id, queueTempo); int result = snd_seq_drain_output(_sequencer); if (result < 0) { std::cerr << "MidiQueue::setTempo error:" << snd_strerror(result) << std::endl; } }
/* * Set the initial time base and tempo. * resolution - Ticks per quarter note or realtime resolution * tempo - Beats per minute * realtime - True if absolute time base */ int SeqContext::seq_init_tempo(int resolution, int tempo, int realtime) { snd_seq_queue_tempo_t *qtempo; int ret; snd_seq_queue_tempo_alloca(&qtempo); memset(qtempo, 0, snd_seq_queue_tempo_sizeof()); snd_seq_queue_tempo_set_ppq(qtempo, resolution); snd_seq_queue_tempo_set_tempo(qtempo, 60*1000000/tempo); ret = snd_seq_set_queue_tempo(handle, queue, qtempo); if( verbose ) fprintf(stderr,"seq queue tempo: res=%d, tempo=%d, realtime=%d\n", resolution, tempo, realtime ); return ret; }
void mastermidibus::set_ppqn (int a_ppqn) { #ifdef HAVE_LIBASOUND automutex locker(m_mutex); snd_seq_queue_tempo_t * tempo; snd_seq_queue_tempo_alloca(&tempo); /* allocate tempo struct */ /* * Fill the tempo structure with the current tempo information. Then * set the ppqn value. Finally, give the tempo structure to the ALSA * queue. */ m_ppqn = a_ppqn; snd_seq_get_queue_tempo(m_alsa_seq, m_queue, tempo); snd_seq_queue_tempo_set_ppq(tempo, m_ppqn); snd_seq_set_queue_tempo(m_alsa_seq, m_queue, tempo); #endif }
void mastermidibus::set_ppqn( int a_ppqn ) { lock(); m_ppqn = a_ppqn; /* allocate tempo struct */ snd_seq_queue_tempo_t *tempo; snd_seq_queue_tempo_alloca( &tempo ); /* fill tempo struct with current tempo info */ snd_seq_get_queue_tempo( m_alsa_seq, m_queue, tempo ); /* set ppqn */ snd_seq_queue_tempo_set_ppq( tempo, m_ppqn ); /* give tempo struct to the queue */ snd_seq_set_queue_tempo( m_alsa_seq, m_queue, tempo ); unlock(); }
/* queue is shared by both input and output, reference counted */ static PmError alsa_use_queue(void) { if (queue_used == 0) { snd_seq_queue_tempo_t *tempo; queue = snd_seq_alloc_queue(seq); if (queue < 0) { pm_hosterror = queue; return pmHostError; } snd_seq_queue_tempo_alloca(&tempo); snd_seq_queue_tempo_set_tempo(tempo, 480000); snd_seq_queue_tempo_set_ppq(tempo, 480); pm_hosterror = snd_seq_set_queue_tempo(seq, queue, tempo); if (pm_hosterror < 0) return pmHostError; snd_seq_start_queue(seq, queue, NULL); snd_seq_drain_output(seq); } ++queue_used; return pmNoError; }