Skip to content

Commit

Permalink
Make ppqPos in VST sync sample accurate
Browse files Browse the repository at this point in the history
  • Loading branch information
DomClark authored and zonkmachine committed Dec 7, 2018
1 parent 3a94ed3 commit 614bca7
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 19 deletions.
4 changes: 2 additions & 2 deletions include/VstSyncController.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class VstSyncController : public QObject
VstSyncController();
~VstSyncController();

void setAbsolutePosition( int ticks );
void setAbsolutePosition( double ticks );

void setPlaybackState( bool enabled )
{
Expand Down Expand Up @@ -77,7 +77,7 @@ private slots:
struct VstSyncData
{
bool isPlaying;
float ppqPos;
double ppqPos;
int timeSigNumer;
int timeSigDenom;
bool isCycle;
Expand Down
2 changes: 1 addition & 1 deletion include/VstSyncData.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
struct VstSyncData
{
bool isPlaying;
float ppqPos;
double ppqPos;
int timeSigNumer;
int timeSigDenom;
bool isCycle;
Expand Down
22 changes: 16 additions & 6 deletions plugins/vst_base/RemoteVstPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ class RemoteVstPlugin : public RemotePluginClient
// host to plugin synchronisation data structure
struct in
{
float lastppqPos;
float m_Timestamp;
double lastppqPos;
double m_Timestamp;
int32_t m_lastFlags;
} ;

Expand Down Expand Up @@ -1605,10 +1605,20 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
}
else if( __plugin->m_vstSyncData->isPlaying )
{
__plugin->m_in->lastppqPos += (
__plugin->m_vstSyncData->hasSHM ?
__plugin->m_vstSyncData->m_bpm :
__plugin->m_bpm ) / (float)10340;
if( __plugin->m_vstSyncData->hasSHM )
{
__plugin->m_in->lastppqPos +=
__plugin->m_vstSyncData->m_bpm / 60.0
* __plugin->m_vstSyncData->m_bufferSize
/ __plugin->m_vstSyncData->m_sampleRate;
}
else
{
__plugin->m_in->lastppqPos +=
__plugin->m_bpm / 60.0
* __plugin->bufferSize()
/ __plugin->sampleRate();
}
_timeInfo.ppqPos = __plugin->m_in->lastppqPos;
}
// _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos;
Expand Down
21 changes: 14 additions & 7 deletions src/core/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ void Song::processNextBuffer()
m_playPos[m_playMode].setTicks(
tl->loopBegin().getTicks() );

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

emit updateSampleTracks();
Expand All @@ -293,8 +291,6 @@ void Song::processNextBuffer()
int ticks = m_playPos[m_playMode].getTicks() +
( int )( currentFrame / framesPerTick );

m_vstSyncController.setAbsolutePosition( ticks );

// did we play a whole tact?
if( ticks >= MidiTime::ticksPerTact() )
{
Expand Down Expand Up @@ -332,7 +328,6 @@ void Song::processNextBuffer()
m_elapsedMilliSeconds =
( ticks * 60 * 1000 / 48 ) / getTempo();

m_vstSyncController.setAbsolutePosition( ticks );
m_vstSyncController.setPlaybackJumped( true );
}
}
Expand All @@ -354,7 +349,6 @@ void Song::processNextBuffer()
m_elapsedMilliSeconds =
( ticks * 60 * 1000 / 48 ) / getTempo();

m_vstSyncController.setAbsolutePosition( ticks );
m_vstSyncController.setPlaybackJumped( true );

emit updateSampleTracks();
Expand All @@ -369,6 +363,16 @@ void Song::processNextBuffer()
m_playPos[m_playMode].setCurrentFrame( currentFrame );
}

if( framesPlayed == 0 )
{
// update VST sync position after we've corrected frame/
// tick count but before actually playing any frames
m_vstSyncController.setAbsolutePosition(
m_playPos[m_playMode].getTicks()
+ m_playPos[m_playMode].currentFrame()
/ (double) framesPerTick );
}

f_cnt_t framesToPlay =
Engine::mixer()->framesPerPeriod() - framesPlayed;

Expand Down Expand Up @@ -716,7 +720,10 @@ void Song::stop()
m_playPos[m_playMode].setCurrentFrame( 0 );

m_vstSyncController.setPlaybackState( m_exporting );
m_vstSyncController.setAbsolutePosition( m_playPos[m_playMode].getTicks() );
m_vstSyncController.setAbsolutePosition(
m_playPos[m_playMode].getTicks()
+ m_playPos[m_playMode].currentFrame()
/ (double) Engine::framesPerTick() );

// remove all note-play-handles that are active
Engine::mixer()->clear();
Expand Down
6 changes: 3 additions & 3 deletions src/core/VstSyncController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@ VstSyncController::~VstSyncController()



void VstSyncController::setAbsolutePosition( int ticks )
void VstSyncController::setAbsolutePosition( double ticks )
{
#ifdef VST_SNC_LATENCY
m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ) - m_syncData->m_latency;
m_syncData->ppqPos = ( ( ticks + 0 ) / 48.0 ) - m_syncData->m_latency;
#else
m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 );
m_syncData->ppqPos = ( ( ticks + 0 ) / 48.0 );
#endif
}

Expand Down

0 comments on commit 614bca7

Please sign in to comment.