Skip to content
Permalink
Browse files

Fix kVstTransportChanged flag usage in VST sync

Changed according to feedback from AudioBlast. The flag used to be set most of the time, now it is only set when playback starts/stops, looping is toggled, or playback jumps around.
  • Loading branch information
DomClark authored and PhysSong committed Sep 11, 2018
1 parent cc2ae66 commit 2c5cda563b4985659a7408008915f0e4e0f85edb
@@ -87,10 +87,19 @@ class EXPORT Song : public TrackContainer
{
return m_currentFrame;
}
inline void setJumped( const bool jumped )
{
m_jumped = jumped;
}
inline bool jumped() const
{
return m_jumped;
}
TimeLineWidget * m_timeLine;

private:
float m_currentFrame;
bool m_jumped;

} ;

@@ -61,6 +61,11 @@ class VstSyncController : public QObject
m_syncData->isCycle = false;
}

void setPlaybackJumped( bool jumped )
{
m_syncData->m_playbackJumped = jumped;
}

void update();


@@ -79,6 +84,7 @@ private slots:
bool hasSHM;
float cycleStart;
float cycleEnd;
bool m_playbackJumped;
int m_bufferSize;
int m_sampleRate;
int m_bpm;
@@ -49,6 +49,7 @@ struct VstSyncData
bool hasSHM;
float cycleStart;
float cycleEnd;
bool m_playbackJumped;
int m_bufferSize;
int m_sampleRate;
int m_bpm;
@@ -396,6 +396,7 @@ class RemoteVstPlugin : public RemotePluginClient
{
float lastppqPos;
float m_Timestamp;
int32_t m_lastFlags;
} ;

in * m_in;
@@ -478,12 +479,14 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) :
m_vstSyncData->ppqPos = 0;
m_vstSyncData->isCycle = false;
m_vstSyncData->hasSHM = false;
m_vstSyncData->m_playbackJumped = false;
m_vstSyncData->m_sampleRate = sampleRate();
}

m_in = ( in* ) new char[ sizeof( in ) ];
m_in->lastppqPos = 0;
m_in->m_Timestamp = -1;
m_in->m_lastFlags = 0;

// process until we have loaded the plugin
while( 1 )
@@ -1588,7 +1591,6 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
__plugin->m_in->m_Timestamp )
{
_timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos;
_timeInfo.flags |= kVstTransportChanged;
__plugin->m_in->lastppqPos = __plugin->m_vstSyncData->ppqPos;
__plugin->m_in->m_Timestamp = __plugin->m_vstSyncData->ppqPos;
}
@@ -1615,6 +1617,14 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,

_timeInfo.flags |= kVstBarsValid;

if( ( _timeInfo.flags & ( kVstTransportPlaying | kVstTransportCycleActive ) ) !=
( __plugin->m_in->m_lastFlags & ( kVstTransportPlaying | kVstTransportCycleActive ) )
|| __plugin->m_vstSyncData->m_playbackJumped )
{
_timeInfo.flags |= kVstTransportChanged;
}
__plugin->m_in->m_lastFlags = _timeInfo.flags;

#ifdef LMMS_BUILD_WIN64
return (long long) &_timeInfo;
#else
@@ -193,6 +193,8 @@ void Song::savePos()

void Song::processNextBuffer()
{
m_vstSyncController.setPlaybackJumped( false );

// if not playing, nothing to do
if( m_playing == false )
{
@@ -262,10 +264,21 @@ void Song::processNextBuffer()
( tl->loopBegin().getTicks() * 60 * 1000 / 48 ) / getTempo();
m_playPos[m_playMode].setTicks(
tl->loopBegin().getTicks() );

m_vstSyncController.setAbsolutePosition(
tl->loopBegin().getTicks() );
m_vstSyncController.setPlaybackJumped( true );

emit updateSampleTracks();
}
}

if( m_playPos[m_playMode].jumped() )
{
m_vstSyncController.setPlaybackJumped( true );
m_playPos[m_playMode].setJumped( false );
}

f_cnt_t framesPlayed = 0;
const float framesPerTick = Engine::framesPerTick();

@@ -320,6 +333,7 @@ void Song::processNextBuffer()
( ticks * 60 * 1000 / 48 ) / getTempo();

m_vstSyncController.setAbsolutePosition( ticks );
m_vstSyncController.setPlaybackJumped( true );
}
}
m_playPos[m_playMode].setTicks( ticks );
@@ -334,11 +348,14 @@ void Song::processNextBuffer()
// beginning of the range
if( m_playPos[m_playMode] >= tl->loopEnd() )
{
m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() );
ticks = tl->loopBegin().getTicks();
m_playPos[m_playMode].setTicks( ticks );

m_elapsedMilliSeconds =
( ( tl->loopBegin().getTicks() ) * 60 * 1000 / 48 ) /
getTempo();
( ticks * 60 * 1000 / 48 ) / getTempo();

m_vstSyncController.setAbsolutePosition( ticks );
m_vstSyncController.setPlaybackJumped( true );
}
else if( m_playPos[m_playMode] == tl->loopEnd() - 1 )
{
@@ -609,6 +626,7 @@ void Song::setPlayPos( tick_t ticks, PlayModes playMode )
getTempo() );
m_playPos[playMode].setTicks( ticks );
m_playPos[playMode].setCurrentFrame( 0.0f );
m_playPos[playMode].setJumped( true );

// send a signal if playposition changes during playback
if( isPlaying() )
@@ -375,6 +375,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event )
( 60 * 1000 / 48 ) ) /
Engine::getSong()->getTempo() );
m_pos.setCurrentFrame( 0 );
m_pos.setJumped( true );
updatePosition();
positionMarkerMoved();
break;

2 comments on commit 2c5cda5

@falkTX

This comment has been minimized.

Copy link
Contributor

@falkTX falkTX replied Sep 12, 2018

I just want to say thank you @DomClark for this commit.
I was doing the same thing in Carla...
This entire time FLStudio in Carla failed to sync properly. not anymore! 🏇

@DomClark

This comment has been minimized.

Copy link
Member Author

@DomClark DomClark replied Sep 18, 2018

You're welcome! I'd like to say thank you to AudioBlast as well for taking the time to let us know what was wrong with our code here and how it should be correctly implemented.

Please sign in to comment.
You can’t perform that action at this time.