void midibus::continue_from( long a_tick ) { /* tell the device that we are going to start at a certain position */ long pp16th = (c_ppqn / 4); long leftover = ( a_tick % pp16th ); long beats = ( a_tick / pp16th ); long starting_tick = a_tick - leftover; /* was there anything left?, then wait for next beat (16th note) to start clocking */ if ( leftover > 0) { starting_tick += pp16th; } //printf ( "continue_from leftover[%ld] starting_tick[%ld]\n", leftover, starting_tick ); m_lasttick = starting_tick - 1; if ( m_clock_type != e_clock_off ) { //printf( "control value %ld\n", beats); snd_seq_event_t evc; snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_CONTINUE; evc.type = SND_SEQ_EVENT_SONGPOS; evc.data.control.value = beats; snd_seq_ev_set_fixed( &ev ); snd_seq_ev_set_fixed( &evc ); snd_seq_ev_set_priority( &ev, 1 ); snd_seq_ev_set_priority( &evc, 1 ); /* set source */ snd_seq_ev_set_source(&evc, m_local_addr_port ); snd_seq_ev_set_subs(&evc); snd_seq_ev_set_source(&ev, m_local_addr_port ); snd_seq_ev_set_subs(&ev); // its immediate snd_seq_ev_set_direct( &ev ); snd_seq_ev_set_direct( &evc ); /* pump it into the queue */ snd_seq_event_output(m_seq, &evc); flush(); snd_seq_event_output(m_seq, &ev); } }
void midibus::stop() { m_lasttick = -1; if ( m_clock_type != e_clock_off ){ snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_STOP; snd_seq_ev_set_fixed( &ev ); snd_seq_ev_set_priority( &ev, 1 ); /* set source */ snd_seq_ev_set_source(&ev, m_local_addr_port ); snd_seq_ev_set_subs(&ev); // its immediate snd_seq_ev_set_direct( &ev ); /* pump it into the queue */ snd_seq_event_output(m_seq, &ev); } }
void midibus::clock (midipulse tick) { #ifdef SEQ64_HAVE_LIBASOUND automutex locker(m_mutex); if (m_clock_type != e_clock_off) { bool done = m_lasttick >= tick; int ct = clock_ticks_from_ppqn(m_ppqn); /* ppqn / 24 */ while (! done) { ++m_lasttick; done = m_lasttick >= tick; if ((m_lasttick % ct) == 0) /* tick time? */ { /* * Set the event tag to 127 so the sequences won't remove it. */ snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_CLOCK; ev.tag = 127; snd_seq_ev_set_fixed(&ev); snd_seq_ev_set_priority(&ev, 1); snd_seq_ev_set_source(&ev, m_local_addr_port); /* set source */ snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* it's immediate */ snd_seq_event_output(m_seq, &ev); /* pump it into queue */ } } flush(); /* and send out */ } #endif // SEQ64_HAVE_LIBASOUND }
void midibus::continue_from (midipulse tick) { #ifdef SEQ64_HAVE_LIBASOUND /* * Tell the device that we are going to start at a certain position. */ midipulse pp16th = m_ppqn / 4; midipulse leftover = tick % pp16th; long beats = tick / pp16th; midipulse starting_tick = tick - leftover; /* * Was there anything left? Then wait for next beat (16th note) to * start clocking. */ if (leftover > 0) starting_tick += pp16th; m_lasttick = starting_tick - 1; if (m_clock_type != e_clock_off) { snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_CONTINUE; snd_seq_event_t evc; evc.type = SND_SEQ_EVENT_SONGPOS; evc.data.control.value = beats; snd_seq_ev_set_fixed(&ev); snd_seq_ev_set_fixed(&evc); snd_seq_ev_set_priority(&ev, 1); snd_seq_ev_set_priority(&evc, 1); snd_seq_ev_set_source(&evc, m_local_addr_port); /* set the source */ snd_seq_ev_set_subs(&evc); snd_seq_ev_set_source(&ev, m_local_addr_port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* it's immediate */ snd_seq_ev_set_direct(&evc); snd_seq_event_output(m_seq, &evc); /* pump into queue */ flush(); snd_seq_event_output(m_seq, &ev); } #endif // SEQ64_HAVE_LIBASOUND }
// generates midi clock void midibus::clock( long a_tick ) { lock(); if ( m_clock_type != e_clock_off ){ bool done = false; long uptotick = a_tick; if ( m_lasttick >= uptotick ) done = true; while ( !done ){ m_lasttick++; if ( m_lasttick >= uptotick ) done = true; /* tick time? */ if ( m_lasttick % ( c_ppqn / 24 ) == 0 ){ snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_CLOCK; /* set tag to 127 so the sequences wont remove it */ ev.tag = 127; snd_seq_ev_set_fixed( &ev ); snd_seq_ev_set_priority( &ev, 1 ); /* set source */ snd_seq_ev_set_source(&ev, m_local_addr_port ); snd_seq_ev_set_subs(&ev); // its immediate snd_seq_ev_set_direct( &ev ); /* pump it into the queue */ snd_seq_event_output(m_seq, &ev); } } /* and send out */ flush(); } unlock(); }
void midibus::stop () { #ifdef SEQ64_HAVE_LIBASOUND m_lasttick = -1; if (m_clock_type != e_clock_off) { snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_STOP; snd_seq_ev_set_fixed(&ev); snd_seq_ev_set_priority(&ev, 1); snd_seq_ev_set_source(&ev, m_local_addr_port); /* set the source */ snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* it's immediate */ snd_seq_event_output(m_seq, &ev); /* pump into queue */ } #endif // SEQ64_HAVE_LIBASOUND }
/* takes an native event, encodes to alsa event, puts it in the queue */ void midibus::sysex( event *a_e24 ) { lock(); snd_seq_event_t ev; /* clear event */ snd_seq_ev_clear( &ev ); snd_seq_ev_set_priority( &ev, 1 ); /* set source */ snd_seq_ev_set_source(&ev, m_local_addr_port ); snd_seq_ev_set_subs(&ev); // its immediate snd_seq_ev_set_direct( &ev ); unsigned char *data = a_e24->get_sysex(); long data_size = a_e24->get_size(); for( long offset = 0; offset < data_size; offset += c_midibus_sysex_chunk ){ long data_left = data_size - offset; snd_seq_ev_set_sysex( &ev, min( data_left, c_midibus_sysex_chunk), &data[offset] ); /* pump it into the queue */ snd_seq_event_output_direct(m_seq, &ev); usleep(80000); flush(); } unlock(); }
void midibus::sysex (event * e24) { #ifdef SEQ64_HAVE_LIBASOUND automutex locker(m_mutex); snd_seq_event_t ev; snd_seq_ev_clear(&ev); /* clear event */ snd_seq_ev_set_priority(&ev, 1); snd_seq_ev_set_source(&ev, m_local_addr_port); /* set source */ snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* it's immediate */ /* * Replaced by a vector of midibytes: * * midibyte * data = e24->get_sysex(); * * This is a bit tricky, and relies on the standard property of * std::vector where all n elements of the vector are guaranteed to be * stored contiguously (in order to be accessible via random-access * iterators). */ event::SysexContainer & data = e24->get_sysex(); int data_size = e24->get_sysex_size(); for (int offset = 0; offset < data_size; offset += c_midibus_sysex_chunk) { int data_left = data_size - offset; snd_seq_ev_set_sysex ( &ev, min(data_left, c_midibus_sysex_chunk), &data[offset] ); snd_seq_event_output_direct(m_seq, &ev); /* pump into queue */ usleep(SEQ64_USLEEP_US); flush(); } #endif // SEQ64_HAVE_LIBASOUND }
void midibus::clock (long a_tick) { #ifdef HAVE_LIBASOUND automutex locker(m_mutex); if (m_clock_type != e_clock_off) { bool done = false; if (m_lasttick >= a_tick) done = true; while (!done) { m_lasttick++; if (m_lasttick >= a_tick) done = true; if (m_lasttick % (c_ppqn / 24) == 0) /* tick time? */ { /* * Set the event tag to 127 so the sequences won't remove it. */ snd_seq_event_t ev; ev.type = SND_SEQ_EVENT_CLOCK; ev.tag = 127; snd_seq_ev_set_fixed(&ev); snd_seq_ev_set_priority(&ev, 1); snd_seq_ev_set_source(&ev, m_local_addr_port); /* set source */ snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* it's immediate */ snd_seq_event_output(m_seq, &ev); /* pump it into queue */ } } flush(); /* and send out */ } #endif // HAVE_LIBASOUND }