void JackOutput::jack_timebase_callback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg) { JackOutput *me = static_cast<JackOutput*>(arg); if (! me) return; Hydrogen * H = Hydrogen::get_instance(); Song* S = H->getSong(); if ( ! S ) return; unsigned long PlayTick = ( pos->frame - me->bbt_frame_offset ) / me->m_transport.m_nTickSize; pos->bar = H->getPosForTick ( PlayTick ); double TPB = H->getTickForHumanPosition( pos->bar ); if ( TPB < 1 ) return; /* We'll cheat there is ticks_per_beat * 4 in bar so every Hydrogen tick will be multipled by 4 ticks */ pos->ticks_per_beat = TPB; pos->valid = JackPositionBBT; pos->beats_per_bar = TPB / 48; pos->beat_type = 4.0; pos->beats_per_minute = H->getTimelineBpm ( pos->bar ); pos->bar++; // Probably there will never be an offset, cause we are the master ;-) #ifndef JACK_NO_BBT_OFFSET pos->valid = static_cast<jack_position_bits_t> ( pos->valid | JackBBTFrameOffset ); pos->bbt_offset = 0; #endif if (H->getHumantimeFrames() < 1) { pos->beat = 1; pos->tick = 0; pos->bar_start_tick = 0; } else { /* how many ticks elpased from last bar ( where bar == pattern ) */ int32_t TicksFromBar = ( PlayTick % (int32_t) pos->ticks_per_beat ) * 4; pos->bar_start_tick = PlayTick - TicksFromBar; pos->beat = TicksFromBar / pos->ticks_per_beat; pos->beat++; pos->tick = TicksFromBar % (int32_t) pos->ticks_per_beat; #if 0 // printf ( "\e[0K\rBar %d, Beat %d, Tick %d, BPB %g, BarStartTick %g", printf ( "Bar %d, Beat %d, Tick %d, BPB %g, BarStartTick %g\n", pos->bar, pos->beat,pos->tick, pos->beats_per_bar, pos->bar_start_tick ); #endif } }