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 2c5cda5
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 4 deletions.
@@ -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
Copy link
Contributor

@falkTX falkTX commented on 2c5cda5 Sep 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.