void JVlibForm::on_System_PauseMidi_button_toggled(bool checked) { unsigned int current_tick; if (checked) { stopPlayer(); if (seqTimer->isActive()) { disconnect(JVlibForm::seqTimer, SIGNAL(timeout()), this, SLOT(tickDisplay())); seqTimer->stop(); } snd_seq_get_queue_status(seq, queue, status); current_tick = snd_seq_queue_status_get_tick_time(status); snd_seq_stop_queue(seq,queue,NULL); snd_seq_drain_output(seq); stop_sound(); disconnect_port(); System_PauseMidi_button->setText("Resume"); } else { connect_port(); snd_seq_continue_queue(seq, queue, NULL); snd_seq_drain_output(seq); snd_seq_get_queue_status(seq, queue, status); current_tick = snd_seq_queue_status_get_tick_time(status); System_PauseMidi_button->setText("Pause"); connect(JVlibForm::seqTimer, SIGNAL(timeout()), this, SLOT(tickDisplay())); startPlayer(current_tick); seqTimer->start(100); } } // end on_System_PauseMidi_button_toggled
/* * =================== Input/output port handling ========================= */ static void set_process_info(struct process_info *info, alsa_seqmidi_t *self, int dir, jack_nframes_t nframes) { const snd_seq_real_time_t* alsa_time; snd_seq_queue_status_t *status; snd_seq_queue_status_alloca(&status); info->dir = dir; info->period_start = jack_last_frame_time(self->jack); info->nframes = nframes; info->sample_rate = jack_get_sample_rate(self->jack); info->cur_frames = jack_frame_time(self->jack); // immediately get alsa'a real time (uhh, why everybody has their own 'real' time) snd_seq_get_queue_status(self->seq, self->queue, status); alsa_time = snd_seq_queue_status_get_real_time(status); info->alsa_time = alsa_time->tv_sec * NSEC_PER_SEC + alsa_time->tv_nsec; if (info->period_start + info->nframes < info->cur_frames) { int periods_lost = (info->cur_frames - info->period_start) / info->nframes; info->period_start += periods_lost * info->nframes; debug_log("xrun detected: %d periods lost\n", periods_lost); } }
void JVlibForm::on_System_MIDI_progressBar_sliderReleased() { if (!System_PauseMidi_button->isChecked()) return; snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_direct(&ev); snd_seq_get_queue_status(seq, queue, status); // reset queue position snd_seq_ev_is_tick(&ev); snd_seq_ev_set_queue_pos_tick(&ev, queue, 0); snd_seq_event_output(seq, &ev); snd_seq_drain_output(seq); // scan the event queue for the closest tick >= 'x' int y = 0; for (std::vector<event>::iterator Event=all_events.begin(); Event!=all_events.end(); ++Event) { if (static_cast<int>(Event->tick) >= System_MIDI_progressBar->sliderPosition()) { ev.time.tick = Event->tick; event_num = y; break; } y++; } ev.dest.client = SND_SEQ_CLIENT_SYSTEM; ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER; snd_seq_ev_set_queue_pos_tick(&ev, queue, ev.time.tick); snd_seq_event_output(seq, &ev); snd_seq_drain_output(seq); snd_seq_real_time_t *new_time = new snd_seq_real_time_t; double x = static_cast<double>(ev.time.tick)/all_events.back().tick; new_time->tv_sec = (x*song_length_seconds); new_time->tv_nsec = 0; snd_seq_ev_set_queue_pos_real(&ev, queue, new_time); MIDI_time_display->setText(QString::number(static_cast<int>(new_time->tv_sec)/60).rightJustified(2,'0')+ ":"+QString::number(static_cast<int>(new_time->tv_sec)%60).rightJustified(2,'0')); if (System_PauseMidi_button->isChecked()) return; } // end on_System_MIDI_progressBar_sliderReleased
static guint32 get_current_tick (void) { snd_seq_queue_status_t *status; snd_seq_queue_status_alloca (&status); snd_seq_get_queue_status (seq, queue_id, status); return snd_seq_queue_status_get_tick_time (status); }
static unsigned int get_tick(void) { snd_seq_queue_status_t * status; int result; snd_seq_queue_status_alloca(&status); result = snd_seq_get_queue_status(seq, seq_queue, status); if (result < 0) { fprintf(stderr, "ALSA snd_seq_get_queue_status err %d\n", result); return 0; } return (unsigned int) snd_seq_queue_status_get_tick_time(status); }
static PyObject * alsaseq_status(PyObject *self /* Not used */, PyObject *args) { snd_seq_queue_status_t *queue_status; int running, events; const snd_seq_real_time_t *current_time; if (!PyArg_ParseTuple(args, "" )) return NULL; snd_seq_queue_status_malloc( &queue_status ); snd_seq_get_queue_status( seq_handle, queue_id, queue_status ); current_time = snd_seq_queue_status_get_real_time( queue_status ); running = snd_seq_queue_status_get_status( queue_status ); events = snd_seq_queue_status_get_events( queue_status ); snd_seq_queue_status_free( queue_status ); return Py_BuildValue( "(i(ii),i)", running, current_time->tv_sec, current_time->tv_nsec, events ); }
void JVlibForm::tickDisplay() { // set timestamp display snd_seq_get_queue_status(seq, queue, status); unsigned int current_tick = snd_seq_queue_status_get_tick_time(status); System_MIDI_progressBar->blockSignals(true); System_MIDI_progressBar->setValue(current_tick); System_MIDI_progressBar->blockSignals(false); // set time label double new_seconds = static_cast<double>(current_tick)/all_events.back().tick; new_seconds *= song_length_seconds; MIDI_time_display->setText(QString::number(static_cast<int>(new_seconds)/60).rightJustified(2,'0')+ ":"+QString::number(static_cast<int>(new_seconds)%60).rightJustified(2,'0')); if (current_tick >= all_events.back().tick) { // end of song sleep(1); System_PlayMidi_button->setChecked(false); return; } while (all_events[event_num].tick<current_tick) event_num++; } // end tickDisplay
static PyObject * alsaseq_status(PyObject *self /* Not used */, PyObject *args) { snd_seq_queue_status_t *queue_status; int running, events; const snd_seq_real_time_t *current_time; if (!PyArg_ParseTuple(args, "" )) return NULL; if (!seq_handle) { PyErr_SetString(PyExc_RuntimeError, "Must initialize module with alsaseq.client() before using it"); return NULL; } snd_seq_queue_status_malloc( &queue_status ); snd_seq_get_queue_status( seq_handle, queue_id, queue_status ); current_time = snd_seq_queue_status_get_real_time( queue_status ); running = snd_seq_queue_status_get_status( queue_status ); events = snd_seq_queue_status_get_events( queue_status ); snd_seq_queue_status_free( queue_status ); return Py_BuildValue( "(i(ii),i)", running, current_time->tv_sec, current_time->tv_nsec, events ); }