From 5a9e0bdcef2589e8ff9136f483f9147d06a275b8 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Mon, 3 Feb 2014 19:41:54 +0100 Subject: [PATCH] Moved VST sync functionality into new VstSyncController class First attempt to clean up the mess in the Song class by moving the VST sync functionality into its own class and just calling a few functions from it. --- include/RemotePlugin.h | 28 ++-- include/VstSyncController.h | 99 +++++++++++ include/{VST_sync_shm.h => VstSyncData.h} | 17 +- include/song.h | 9 +- plugins/vst_base/RemoteVstPlugin.cpp | 88 +++++----- src/core/VstSyncController.cpp | 196 ++++++++++++++++++++++ src/core/song.cpp | 181 +++----------------- 7 files changed, 392 insertions(+), 226 deletions(-) create mode 100644 include/VstSyncController.h rename include/{VST_sync_shm.h => VstSyncData.h} (83%) create mode 100644 src/core/VstSyncController.cpp diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 8eb097ebd..0da674289 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -27,7 +27,7 @@ #include "export.h" #include "MidiEvent.h" -#include "VST_sync_shm.h" +#include "VstSyncData.h" #include #include @@ -813,7 +813,7 @@ public: RemotePluginClient( key_t _shm_in, key_t _shm_out ); virtual ~RemotePluginClient(); #ifdef USE_QT_SHMEM - sncVST * getQtVSTshm(); + VstSyncData * getQtVSTshm(); #endif virtual bool processMessage( const message & _m ); @@ -883,7 +883,7 @@ private: QSharedMemory m_shmObj; QSharedMemory m_shmQtID; #endif - sncVST * m_SncVSTplug; + VstSyncData * m_vstSyncData; float * m_shm; int m_inputCount; @@ -1013,7 +1013,7 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) : m_shmObj(), m_shmQtID( "/usr/bin/lmms" ), #endif - m_SncVSTplug( NULL ), + m_vstSyncData( NULL ), m_shm( NULL ), m_inputCount( 0 ), m_outputCount( 0 ), @@ -1023,9 +1023,9 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) : #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; + m_vstSyncData = (VstSyncData *) m_shmQtID.data(); + m_bufferSize = m_vstSyncData->m_bufferSize; + m_sampleRate = m_vstSyncData->m_sampleRate; return; } #else @@ -1044,18 +1044,18 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) : } else { // attach segment - m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0); - if( m_SncVSTplug == (sncVST *)( -1 ) ) + m_vstSyncData = (VstSyncData *)shmat(m_shmID, 0, 0); + if( m_vstSyncData == (VstSyncData *)( -1 ) ) { perror( "RemotePluginClient::shmat" ); } else { - m_bufferSize = m_SncVSTplug->m_bufferSize; - m_sampleRate = m_SncVSTplug->m_sampleRate; + m_bufferSize = m_vstSyncData->m_bufferSize; + m_sampleRate = m_vstSyncData->m_sampleRate; // detach segment - if( shmdt(m_SncVSTplug) == -1 ) + if( shmdt(m_vstSyncData) == -1 ) { perror("RemotePluginClient::shmdt"); } @@ -1087,9 +1087,9 @@ RemotePluginClient::~RemotePluginClient() #ifdef USE_QT_SHMEM -sncVST * RemotePluginClient::getQtVSTshm() +VstSyncData * RemotePluginClient::getQtVSTshm() { - return m_SncVSTplug; + return m_vstSyncData; } #endif diff --git a/include/VstSyncController.h b/include/VstSyncController.h new file mode 100644 index 000000000..91c39ea6e --- /dev/null +++ b/include/VstSyncController.h @@ -0,0 +1,99 @@ +/* + * VstSyncController.h - type declarations needed for VST to lmms host sync + * + * Copyright (c) 2014 Tobias Doerffel + * Copyright (c) 2013 Mike Choi + * + * 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_CONTROLLER_H +#define VST_SYNC_CONTROLLER_H + +#include +#include + +#include "VstSyncData.h" + + +class VstSyncController : public QObject +{ + Q_OBJECT +public: + VstSyncController(); + ~VstSyncController(); + + void setAbsolutePosition( int ticks ); + + void setPlaybackState( bool enabled ) + { + m_syncData->isPlaying = enabled; + } + + void setTempo( int newTempo ); + + void setTimeSignature( int num, int denom ) + { + m_syncData->timeSigNumer = num; + m_syncData->timeSigDenom = denom; + } + + void startCycle( int startTick, int endTick ); + + void stopCycle() + { + m_syncData->isCycle = false; + } + + void update(); + + +private slots: + void updateSampleRate(); + + +private: + struct VstSyncData + { + bool isPlaying; + float ppqPos; + int timeSigNumer; + int timeSigDenom; + bool isCycle; + bool hasSHM; + float cycleStart; + float cycleEnd; + int m_bufferSize; + int m_sampleRate; + int m_bpm; + +#ifdef VST_SNC_LATENCY + float m_latency; +#endif + } ; + + VstSyncData* m_syncData; + + int m_shmID; + + QSharedMemory m_shm; + +}; + +#endif diff --git a/include/VST_sync_shm.h b/include/VstSyncData.h similarity index 83% rename from include/VST_sync_shm.h rename to include/VstSyncData.h index 7b6a813d5..9daa3380f 100644 --- a/include/VST_sync_shm.h +++ b/include/VstSyncData.h @@ -1,8 +1,9 @@ /* - * VST_sync_shm.h - type declarations needed for VST to lmms host sync + * VstSyncData.h - type declarations needed for VST to lmms host sync + * + * Copyright (c) 2014 Tobias Doerffel + * Copyright (c) 2013 Mike Choi * - * Copyright (c) 2004-2013 Tobias Doerffel - * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -22,8 +23,8 @@ * */ -#ifndef _VST_SYNC_SHM_H -#define _VST_SYNC_SHM_H +#ifndef VST_SYNC_DATA_H +#define VST_SYNC_DATA_H // VST sync frequency (in ms), how often will be VST plugin synced // keep it power of two if possible (not used by now) @@ -36,9 +37,11 @@ #define VST_SNC_SHM_KEY_FILE "/dev/null" //#define VST_SNC_SHM_RND_KEY 3561653564469 -struct sncVST + + +struct VstSyncData { - bool isPlayin; + bool isPlaying; float ppqPos; int timeSigNumer; int timeSigDenom; diff --git a/include/song.h b/include/song.h index 5900c8c93..c2ba37fbf 100644 --- a/include/song.h +++ b/include/song.h @@ -32,7 +32,7 @@ #include "AutomatableModel.h" #include "Controller.h" #include "MeterModel.h" -#include "VST_sync_shm.h" +#include "VstSyncController.h" class AutomationTrack; class pattern; @@ -296,8 +296,6 @@ private slots: void updateFramesPerTick(); - void updateSampleRateSHM(); - private: @@ -368,9 +366,8 @@ private: } ; QVector m_actions; - int m_shmID; - sncVST * m_SncVSTplug; - QSharedMemory m_shmQtID; + VstSyncController m_vstSyncController; + friend class engine; friend class songEditor; diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 559ae889b..1c0c66c6e 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -92,7 +92,7 @@ struct ERect #include "Midi.h" #include "communication.h" -#include "VST_sync_shm.h" +#include "VstSyncData.h" #ifdef LMMS_BUILD_WIN32 #define USE_QT_SHMEM @@ -325,7 +325,7 @@ private: in * m_in; int m_shmID; - sncVST * m_SncVSTplug; + VstSyncData* m_vstSyncData; } ; @@ -351,7 +351,7 @@ RemoteVstPlugin::RemoteVstPlugin( key_t _shm_in, key_t _shm_out ) : m_currentProgram( -1 ), m_in( NULL ), m_shmID( -1 ), - m_SncVSTplug( NULL ) + m_vstSyncData( NULL ) { pthread_mutex_init( &m_pluginLock, NULL ); @@ -372,29 +372,29 @@ RemoteVstPlugin::RemoteVstPlugin( key_t _shm_in, key_t _shm_out ) : } else { // attach segment - m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0); - if( m_SncVSTplug == (sncVST *)( -1 ) ) + m_vstSyncData = (VstSyncData *)shmat(m_shmID, 0, 0); + if( m_vstSyncData == (VstSyncData *)( -1 ) ) { perror( "RemoteVstPlugin.cpp::shmat" ); } } } #else - m_SncVSTplug = RemotePluginClient::getQtVSTshm(); + m_vstSyncData = RemotePluginClient::getQtVSTshm(); #endif - if( m_SncVSTplug == NULL ) + if( m_vstSyncData == NULL ) { fprintf(stderr, "RemoteVstPlugin.cpp: " "Failed to initialize shared memory for VST synchronization.\n" " (VST-host synchronization will be disabled)\n"); - m_SncVSTplug = (sncVST*) malloc( sizeof( sncVST ) ); - m_SncVSTplug->isPlayin = true; - m_SncVSTplug->timeSigNumer = 4; - m_SncVSTplug->timeSigDenom = 4; - m_SncVSTplug->ppqPos = 0; - m_SncVSTplug->isCycle = false; - m_SncVSTplug->hasSHM = false; - m_SncVSTplug->m_sampleRate = sampleRate(); + m_vstSyncData = (VstSyncData*) malloc( sizeof( VstSyncData ) ); + m_vstSyncData->isPlaying = true; + m_vstSyncData->timeSigNumer = 4; + m_vstSyncData->timeSigDenom = 4; + m_vstSyncData->ppqPos = 0; + m_vstSyncData->isCycle = false; + m_vstSyncData->hasSHM = false; + m_vstSyncData->m_sampleRate = sampleRate(); } m_in = ( in* ) new char[ sizeof( in ) ]; @@ -420,16 +420,16 @@ RemoteVstPlugin::~RemoteVstPlugin() { #ifndef USE_QT_SHMEM // detach shared memory segment - if( shmdt( m_SncVSTplug ) == -1) + if( shmdt( m_vstSyncData ) == -1) { - if( __plugin->m_SncVSTplug->hasSHM ) + if( __plugin->m_vstSyncData->hasSHM ) { perror( "~RemoteVstPlugin::shmdt" ); } - if( m_SncVSTplug != NULL ) + if( m_vstSyncData != NULL ) { - delete m_SncVSTplug; - m_SncVSTplug = NULL; + delete m_vstSyncData; + m_vstSyncData = NULL; } } #endif @@ -573,7 +573,7 @@ void RemoteVstPlugin::init( const std::string & _plugin_file ) updateInOutCount(); // some plugins have to set samplerate during init - if( m_SncVSTplug->hasSHM ) + if( m_vstSyncData->hasSHM ) { updateSampleRate(); } @@ -1444,58 +1444,58 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, // items may require extensive conversions // Shared memory was initialised? - see song.cpp - //assert( __plugin->m_SncVSTplug != NULL ); + //assert( __plugin->m_vstSyncData != NULL ); memset( &_timeInfo, 0, sizeof( _timeInfo ) ); _timeInfo.samplePos = __plugin->m_currentSamplePos; - _timeInfo.sampleRate = __plugin->m_SncVSTplug->hasSHM ? - __plugin->m_SncVSTplug->m_sampleRate : + _timeInfo.sampleRate = __plugin->m_vstSyncData->hasSHM ? + __plugin->m_vstSyncData->m_sampleRate : __plugin->sampleRate(); _timeInfo.flags = 0; - _timeInfo.tempo = __plugin->m_SncVSTplug->hasSHM ? - __plugin->m_SncVSTplug->m_bpm : + _timeInfo.tempo = __plugin->m_vstSyncData->hasSHM ? + __plugin->m_vstSyncData->m_bpm : __plugin->m_bpm; - _timeInfo.timeSigNumerator = __plugin->m_SncVSTplug->timeSigNumer; - _timeInfo.timeSigDenominator = __plugin->m_SncVSTplug->timeSigDenom; + _timeInfo.timeSigNumerator = __plugin->m_vstSyncData->timeSigNumer; + _timeInfo.timeSigDenominator = __plugin->m_vstSyncData->timeSigDenom; _timeInfo.flags |= kVstTempoValid; _timeInfo.flags |= kVstTimeSigValid; - if( __plugin->m_SncVSTplug->isCycle ) + if( __plugin->m_vstSyncData->isCycle ) { - _timeInfo.cycleStartPos = __plugin->m_SncVSTplug->cycleStart; - _timeInfo.cycleEndPos = __plugin->m_SncVSTplug->cycleEnd; + _timeInfo.cycleStartPos = __plugin->m_vstSyncData->cycleStart; + _timeInfo.cycleEndPos = __plugin->m_vstSyncData->cycleEnd; _timeInfo.flags |= kVstCyclePosValid; _timeInfo.flags |= kVstTransportCycleActive; } - if( __plugin->m_SncVSTplug->ppqPos != + if( __plugin->m_vstSyncData->ppqPos != __plugin->m_in->m_Timestamp ) { - _timeInfo.ppqPos = __plugin->m_SncVSTplug->ppqPos; + _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos; _timeInfo.flags |= kVstTransportChanged; - __plugin->m_in->lastppqPos = __plugin->m_SncVSTplug->ppqPos; - __plugin->m_in->m_Timestamp = __plugin->m_SncVSTplug->ppqPos; + __plugin->m_in->lastppqPos = __plugin->m_vstSyncData->ppqPos; + __plugin->m_in->m_Timestamp = __plugin->m_vstSyncData->ppqPos; } - else if( __plugin->m_SncVSTplug->isPlayin ) + else if( __plugin->m_vstSyncData->isPlaying ) { __plugin->m_in->lastppqPos += ( - __plugin->m_SncVSTplug->hasSHM ? - __plugin->m_SncVSTplug->m_bpm : + __plugin->m_vstSyncData->hasSHM ? + __plugin->m_vstSyncData->m_bpm : __plugin->m_bpm ) / (float)10340; _timeInfo.ppqPos = __plugin->m_in->lastppqPos; } -// _timeInfo.ppqPos = __plugin->m_SncVSTplug->ppqPos; +// _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos; _timeInfo.flags |= kVstPpqPosValid; - if( __plugin->m_SncVSTplug->isPlayin ) + if( __plugin->m_vstSyncData->isPlaying ) { _timeInfo.flags |= kVstTransportPlaying; } _timeInfo.barStartPos = ( (int) ( _timeInfo.ppqPos / - ( 4 *__plugin->m_SncVSTplug->timeSigNumer - / (float) __plugin->m_SncVSTplug->timeSigDenom ) ) ) * - ( 4 * __plugin->m_SncVSTplug->timeSigNumer - / (float) __plugin->m_SncVSTplug->timeSigDenom ); + ( 4 *__plugin->m_vstSyncData->timeSigNumer + / (float) __plugin->m_vstSyncData->timeSigDenom ) ) ) * + ( 4 * __plugin->m_vstSyncData->timeSigNumer + / (float) __plugin->m_vstSyncData->timeSigDenom ); _timeInfo.flags |= kVstBarsValid; diff --git a/src/core/VstSyncController.cpp b/src/core/VstSyncController.cpp new file mode 100644 index 000000000..93243b197 --- /dev/null +++ b/src/core/VstSyncController.cpp @@ -0,0 +1,196 @@ +/* + * VstSyncController.cpp - manage synchronization between LMMS and VST plugins + * + * Copyright (c) 2014 Tobias Doerffel + * Copyright (c) 2013 Mike Choi + * + * This file is part of LMMS - 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. + * + */ + +#include + +#include "config_mgr.h" +#include "engine.h" +#include "lmmsconfig.h" +#include "Mixer.h" +#include "VstSyncController.h" + +#ifdef LMMS_BUILD_WIN32 +#ifndef USE_QT_SHMEM +#define USE_QT_SHMEM +#endif +#endif + +#ifndef USE_QT_SHMEM +#include +#include +#include +#include +#include +#include +#endif + + +VstSyncController::VstSyncController() : + m_syncData( NULL ), + m_shmID( -1 ), + m_shm( "/usr/bin/lmms" ) +{ + if( configManager::inst()->value( "ui", "syncvstplugins" ).toInt() ) + { + connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateSampleRate() ) ); + +#ifdef USE_QT_SHMEM + if ( m_shm.create( sizeof( VstSyncData ) ) ) + { + m_syncData = (VstSyncData*) m_shm.data(); + } + else + { + qWarning() << QString( "Failed to allocate shared memory for VST sync: %1" ).arg( m_shm.errorString() ); + } +#else + key_t key; // make the key: + if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 ) + { + qWarning( "VstSyncController: ftok() failed" ); + } + else + { // connect to shared memory segment + if( ( m_shmID = shmget( key, sizeof( VstSyncData ), 0644 | IPC_CREAT ) ) == -1 ) + { + qWarning( "VstSyncController: shmget() failed" ); + } + else + { // attach segment + m_syncData = (VstSyncData *)shmat( m_shmID, 0, 0 ); + if( m_syncData == (VstSyncData *)( -1 ) ) + { + qWarning( "VstSyncController: shmat() failed" ); + } + } + } +#endif + } + + if( m_syncData == NULL ) + { + m_syncData = new VstSyncData; + m_syncData->hasSHM = false; + } + else + { + m_syncData->hasSHM = true; + } + + m_syncData->isPlaying = false; + m_syncData->m_bufferSize = engine::mixer()->framesPerPeriod(); + m_syncData->timeSigNumer = 4; + m_syncData->timeSigDenom = 4; + + updateSampleRate(); +} + + + +VstSyncController::~VstSyncController() +{ + if( m_syncData->hasSHM == false ) + { + delete m_syncData; + } + else + { +#ifdef USE_QT_SHMEM + if( m_shm.data() ) + { + // detach shared memory, delete it: + m_shm.detach(); + } +#else + if( shmdt( m_syncData ) != -1 ) + { + shmctl( m_shmID, IPC_RMID, NULL ); + } + else + { + qWarning( "VstSyncController: shmdt() failed" ); + } +#endif + } +} + + + +void VstSyncController::setAbsolutePosition( int ticks ) +{ +#ifdef VST_SNC_LATENCY + m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ) - m_syncData->m_latency; +#else + m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ); +#endif +} + + + +void VstSyncController::setTempo( int newTempo ) +{ + m_syncData->m_bpm = newTempo; + +#ifdef VST_SNC_LATENCY + m_syncData->m_latency = m_syncData->m_bufferSize * newTempo / ( (float) m_syncData->m_sampleRate * 60 ); +#endif + +} + + + +void VstSyncController::startCycle( int startTick, int endTick ) +{ + m_syncData->isCycle = true; + m_syncData->cycleStart = startTick / (float)48; + m_syncData->cycleEnd = endTick / (float)48; +} + + + +void VstSyncController::update() +{ + m_syncData->m_bufferSize = engine::mixer()->framesPerPeriod(); + +#ifdef VST_SNC_LATENCY + m_syncData->m_latency = m_syncData->m_bufferSize * m_syncData->m_bpm / ( (float) m_syncData->m_sampleRate * 60 ); +#endif +} + + + +void VstSyncController::updateSampleRate() +{ + m_syncData->m_sampleRate = engine::mixer()->processingSampleRate(); + +#ifdef VST_SNC_LATENCY + m_syncData->m_latency = m_syncData->m_bufferSize * m_syncData->m_bpm / ( (float) m_syncData->m_sampleRate * 60 ); +#endif +} + + + +#include "moc_VstSyncController.cxx" + diff --git a/src/core/song.cpp b/src/core/song.cpp index b1a3763e5..ebbb0d8f3 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -63,20 +63,6 @@ #include "timeline.h" #include "PeakController.h" -#ifdef LMMS_BUILD_WIN32 -#ifndef USE_QT_SHMEM -#define USE_QT_SHMEM -#endif -#endif - -#ifndef USE_QT_SHMEM -#include -#include -#include -#include -#include -#include -#endif tick_t MidiTime::s_ticksPerTact = DefaultTicksPerTact; @@ -108,10 +94,7 @@ song::song() : m_loopPattern( false ), m_elapsedMilliSeconds( 0 ), m_elapsedTicks( 0 ), - m_elapsedTacts( 0 ), - m_shmID( -1 ), - m_SncVSTplug( NULL ), - m_shmQtID( "/usr/bin/lmms" ) + m_elapsedTacts( 0 ) { connect( &m_tempoModel, SIGNAL( dataChanged() ), this, SLOT( setTempo() ) ); @@ -124,60 +107,6 @@ song::song() : connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateFramesPerTick() ) ); - // handle VST plugins sync - if( configManager::inst()->value( "ui", "syncvstplugins" ).toInt() ) - { - connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, - SLOT( updateSampleRateSHM() ) ); -#ifdef USE_QT_SHMEM - if ( !m_shmQtID.create( sizeof( sncVST ) ) ) - { - fprintf(stderr, "song.cpp::m_shmQtID create SHM error: %s\n", - m_shmQtID.errorString().toStdString().c_str() ); - } - m_SncVSTplug = (sncVST *) m_shmQtID.data(); -#else - key_t key; // make the key: - if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 ) - { - perror( "song.cpp::ftok" ); - } - else - { // connect to shared memory segment - if( ( m_shmID = shmget( key, sizeof( sncVST ), - 0644 | IPC_CREAT ) ) == -1 ) - { - perror( "song.cpp::shmget" ); - } - else - { // attach segment - m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0); - if( m_SncVSTplug == (sncVST *)( -1 ) ) - { - perror( "song.cpp::shmat" ); - } - } - } -#endif - // if we are connected into shared memory - if( m_SncVSTplug != NULL ) - { - m_SncVSTplug->isPlayin = m_playing | m_exporting; - m_SncVSTplug->hasSHM = true; - m_SncVSTplug->m_sampleRate = - engine::mixer()->processingSampleRate(); - m_SncVSTplug->m_bufferSize = - engine::mixer()->framesPerPeriod(); - m_SncVSTplug->timeSigNumer = 4; - m_SncVSTplug->timeSigDenom = 4; - } - } // end of VST plugin sync section - - if( m_SncVSTplug == NULL ) - { - m_SncVSTplug = (sncVST*) malloc( sizeof( sncVST ) ); - } - connect( &m_masterVolumeModel, SIGNAL( dataChanged() ), this, SLOT( masterVolumeChanged() ) ); /* connect( &m_masterPitchModel, SIGNAL( dataChanged() ), @@ -191,24 +120,6 @@ song::song() : song::~song() { - // detach shared memory, delete it: -#ifdef USE_QT_SHMEM - m_shmQtID.detach(); -#else - if( shmdt( m_SncVSTplug ) == -1) - { - if( m_SncVSTplug->hasSHM ) - { - perror("~song::shmdt"); - } - if( m_SncVSTplug != NULL ) - { - free( m_SncVSTplug ); - m_SncVSTplug = NULL; - } - } - shmctl(m_shmID, IPC_RMID, NULL); -#endif m_playing = false; delete m_globalAutomationTrack; } @@ -243,12 +154,7 @@ void song::setTempo() engine::updateFramesPerTick(); - m_SncVSTplug->m_bpm = tempo; - -#ifdef VST_SNC_LATENCY - m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * tempo / - ( (float) m_SncVSTplug->m_sampleRate * 60 ); -#endif + m_vstSyncController.setTempo( tempo ); emit tempoChanged( tempo ); } @@ -262,8 +168,8 @@ void song::setTimeSignature() emit timeSignatureChanged( m_oldTicksPerTact, ticksPerTact() ); emit dataChanged(); m_oldTicksPerTact = ticksPerTact(); - m_SncVSTplug->timeSigNumer = getTimeSigModel().getNumerator(); - m_SncVSTplug->timeSigDenom = getTimeSigModel().getDenominator(); + + m_vstSyncController.setTimeSignature( getTimeSigModel().getNumerator(), getTimeSigModel().getDenominator() ); } @@ -280,7 +186,7 @@ void song::savePos() case ActionStop: { m_playing = false; - m_SncVSTplug->isPlayin = m_exporting; + m_vstSyncController.setPlaybackState( m_exporting ); m_recording = true; if( tl != NULL ) { @@ -325,37 +231,37 @@ void song::savePos() case ActionPlaySong: m_playMode = Mode_PlaySong; m_playing = true; - m_SncVSTplug->isPlayin = true; + m_vstSyncController.setPlaybackState( true ); Controller::resetFrameCounter(); break; case ActionPlayTrack: m_playMode = Mode_PlayTrack; m_playing = true; - m_SncVSTplug->isPlayin = true; + m_vstSyncController.setPlaybackState( true ); break; case ActionPlayBB: m_playMode = Mode_PlayBB; m_playing = true; - m_SncVSTplug->isPlayin = true; + m_vstSyncController.setPlaybackState( true ); break; case ActionPlayPattern: m_playMode = Mode_PlayPattern; m_playing = true; - m_SncVSTplug->isPlayin = true; + m_vstSyncController.setPlaybackState( true ); break; case ActionPause: m_playing = false;// just set the play-flag - m_SncVSTplug->isPlayin = m_exporting; + m_vstSyncController.setPlaybackState( m_exporting ); m_paused = true; break; case ActionResumeFromPause: m_playing = true;// just set the play-flag - m_SncVSTplug->isPlayin = true; + m_vstSyncController.setPlaybackState( true ); m_paused = false; break; } @@ -472,28 +378,17 @@ void song::processNextBuffer() while( total_frames_played < engine::mixer()->framesPerPeriod() ) { - f_cnt_t played_frames = ( m_SncVSTplug->m_bufferSize = engine::mixer() - ->framesPerPeriod() ) - total_frames_played; + m_vstSyncController.update(); -#ifdef VST_SNC_LATENCY - m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * - m_SncVSTplug->m_bpm / - ( (float) m_SncVSTplug->m_sampleRate * 60 ); -#endif + f_cnt_t played_frames = engine::mixer()->framesPerPeriod() - total_frames_played; float current_frame = m_playPos[m_playMode].currentFrame(); // did we play a tick? if( current_frame >= frames_per_tick ) { - int ticks = m_playPos[m_playMode].getTicks() - + (int)( current_frame / frames_per_tick ); + int ticks = m_playPos[m_playMode].getTicks() + (int)( current_frame / frames_per_tick ); -#ifdef VST_SNC_LATENCY - m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 ) - - m_SncVSTplug->m_latency; -#else - m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 ); -#endif + m_vstSyncController.setAbsolutePosition( ticks ); // did we play a whole tact? if( ticks >= MidiTime::ticksPerTact() ) @@ -526,39 +421,26 @@ void song::processNextBuffer() { // then start from beginning and keep // offset - ticks = ticks % ( max_tact * - MidiTime::ticksPerTact() ); -#ifdef VST_SNC_LATENCY - m_SncVSTplug->ppqPos = ( ( ticks + 0 ) - / (float)48 ) - - m_SncVSTplug->m_latency; -#else - m_SncVSTplug->ppqPos = ( ( ticks + 0 ) - / (float)48 ); -#endif + ticks = ticks % ( max_tact * MidiTime::ticksPerTact() ); + + m_vstSyncController.setAbsolutePosition( ticks ); } } m_playPos[m_playMode].setTicks( ticks ); if( check_loop ) { - m_SncVSTplug->isCycle = true; - m_SncVSTplug->cycleStart = - ( tl->loopBegin().getTicks() ) - / (float)48; - m_SncVSTplug->cycleEnd = - ( tl->loopEnd().getTicks() ) - / (float)48; + m_vstSyncController.startCycle( tl->loopBegin().getTicks(), tl->loopEnd().getTicks() ); + if( m_playPos[m_playMode] >= tl->loopEnd() ) { - m_playPos[m_playMode].setTicks( - tl->loopBegin().getTicks() ); + m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); m_elapsedMilliSeconds = ((tl->loopBegin().getTicks())*60*1000/48)/getTempo(); } } else { - m_SncVSTplug->isCycle = false; + m_vstSyncController.stopCycle(); } current_frame = fmodf( current_frame, frames_per_tick ); @@ -852,7 +734,8 @@ void song::startExport() playSong(); m_exporting = true; - m_SncVSTplug->isPlayin = true; + + m_vstSyncController.setPlaybackState( true ); } @@ -863,7 +746,8 @@ void song::stopExport() stop(); m_exporting = false; m_exportLoop = false; - m_SncVSTplug->isPlayin = m_playing; + + m_vstSyncController.setPlaybackState( m_playing ); } @@ -1453,19 +1337,6 @@ void song::updateFramesPerTick() -void song::updateSampleRateSHM() -{ - m_SncVSTplug->m_sampleRate = engine::mixer()->processingSampleRate(); - -#ifdef VST_SNC_LATENCY - m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * m_SncVSTplug->m_bpm / - ( (float) m_SncVSTplug->m_sampleRate * 60 ); -#endif -} - - - - void song::setModified() { if( !m_loadingProject )