VST to host sync

This patch should bring VST to host synchronization for LMMS.
 (e.g. for plugins like dBlue Glitch, TAL Filters).

Synchronization is done via shared memory, missing song time
positions are reccalculated and added to PPQ position sync values
(SHM - common input interface for sync of all VST plugins)
This commit is contained in:
Mike Choi
2013-02-07 21:54:06 +01:00
committed by Tobias Doerffel
parent 7682bc6ef9
commit 0ef2997ece
8 changed files with 475 additions and 25 deletions

View File

@@ -27,6 +27,7 @@
#include "export.h"
#include "midi.h"
#include "VST_sync_shm.h"
#include <vector>
#include <cstdio>
@@ -811,7 +812,9 @@ class RemotePluginClient : public RemotePluginBase
public:
RemotePluginClient( key_t _shm_in, key_t _shm_out );
virtual ~RemotePluginClient();
#ifdef USE_QT_SHMEM
sncVST * getQtVSTshm();
#endif
virtual bool processMessage( const message & _m );
virtual void process( const sampleFrame * _in_buf,
@@ -879,7 +882,9 @@ private:
#ifdef USE_QT_SHMEM
QSharedMemory m_shmObj;
QSharedMemory m_shmQtID;
#endif
sncVST * m_SncVSTplug;
float * m_shm;
int m_inputCount;
@@ -1007,13 +1012,60 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) :
RemotePluginBase( new shmFifo( _shm_in ), new shmFifo( _shm_out ) ),
#ifdef USE_QT_SHMEM
m_shmObj(),
m_shmQtID( "/usr/bin/lmms" ),
#endif
m_SncVSTplug( NULL ),
m_shm( NULL ),
m_inputCount( 0 ),
m_outputCount( 0 ),
m_sampleRate( 44100 ),
m_bufferSize( 0 )
{
#ifdef USE_QT_SHMEM
if( m_shmQtID.attach( QSharedMemory::ReadOnly ) )
{
m_SncVSTplug = (sncVST *) m_shmQtID.data();
m_bufferSize = m_SncVSTplug->m_bufferSize;
m_sampleRate = m_SncVSTplug->m_sampleRate;
return;
}
#else
key_t key;
int m_shmID;
if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 )
{
perror( "RemotePluginClient::ftok" );
}
else
{ // connect to shared memory segment
if( ( m_shmID = shmget( key, 0, 0 ) ) == -1 )
{
perror( "RemotePluginClient::shmget" );
}
else
{ // attach segment
m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0);
if( m_SncVSTplug == (sncVST *)( -1 ) )
{
perror( "RemotePluginClient::shmat" );
}
else
{
m_bufferSize = m_SncVSTplug->m_bufferSize;
m_sampleRate = m_SncVSTplug->m_sampleRate;
// detach segment
if( shmdt(m_SncVSTplug) == -1 )
{
perror("RemotePluginClient::shmdt");
}
return;
}
}
}
#endif
// if attaching shared memory fails
sendMessage( IdSampleRateInformation );
sendMessage( IdBufferSizeInformation );
}
@@ -1023,6 +1075,9 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) :
RemotePluginClient::~RemotePluginClient()
{
#ifdef USE_QT_SHMEM
m_shmQtID.detach();
#endif
sendMessage( IdQuit );
#ifndef USE_QT_SHMEM
@@ -1032,6 +1087,14 @@ RemotePluginClient::~RemotePluginClient()
#ifdef USE_QT_SHMEM
sncVST * RemotePluginClient::getQtVSTshm()
{
return m_SncVSTplug;
}
#endif
bool RemotePluginClient::processMessage( const message & _m )
{

58
include/VST_sync_shm.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* VST_sync_shm.h - type declarations needed for VST to lmms host sync
*
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _VST_SYNC_SHM_H
#define _VST_SYNC_SHM_H
// VST sync frequency (in ms), how often will be VST plugin synced
// keep it power of two if possible (not used by now)
//#define VST_SNC_TIMER 1
// When defined, latency should be subtracted from song PPQ position
//#define VST_SNC_LATENCY
// define file for ftok as shared memory shmget key
#define VST_SNC_SHM_KEY_FILE "/dev/null"
//#define VST_SNC_SHM_RND_KEY 3561653564469
struct sncVST
{
bool isPlayin;
double ppqPos;
int timeSigNumer;
int timeSigDenom;
bool isCycle;
bool hasSHM;
double cycleStart;
double cycleEnd;
int m_bufferSize;
int m_sampleRate;
int m_bpm;
#ifdef VST_SNC_LATENCY
double m_latency;
#endif
} ;
#endif

View File

@@ -114,8 +114,14 @@ const int kEffectMagic = CCONST( 'V', 's', 't', 'P' );
const int kVstLangEnglish = 1;
const int kVstMidiType = 1;
const int kVstParameterUsesFloatStep = 1 << 2;
const int kVstPpqPosValid = 1 << 9;
const int kVstTempoValid = 1 << 10;
const int kVstBarsValid = 1 << 11;
const int kVstCyclePosValid = 1 << 12;
const int kVstTimeSigValid = 1 << 13;
const int kVstTransportPlaying = 1 << 1;
const int kVstTransportCycleActive = 1 << 2;
const int kVstTransportChanged = 1;
class RemoteVstPlugin;
@@ -267,12 +273,18 @@ public:
double samplePos;
// 08
double sampleRate;
// unconfirmed 10 18
char empty1[8 + 8];
// unconfirmed 10
char empty1[8];
// 18
double ppqPos;
// 20?
double tempo;
// unconfirmed 28 30 38
char empty2[8 + 8 + 8];
// 28
double barStartPos;
// 30?
double cycleStartPos;
// 38?
double cycleEndPos;
// 40?
int timeSigNumerator;
// 44?

View File

@@ -108,6 +108,7 @@ private slots:
void toggleAutoSave( bool _enabled );
void toggleOneInstrumentTrackWindow( bool _enabled );
void toggleCompactTrackButtons( bool _enabled );
void toggleSyncVSTPlugins( bool _enabled );
private:
@@ -156,6 +157,7 @@ private:
bool m_enableAutoSave;
bool m_oneInstrumentTrackWindow;
bool m_compactTrackButtons;
bool m_syncVSTPlugins;
typedef QMap<QString, AudioDevice::setupWidget *> AswMap;
typedef QMap<QString, MidiClient::setupWidget *> MswMap;

View File

@@ -25,13 +25,14 @@
#ifndef _SONG_H
#define _SONG_H
#include <QtCore/QSharedMemory>
#include <QtCore/QVector>
#include "track_container.h"
#include "AutomatableModel.h"
#include "Controller.h"
#include "MeterModel.h"
#include "VST_sync_shm.h"
class AutomationTrack;
class pattern;
@@ -249,6 +250,8 @@ private slots:
void updateFramesPerTick();
void updateSampleRateSHM();
private:
@@ -323,6 +326,9 @@ private:
} ;
QVector<Actions> m_actions;
int m_shmID;
sncVST * m_SncVSTplug;
QSharedMemory m_shmQtID;
friend class engine;
friend class songEditor;