Ejemplo n.º 1
0
/// Take beat-bar-tick info from the Jack system, and translate it to a new internal frame position and ticksize.
void JackOutput::relocateBBT()
{
	Preferences* pPref = Preferences::get_instance();

	//wolke if hydrogen is jack time master this is not relevant
	if ( m_transport.m_status != TransportInfo::ROLLING
	  || pPref->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER
	  || ! ( m_JackTransportPos.valid & JackPositionBBT )
	) {
		WARNINGLOG( "Relocate: Call it off" );
		return;
	}

	//WARNINGLOG( "Resyncing!" );
	INFOLOG( "..." );

	Hydrogen * H = Hydrogen::get_instance();
	Song * S = H->getSong();

	float hydrogen_TPB = ( float )( S->__resolution / m_JackTransportPos.beat_type * 4 );

	long bar_ticks = 0;
	//long beat_ticks = 0;
	if ( S->get_mode() == Song::SONG_MODE ) {
		// (Reasonable?) assumption that one pattern is _always_ 1 bar long!
		bar_ticks = H->getTickForPosition( m_JackTransportPos.bar-1  );
		// ignore error NOTE This is wrong -- if loop state is off, transport should just stop ??
		if ( bar_ticks < 0 ) bar_ticks = 0;
	}

	float hydrogen_ticks_to_locate = bar_ticks + ( m_JackTransportPos.beat-1 ) * hydrogen_TPB +
									 m_JackTransportPos.tick * ( hydrogen_TPB / m_JackTransportPos.ticks_per_beat );

	// INFOLOG( QString( "Position from Time Master: BBT [%1,%2,%3]" ) . arg( m_JackTransportPos.bar ) . arg( m_JackTransportPos.beat ) . arg( m_JackTransportPos.tick ) );
	// WARNINGLOG( QString(bbt) + " -- Tx/Beat = "+to_string(m_JackTransportPos.ticks_per_beat)+", Meter "+to_string(m_JackTransportPos.beats_per_bar)+"/"+to_string(m_JackTransportPos.beat_type)+" =>tick " + to_string( hydrogen_ticks_to_locate ) );

	float fNewTickSize = getSampleRate() * 60.0 /  m_transport.m_nBPM / S->__resolution;
	// not S->m_fBPM !??

	if ( fNewTickSize == 0 ) return; // ??!?

	// NOTE this _should_ prevent audioEngine_process_checkBPMChanged in Hydrogen.cpp from recalculating things.
	m_transport.m_nTickSize = fNewTickSize;

	long long nNewFrames = ( long long )( hydrogen_ticks_to_locate * fNewTickSize );

#ifndef JACK_NO_BBT_OFFSET
	if ( m_JackTransportPos.valid & JackBBTFrameOffset )
		nNewFrames += m_JackTransportPos.bbt_offset;
#endif

	m_transport.m_nFrames = nNewFrames;
}
Ejemplo n.º 2
0
void JackAudioDriver::relocateBBT()
{
	Preferences* pPref = Preferences::get_instance();

	// If Hydrogen itself is the JACK timebase master, this
	// function is not relevant.
	if ( m_transport.m_status != TransportInfo::ROLLING
	  || pPref->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER
	  || ! ( m_JackTransportPos.valid & JackPositionBBT )
	) {
		// WARNINGLOG( "Relocate: Call it off" );
		return;
	}

	// WARNINGLOG( "Relocate..." );

	Hydrogen * H = Hydrogen::get_instance();
	Song * S = H->getSong();

	// m_JackTransportPos.beat_type contains the denominator of
	// the time signature and is given in number of ticks per
	// quarter. Thus, hydrogen_TPB contains the number of beats
	// per denominator of the JACK time signature. (Ticks per bar)
	float hydrogen_TPB = ( float )( S->__resolution / m_JackTransportPos.beat_type * 4 );

	long bar_ticks = 0;
	//long beat_ticks = 0;
	if ( S->get_mode() == Song::SONG_MODE ) {
		// m_JackTransportPos.bar accesses the current bar at
		// the transport position. (Reasonable?) assumption
		// that one pattern is _always_ 1 bar long!
		bar_ticks = H->getTickForPosition( m_JackTransportPos.bar-1  );
		// If a tick corresponding to the position of the
		// current bar-1 could not be found, we will use the
		// tick at the very beginning of the song instead.
		if ( bar_ticks < 0 ) bar_ticks = 0;
	}

	// m_JackTransportPos.beat refers to the current beat within a
	// bar, m_JackTransportPos.tick to the current tick within a
	// beat, and m_JackTransportPos.ticks_per_beat to the number
	// of ticks per beat.
	// Using hydrogen_TPB as conversion factor, the relocation
	// position in ticks will be calculated by combining the
	// current bar, beat, and tick.
	float hydrogen_ticks_to_locate = bar_ticks +
		( m_JackTransportPos.beat-1 ) * hydrogen_TPB +
		m_JackTransportPos.tick * ( hydrogen_TPB / m_JackTransportPos.ticks_per_beat );

	INFOLOG( QString( "Position from Timebase Master: BBT [%1,%2,%3]" ).arg( m_JackTransportPos.bar ).arg( m_JackTransportPos.beat ).arg( m_JackTransportPos.tick ) );
	// WARNINGLOG( "Tx/Beat = "+to_string(m_JackTransportPos.ticks_per_beat)+", Meter "+to_string(m_JackTransportPos.beats_per_bar)+"/"+to_string(m_JackTransportPos.beat_type)+" =>tick " + to_string( hydrogen_ticks_to_locate ) );

	// Before calling this function in updateTransportInfo() the
	// speed obtained by the JACK server query was already written
	// to m_transport.m_nBPM. This value can thus be considered
	// clean.
	float fNewTickSize = getSampleRate() * 60.0 /  m_transport.m_nBPM / S->__resolution;

	if ( fNewTickSize == 0 ) return;

	// Note that this will prevent
	// audioEngine_process_checkBPMChanged() in Hydrogen.cpp from
	// recalculating things unless m_transport.m_nBpm and S->__bpm
	// aren't equal.
	m_transport.m_nTickSize = fNewTickSize;

	// New transport position in frames
	long long nNewFrames = ( long long )( hydrogen_ticks_to_locate * fNewTickSize );

#ifndef JACK_NO_BBT_OFFSET
	// m_JackTransportPos.bbt_offset is a frame offset for the BBT
	// fields (the given bar, beat, and tick values actually refer
	// to a time frame_offset frames before the start of the
	// cycle), should be assumed to be 0 if JackBBTFrameOffset is
	// not set. If JackBBTFrameOffset is set and this value is
	// zero, the BBT time refers to the first frame of this
	// cycle. If the value is positive, the BBT time refers to a
	// frame that many frames before the start of the cycle.
	//
	// Due to the if clause in the beginning of the function, the
	// following if clause is true at all times.
	if ( m_JackTransportPos.valid & JackBBTFrameOffset )
		nNewFrames += m_JackTransportPos.bbt_offset;
#endif

	m_transport.m_nFrames = nNewFrames;
}