LVSL: added support for (automatable) VST controls and VST presets
LMMS VST Support Layer has been greatly advanced as it now features (automatable) VST controls as well as support for VST presets. This still needs some work as it crashes with various plugins (e.g. z3ta+). Signed-off-by: Tobias Doerffel <tobias.doerffel@gmail.com>
BIN
data/themes/default/stepper-down-press.png
Normal file
|
After Width: | Height: | Size: 510 B |
BIN
data/themes/default/stepper-down.png
Normal file
|
After Width: | Height: | Size: 516 B |
BIN
data/themes/default/stepper-left-press.png
Normal file
|
After Width: | Height: | Size: 514 B |
BIN
data/themes/default/stepper-left.png
Normal file
|
After Width: | Height: | Size: 548 B |
BIN
data/themes/default/stepper-right-press.png
Normal file
|
After Width: | Height: | Size: 519 B |
BIN
data/themes/default/stepper-right.png
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
data/themes/default/stepper-up-press.png
Normal file
|
After Width: | Height: | Size: 516 B |
BIN
data/themes/default/stepper-up.png
Normal file
|
After Width: | Height: | Size: 528 B |
@@ -509,6 +509,11 @@ enum RemoteMessageIDs
|
||||
IdSaveSettingsToFile,
|
||||
IdLoadSettingsFromString,
|
||||
IdLoadSettingsFromFile,
|
||||
IdLoadChunkFromPresetFile,
|
||||
IdRotateProgram,
|
||||
IdLoadPrograms,
|
||||
IdSavePreset,
|
||||
IdSetParameter,
|
||||
IdLoadPresetFromFile,
|
||||
IdDebugMessage,
|
||||
IdUserBase = 64
|
||||
|
||||
@@ -180,7 +180,7 @@ public:
|
||||
class VstParameterProperties
|
||||
{
|
||||
public:
|
||||
float stepFloat;
|
||||
/* float stepFloat;
|
||||
char label[64];
|
||||
int flags;
|
||||
int minInteger;
|
||||
@@ -189,7 +189,24 @@ public:
|
||||
char shortLabel[8];
|
||||
int category;
|
||||
char categoryLabel[24];
|
||||
char empty[128];
|
||||
char empty[128];*/
|
||||
|
||||
float stepFloat;
|
||||
float smallStepFloat;
|
||||
float largeStepFloat;
|
||||
char label[64];
|
||||
unsigned int flags;
|
||||
unsigned int minInteger;
|
||||
unsigned int maxInteger;
|
||||
unsigned int stepInteger;
|
||||
unsigned int largeStepInteger;
|
||||
char shortLabel[8];
|
||||
unsigned short displayIndex;
|
||||
unsigned short category;
|
||||
unsigned short numParametersInCategory;
|
||||
unsigned short reserved;
|
||||
char categoryLabel[24];
|
||||
char future[16];
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* vestige.cpp - instrument-plugin for hosting VST-instruments
|
||||
*
|
||||
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QMdiArea>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtXml/QDomElement>
|
||||
|
||||
#include "engine.h"
|
||||
@@ -36,6 +38,7 @@
|
||||
#include "InstrumentPlayHandle.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "VstPlugin.h"
|
||||
#include "MainWindow.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "string_pair_drag.h"
|
||||
#include "text_float.h"
|
||||
@@ -44,6 +47,7 @@
|
||||
#include "embed.cpp"
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
@@ -65,12 +69,16 @@ Plugin::Descriptor PLUGIN_EXPORT vestige_plugin_descriptor =
|
||||
|
||||
|
||||
QPixmap * VestigeInstrumentView::s_artwork = NULL;
|
||||
QPixmap * manageVestigeInstrumentView::s_artwork = NULL;
|
||||
|
||||
|
||||
vestigeInstrument::vestigeInstrument( InstrumentTrack * _instrument_track ) :
|
||||
Instrument( _instrument_track, &vestige_plugin_descriptor ),
|
||||
m_plugin( NULL ),
|
||||
m_pluginMutex()
|
||||
m_pluginMutex(),
|
||||
m_subWindow( NULL ),
|
||||
knobFModel( NULL ),
|
||||
vstKnobs( NULL )
|
||||
{
|
||||
// now we need a play-handle which cares for calling play()
|
||||
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this );
|
||||
@@ -96,6 +104,28 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
if( m_plugin != NULL )
|
||||
{
|
||||
m_plugin->loadSettings( _this );
|
||||
|
||||
const QMap<QString, QString> & dump = m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
char paramStr[35];
|
||||
vstKnobs = new knob *[paramCount];
|
||||
knobFModel = new FloatModel *[paramCount];
|
||||
QStringList list1;
|
||||
QWidget * xx = new QWidget();
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
|
||||
vstKnobs[i] = new knob( knobBright_26, xx );
|
||||
vstKnobs[i]->setHintText( list1.at(1) + ":", "");
|
||||
vstKnobs[i]->setLabel( list1.at(1).left(15) );
|
||||
|
||||
knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i]->loadSettings( _this, paramStr );
|
||||
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
|
||||
vstKnobs[i]->setModel( knobFModel[i] );
|
||||
}
|
||||
}
|
||||
m_pluginMutex.unlock();
|
||||
}
|
||||
@@ -103,6 +133,20 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::setParameter( void )
|
||||
{
|
||||
|
||||
Model *action = qobject_cast<Model *>(sender());
|
||||
int knobUNID = action->displayName().toInt();
|
||||
|
||||
if ( m_plugin != NULL ) {
|
||||
m_plugin->setParam( knobUNID, knobFModel[knobUNID]->value() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
_this.setAttribute( "plugin", m_pluginDLL );
|
||||
@@ -110,6 +154,40 @@ void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
if( m_plugin != NULL )
|
||||
{
|
||||
m_plugin->saveSettings( _doc, _this );
|
||||
if (knobFModel != NULL) {
|
||||
const QMap<QString, QString> & dump = m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
char paramStr[35];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
if (knobFModel[i]->isAutomated() || knobFModel[i]->getControllerConnection()) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
knobFModel[i]->saveSettings( _doc, _this, paramStr );
|
||||
}
|
||||
|
||||
/* QDomElement me = _doc.createElement( paramStr );
|
||||
me.setAttribute( "id", knobFModel[i]->id() );
|
||||
me.setAttribute( "value", knobFModel[i]->value() );
|
||||
_this.appendChild( me );
|
||||
|
||||
ControllerConnection * m_controllerConnection = knobFModel[i]->getControllerConnection();
|
||||
if (m_controllerConnection) {
|
||||
QDomElement controller_element;
|
||||
QDomNode node = _this.namedItem( "connection" );
|
||||
if( node.isElement() )
|
||||
{
|
||||
controller_element = node.toElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
controller_element = _doc.createElement( "connection" );
|
||||
_this.appendChild( controller_element );
|
||||
}
|
||||
QDomElement element = _doc.createElement( paramStr );
|
||||
m_controllerConnection->saveSettings( _doc, element );
|
||||
controller_element.appendChild( element );
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
m_pluginMutex.unlock();
|
||||
}
|
||||
@@ -246,7 +324,9 @@ PluginView * vestigeInstrument::instantiateView( QWidget * _parent )
|
||||
|
||||
VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument,
|
||||
QWidget * _parent ) :
|
||||
InstrumentView( _instrument, _parent )
|
||||
InstrumentView( _instrument, _parent ),
|
||||
tt ( NULL ),
|
||||
lastPosInMenu (0)
|
||||
{
|
||||
if( s_artwork == NULL )
|
||||
{
|
||||
@@ -271,8 +351,108 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument,
|
||||
"clicking on this button, a file-open-dialog appears "
|
||||
"and you can select your file." ) );
|
||||
|
||||
m_managePluginButton = new pixmapButton( this, "" );
|
||||
m_managePluginButton->setCheckable( false );
|
||||
m_managePluginButton->setCursor( Qt::PointingHandCursor );
|
||||
m_managePluginButton->move( 220, 102 );
|
||||
m_managePluginButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"track_op_menu", 20, 20 ) );
|
||||
m_managePluginButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"track_op_menu", 20, 20 ) );
|
||||
connect( m_managePluginButton, SIGNAL( clicked() ), this,
|
||||
SLOT( managePlugin() ) );
|
||||
toolTip::add( m_managePluginButton, tr( "Control VST-plugin from LMMS host" ) );
|
||||
|
||||
m_managePluginButton->setWhatsThis(
|
||||
tr( "Click here, if you want to control VST-plugin from host." ) );
|
||||
|
||||
|
||||
m_openPresetButton = new pixmapButton( this, "" );
|
||||
m_openPresetButton->setCheckable( false );
|
||||
m_openPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_openPresetButton->move( 224, 192 );
|
||||
m_openPresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-up-press" ) );
|
||||
m_openPresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-up" ) );
|
||||
connect( m_openPresetButton, SIGNAL( clicked() ), this,
|
||||
SLOT( openPreset() ) );
|
||||
toolTip::add( m_openPresetButton, tr( "Open VST-plugin preset" ) );
|
||||
|
||||
m_openPresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to open another *.fxp, *.fxb VST-plugin preset." ) );
|
||||
|
||||
|
||||
m_rolLPresetButton = new pixmapButton( this, "" );
|
||||
m_rolLPresetButton->setCheckable( false );
|
||||
m_rolLPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_rolLPresetButton->move( 167, 192 );
|
||||
m_rolLPresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-left-press" ) );
|
||||
m_rolLPresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-left" ) );
|
||||
connect( m_rolLPresetButton, SIGNAL( clicked() ), this,
|
||||
SLOT( rolrPreset() ) );
|
||||
toolTip::add( m_rolLPresetButton, tr( "Previous (-)" ) );
|
||||
|
||||
m_rolLPresetButton->setShortcut( Qt::Key_Minus );
|
||||
|
||||
m_rolLPresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to switch to another VST-plugin presset program." ) );
|
||||
|
||||
|
||||
m_savePresetButton = new pixmapButton( this, "" );
|
||||
m_savePresetButton->setCheckable( false );
|
||||
m_savePresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_savePresetButton->move( 224, 213 );
|
||||
m_savePresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"project_save", 16, 16 ) );
|
||||
m_savePresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"project_save", 16, 16 ) );
|
||||
connect( m_savePresetButton, SIGNAL( clicked() ), this,
|
||||
SLOT( savePreset() ) );
|
||||
toolTip::add( m_savePresetButton, tr( "Save preset" ) );
|
||||
|
||||
m_savePresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to save current VST-plugin presset program." ) );
|
||||
|
||||
|
||||
m_rolRPresetButton = new pixmapButton( this, "" );
|
||||
m_rolRPresetButton->setCheckable( false );
|
||||
m_rolRPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_rolRPresetButton->move( 186, 192 );
|
||||
m_rolRPresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-right-press" ) );
|
||||
m_rolRPresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-right" ) );
|
||||
connect( m_rolRPresetButton, SIGNAL( clicked() ), this,
|
||||
SLOT( rollPreset() ) );
|
||||
toolTip::add( m_rolRPresetButton, tr( "Next (+)" ) );
|
||||
|
||||
m_rolRPresetButton->setShortcut( Qt::Key_Plus );
|
||||
|
||||
m_rolRPresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to switch to another VST-plugin presset program." ) );
|
||||
|
||||
|
||||
|
||||
m_selPresetButton = new QPushButton( tr( "" ), this );
|
||||
m_selPresetButton->setGeometry( 205, 192, 16, 16 );
|
||||
|
||||
QMenu *menu = new QMenu;
|
||||
|
||||
connect( menu, SIGNAL( aboutToShow() ), this, SLOT( updateMenu() ) );
|
||||
|
||||
|
||||
m_selPresetButton->setIcon( PLUGIN_NAME::getIconPixmap( "stepper-down" ) );
|
||||
m_selPresetButton->setWhatsThis(
|
||||
tr( "Click here to select presets that are currently loaded in VST." ) );
|
||||
|
||||
m_selPresetButton->setMenu(menu);
|
||||
|
||||
|
||||
m_toggleGUIButton = new QPushButton( tr( "Show/hide GUI" ), this );
|
||||
m_toggleGUIButton->setGeometry( 20, 150, 200, 24 );
|
||||
m_toggleGUIButton->setGeometry( 20, 130, 200, 24 );
|
||||
m_toggleGUIButton->setIcon( embed::getIconPixmap( "zoom" ) );
|
||||
m_toggleGUIButton->setFont( pointSize<8>( m_toggleGUIButton->font() ) );
|
||||
connect( m_toggleGUIButton, SIGNAL( clicked() ), this,
|
||||
@@ -283,16 +463,60 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument,
|
||||
|
||||
QPushButton * note_off_all_btn = new QPushButton( tr( "Turn off all "
|
||||
"notes" ), this );
|
||||
note_off_all_btn->setGeometry( 20, 180, 200, 24 );
|
||||
note_off_all_btn->setGeometry( 20, 160, 200, 24 );
|
||||
note_off_all_btn->setIcon( embed::getIconPixmap( "state_stop" ) );
|
||||
note_off_all_btn->setFont( pointSize<8>( note_off_all_btn->font() ) );
|
||||
connect( note_off_all_btn, SIGNAL( clicked() ), this,
|
||||
SLOT( noteOffAll() ) );
|
||||
|
||||
setAcceptDrops( true );
|
||||
_instrument2 = _instrument;
|
||||
_parent2 = _parent;
|
||||
}
|
||||
|
||||
|
||||
void VestigeInstrumentView::managePlugin( void )
|
||||
{
|
||||
if ( m_vi->m_plugin != NULL && m_vi->m_subWindow == NULL ) {
|
||||
tt = new manageVestigeInstrumentView( _instrument2, _parent2, m_vi);
|
||||
} else if (m_vi->m_subWindow != NULL) {
|
||||
m_vi->m_scrollArea->show();
|
||||
m_vi->m_subWindow->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VestigeInstrumentView::updateMenu( void )
|
||||
{
|
||||
|
||||
// get all presets -
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
m_vi->m_plugin->loadPrograms( 1 );
|
||||
QWidget::update();
|
||||
|
||||
QString str = m_vi->m_plugin->presetsString();
|
||||
|
||||
QStringList list1 = str.split("|");
|
||||
|
||||
QMenu * to_menu = m_selPresetButton->menu();
|
||||
to_menu->clear();
|
||||
|
||||
QAction *presetActions[list1.size()];
|
||||
|
||||
for (int i = 0; i < list1.size(); i++) {
|
||||
presetActions[i] = new QAction(this);
|
||||
connect(presetActions[i], SIGNAL(triggered()), this, SLOT(selPreset()));
|
||||
|
||||
presetActions[i]->setText(QString("%1. %2").arg(QString::number(i+1), list1.at(i)));
|
||||
presetActions[i]->setData(i);
|
||||
if (i == lastPosInMenu) {
|
||||
presetActions[i]->setIcon(embed::getIconPixmap( "sample_file", 16, 16 ));
|
||||
} else presetActions[i]->setIcon(embed::getIconPixmap( "edit_copy", 16, 16 ));
|
||||
to_menu->addAction( presetActions[i] );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VestigeInstrumentView::~VestigeInstrumentView()
|
||||
@@ -346,6 +570,12 @@ void VestigeInstrumentView::openPlugin( void )
|
||||
return;
|
||||
}
|
||||
engine::getMixer()->lock();
|
||||
|
||||
if (tt != NULL) {
|
||||
delete tt;
|
||||
tt = NULL;
|
||||
}
|
||||
|
||||
m_vi->loadFile( ofd.selectedFiles()[0] );
|
||||
engine::getMixer()->unlock();
|
||||
if( m_vi->m_plugin && m_vi->m_plugin->pluginWidget() )
|
||||
@@ -359,6 +589,87 @@ void VestigeInstrumentView::openPlugin( void )
|
||||
|
||||
|
||||
|
||||
void VestigeInstrumentView::openPreset( void )
|
||||
{
|
||||
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
m_vi->m_plugin->openPreset( );
|
||||
bool converted;
|
||||
QString str = m_vi->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
QWidget::update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VestigeInstrumentView::savePreset( void )
|
||||
{
|
||||
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
m_vi->m_plugin->savePreset( );
|
||||
/* bool converted;
|
||||
QString str = m_vi->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
QWidget::update();*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VestigeInstrumentView::rollPreset( void )
|
||||
{
|
||||
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
m_vi->m_plugin->rollPreset( 1 );
|
||||
bool converted;
|
||||
QString str = m_vi->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
QWidget::update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VestigeInstrumentView::rolrPreset( void )
|
||||
{
|
||||
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
m_vi->m_plugin->rollPreset( -1 );
|
||||
bool converted;
|
||||
QString str = m_vi->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
QWidget::update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VestigeInstrumentView::selPreset( void )
|
||||
{
|
||||
|
||||
QAction *action = qobject_cast<QAction *>(sender());
|
||||
if (action)
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
lastPosInMenu = action->data().toInt();
|
||||
m_vi->m_plugin->rollPreset( action->data().toInt() + 2 );
|
||||
QWidget::update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VestigeInstrumentView::toggleGUI( void )
|
||||
{
|
||||
QMutexLocker ml( &m_vi->m_pluginMutex );
|
||||
@@ -458,6 +769,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * )
|
||||
p.setPen( QColor( 32, 160, 54 ) );
|
||||
|
||||
p.drawText( 10, 100, plugin_name );
|
||||
p.drawText( 10, 211, tr( "Preset" ) );
|
||||
|
||||
// m_pluginMutex.lock();
|
||||
if( m_vi->m_plugin != NULL )
|
||||
@@ -467,6 +779,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * )
|
||||
p.setFont( pointSize<8>( f ) );
|
||||
p.drawText( 10, 114, tr( "by" ) + " " +
|
||||
m_vi->m_plugin->vendorString() );
|
||||
p.drawText( 10, 225, m_vi->m_plugin->presetString() );
|
||||
}
|
||||
// m_pluginMutex.unlock();
|
||||
}
|
||||
@@ -474,6 +787,188 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * )
|
||||
|
||||
|
||||
|
||||
manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrument,
|
||||
QWidget * _parent, vestigeInstrument * m_vi2 ) :
|
||||
InstrumentView( _instrument, _parent )
|
||||
{
|
||||
m_vi = m_vi2;
|
||||
m_vi->m_scrollArea = new QScrollArea( this );
|
||||
widget = new QWidget(this);
|
||||
l = new QGridLayout( this );
|
||||
|
||||
m_vi->m_subWindow = engine::mainWindow()->workspace()->addSubWindow(new QMdiSubWindow, Qt::SubWindow |
|
||||
Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
m_vi->m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
|
||||
m_vi->m_subWindow->setFixedSize( 960, 300);
|
||||
m_vi->m_subWindow->setWidget(m_vi->m_scrollArea);
|
||||
m_vi->m_subWindow->setWindowTitle(m_vi->m_plugin->name());
|
||||
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
|
||||
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
|
||||
l->setContentsMargins( 20, 10, 10, 10 );
|
||||
l->setVerticalSpacing( 10 );
|
||||
l->setHorizontalSpacing( 23 );
|
||||
|
||||
m_syncButton = new QPushButton( tr( "VST Sync" ), this );
|
||||
connect( m_syncButton, SIGNAL( clicked() ), this,
|
||||
SLOT( syncPlugin() ) );
|
||||
m_syncButton->setWhatsThis(
|
||||
tr( "Click here if you want to synchronize all parameters with VST plugin." ) );
|
||||
|
||||
l->addWidget( m_syncButton, 0, 0, 1, 2, Qt::AlignLeft );
|
||||
|
||||
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
|
||||
bool isVstKnobs = true, isKnobFModel = true;
|
||||
|
||||
if (m_vi->vstKnobs == NULL) {
|
||||
m_vi->vstKnobs = new knob *[paramCount];
|
||||
isVstKnobs = false;
|
||||
}
|
||||
if (m_vi->knobFModel == NULL) {
|
||||
m_vi->knobFModel = new FloatModel *[paramCount];
|
||||
isKnobFModel = false;
|
||||
}
|
||||
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
|
||||
if (isVstKnobs == false) {
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
|
||||
m_vi->vstKnobs[i] = new knob( knobBright_26, this );
|
||||
m_vi->vstKnobs[i]->setHintText( list1.at(1) + ":", "");
|
||||
m_vi->vstKnobs[i]->setLabel( list1.at(1).left(15) );
|
||||
|
||||
sprintf( paramStr, "%d", i);
|
||||
m_vi->knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f,
|
||||
castModel<vestigeInstrument>(), tr( paramStr ) );
|
||||
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
m_vi->vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (int lrow = 0+1; lrow < (int(paramCount / 10) + 1)+1; lrow++) {
|
||||
for (int lcolumn = 0; lcolumn < 10; lcolumn++) {
|
||||
if (i < paramCount)
|
||||
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
l->setRowStretch( (int(paramCount / 10) + 1), 1 );
|
||||
l->setColumnStretch( 10, 1 );
|
||||
|
||||
widget->setLayout(l);
|
||||
widget->setAutoFillBackground(true);
|
||||
|
||||
m_vi->m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
|
||||
m_vi->m_scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_vi->m_scrollArea->setPalette( QApplication::palette( m_vi->m_scrollArea ) );
|
||||
m_vi->m_scrollArea->setMinimumHeight( 64 );
|
||||
|
||||
m_vi->m_scrollArea->setWidget( widget );
|
||||
|
||||
m_vi->m_subWindow->show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::syncPlugin( void )
|
||||
{
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
|
||||
float f;
|
||||
|
||||
for (int i = 0; i<(dump).size(); i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
f = (list1.at(2)).toFloat();
|
||||
m_vi->knobFModel[i]->setValue(f);
|
||||
m_vi->knobFModel[i]->setInitValue(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
manageVestigeInstrumentView::~manageVestigeInstrumentView()
|
||||
{
|
||||
delete m_vi->m_subWindow;
|
||||
m_vi->m_subWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::modelChanged( void )
|
||||
{
|
||||
m_vi = castModel<vestigeInstrument>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::setParameter( void )
|
||||
{
|
||||
|
||||
Model *action = qobject_cast<Model *>(sender());
|
||||
int knobUNID = action->displayName().toInt();
|
||||
|
||||
if ( m_vi->m_plugin != NULL ) {
|
||||
m_vi->m_plugin->setParam( knobUNID, m_vi->knobFModel[knobUNID]->value() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
if( _dee->mimeData()->hasFormat( stringPairDrag::mimeType() ) )
|
||||
{
|
||||
QString txt = _dee->mimeData()->data(
|
||||
stringPairDrag::mimeType() );
|
||||
if( txt.section( ':', 0, 0 ) == "vstplugin" )
|
||||
{
|
||||
_dee->acceptProposedAction();
|
||||
}
|
||||
else
|
||||
{
|
||||
_dee->ignore();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dee->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::dropEvent( QDropEvent * _de )
|
||||
{
|
||||
QString type = stringPairDrag::decodeKey( _de );
|
||||
QString value = stringPairDrag::decodeValue( _de );
|
||||
if( type == "vstplugin" )
|
||||
{
|
||||
m_vi->loadFile( value );
|
||||
_de->accept();
|
||||
return;
|
||||
}
|
||||
_de->ignore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::paintEvent( QPaintEvent * )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* vestige.h - instrument VeSTige for hosting VST-plugins
|
||||
*
|
||||
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -28,11 +28,15 @@
|
||||
|
||||
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QMdiSubWindow>
|
||||
#include <QtGui/QScrollArea>
|
||||
|
||||
#include "Instrument.h"
|
||||
#include "InstrumentView.h"
|
||||
#include "midi.h"
|
||||
#include "note.h"
|
||||
#include "knob.h"
|
||||
|
||||
|
||||
class QPixmap;
|
||||
@@ -68,6 +72,8 @@ public:
|
||||
|
||||
virtual PluginView * instantiateView( QWidget * _parent );
|
||||
|
||||
protected slots:
|
||||
void setParameter( void );
|
||||
|
||||
private:
|
||||
void closePlugin( void );
|
||||
@@ -79,13 +85,50 @@ private:
|
||||
QMutex m_pluginMutex;
|
||||
|
||||
QString m_pluginDLL;
|
||||
QMdiSubWindow * m_subWindow;
|
||||
QScrollArea * m_scrollArea;
|
||||
FloatModel ** knobFModel;
|
||||
knob ** vstKnobs;
|
||||
|
||||
|
||||
friend class VestigeInstrumentView;
|
||||
friend class manageVestigeInstrumentView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
class manageVestigeInstrumentView : public InstrumentView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
manageVestigeInstrumentView( Instrument * _instrument, QWidget * _parent, vestigeInstrument * m_vi2 );
|
||||
virtual ~manageVestigeInstrumentView();
|
||||
|
||||
|
||||
protected slots:
|
||||
void syncPlugin( void );
|
||||
void setParameter( void );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void dragEnterEvent( QDragEnterEvent * _dee );
|
||||
virtual void dropEvent( QDropEvent * _de );
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
|
||||
|
||||
private:
|
||||
virtual void modelChanged( void );
|
||||
|
||||
static QPixmap * s_artwork;
|
||||
|
||||
vestigeInstrument * m_vi;
|
||||
|
||||
QWidget *widget;
|
||||
QGridLayout * l;
|
||||
QPushButton * m_syncButton;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
class VestigeInstrumentView : public InstrumentView
|
||||
{
|
||||
@@ -93,10 +136,18 @@ class VestigeInstrumentView : public InstrumentView
|
||||
public:
|
||||
VestigeInstrumentView( Instrument * _instrument, QWidget * _parent );
|
||||
virtual ~VestigeInstrumentView();
|
||||
manageVestigeInstrumentView * tt;
|
||||
|
||||
|
||||
protected slots:
|
||||
void updateMenu( void );
|
||||
void openPlugin( void );
|
||||
void managePlugin( void );
|
||||
void openPreset( void );
|
||||
void savePreset( void );
|
||||
void rollPreset( void );
|
||||
void rolrPreset( void );
|
||||
void selPreset( void );
|
||||
void toggleGUI( void );
|
||||
void noteOffAll( void );
|
||||
|
||||
@@ -114,8 +165,19 @@ private:
|
||||
|
||||
vestigeInstrument * m_vi;
|
||||
|
||||
int lastPosInMenu;
|
||||
|
||||
pixmapButton * m_openPluginButton;
|
||||
pixmapButton * m_openPresetButton;
|
||||
pixmapButton * m_rolLPresetButton;
|
||||
pixmapButton * m_rolRPresetButton;
|
||||
QPushButton * m_selPresetButton;
|
||||
QPushButton * m_toggleGUIButton;
|
||||
pixmapButton * m_managePluginButton;
|
||||
pixmapButton * m_savePresetButton;
|
||||
|
||||
Instrument * _instrument2;
|
||||
QWidget * _parent2;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -163,6 +163,9 @@ public:
|
||||
// determine product-string of plugin
|
||||
const char * pluginProductString();
|
||||
|
||||
// determine name of plugipn preset
|
||||
const char * presetName();
|
||||
|
||||
// do a complete parameter-dump and post it
|
||||
void getParameterDump();
|
||||
|
||||
@@ -178,6 +181,18 @@ public:
|
||||
// restore settings chunk of plugin from file
|
||||
void loadChunkFromFile( const std::string & _file, int _len );
|
||||
|
||||
// restore settings chunk of plugin from file
|
||||
void loadChunkFromPresetFile( const std::string & _file );
|
||||
|
||||
// restore settings chunk of plugin from file
|
||||
void rotateProgram( int _len );
|
||||
|
||||
// Load names VST of presets/programs
|
||||
void loadPrograms( int _len );
|
||||
|
||||
// Save presets/programs
|
||||
void savePreset( const std::string & _file );
|
||||
|
||||
// number of inputs
|
||||
virtual int inputCount() const
|
||||
{
|
||||
@@ -386,6 +401,33 @@ bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
sendMessage( IdLoadSettingsFromFile );
|
||||
break;
|
||||
|
||||
case IdLoadChunkFromPresetFile:
|
||||
loadChunkFromPresetFile( _m.getString( 0 ) );
|
||||
sendMessage( IdLoadChunkFromPresetFile );
|
||||
break;
|
||||
|
||||
case IdRotateProgram:
|
||||
rotateProgram( _m.getInt( 0 ) );
|
||||
sendMessage( IdRotateProgram );
|
||||
break;
|
||||
|
||||
case IdLoadPrograms:
|
||||
loadPrograms( _m.getInt( 0 ) );
|
||||
sendMessage( IdLoadPrograms );
|
||||
break;
|
||||
|
||||
case IdSavePreset:
|
||||
savePreset( _m.getString( 0 ) );
|
||||
sendMessage( IdSavePreset );
|
||||
break;
|
||||
|
||||
case IdSetParameter:
|
||||
m_plugin->setParameter( m_plugin, _m.getInt( 0 ), _m.getFloat( 1 ) );
|
||||
sendMessage( IdSetParameter );
|
||||
break;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
return RemotePluginClient::processMessage( _m );
|
||||
}
|
||||
@@ -726,19 +768,34 @@ const char * RemoteVstPlugin::pluginProductString()
|
||||
|
||||
|
||||
|
||||
const char * RemoteVstPlugin::presetName()
|
||||
{
|
||||
static char buf[32];
|
||||
buf[0] = 0;
|
||||
|
||||
m_plugin->dispatcher(m_plugin, effGetProgramName, 0, 0, buf, 0);
|
||||
|
||||
buf[31] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::getParameterDump()
|
||||
{
|
||||
VstParameterProperties vst_props;
|
||||
message m( IdVstParameterDump );
|
||||
m.addInt( m_plugin->numParams );
|
||||
for( int i = 0; i < m_plugin->numParams; ++i )
|
||||
{
|
||||
pluginDispatch( effGetParameterProperties, i, 0, &vst_props );
|
||||
m.addInt( i );
|
||||
m.addString( vst_props.shortLabel );
|
||||
m.addFloat( m_plugin->getParameter( m_plugin, i ) );
|
||||
}
|
||||
sendMessage( m );
|
||||
char curPresName[30];
|
||||
//VstParameterProperties vst_props;
|
||||
message m( IdVstParameterDump );
|
||||
m.addInt( m_plugin->numParams );
|
||||
for( int i = 0; i < m_plugin->numParams; ++i )
|
||||
{
|
||||
//pluginDispatch( effGetParameterProperties, i, 0, &vst_props );
|
||||
m_plugin->dispatcher(m_plugin, effGetParamName, i, 0, curPresName, 0);
|
||||
m.addInt( i );
|
||||
m.addString( /*vst_props.shortLabel*/curPresName );
|
||||
m.addFloat( m_plugin->getParameter( m_plugin, i ) );
|
||||
}
|
||||
sendMessage( m );
|
||||
}
|
||||
|
||||
|
||||
@@ -812,6 +869,257 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file )
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::rotateProgram( int _len )
|
||||
{
|
||||
int currProgram;
|
||||
if (isInitialized() == false) return;
|
||||
if (_len <= 1) {
|
||||
currProgram = m_plugin->dispatcher(m_plugin, effGetProgram, 0, 0, 0, 0) + _len;
|
||||
if (currProgram >= m_plugin->numPrograms) currProgram = m_plugin->numPrograms - 1;
|
||||
if (currProgram < 0) currProgram = 0;
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, currProgram++, 0, 0);
|
||||
} else {
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, _len - 2, 0, 0);
|
||||
currProgram = _len - 1;
|
||||
}
|
||||
|
||||
char presName[30];
|
||||
sprintf( presName, " %d/%d: %s", currProgram, m_plugin->numPrograms, presetName() );
|
||||
|
||||
sendMessage( message( IdVstPluginPresetString ).addString( presName ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::loadPrograms( int _len )
|
||||
{
|
||||
char presName[4096];
|
||||
char curProgName[30];
|
||||
if (isInitialized() == false) return;
|
||||
bool progNameIndexed = (m_plugin->dispatcher(m_plugin, 29, 0, -1, curProgName, 0) == 1);
|
||||
|
||||
if (m_plugin->numPrograms > 1) {
|
||||
if (progNameIndexed) {
|
||||
for (int i = 0; i< (m_plugin->numPrograms >= 256?256:m_plugin->numPrograms); i++) {
|
||||
m_plugin->dispatcher(m_plugin, 29, i, -1, curProgName, 0);
|
||||
if (i == 0) sprintf( presName, "%s", curProgName );
|
||||
else sprintf( presName + strlen(presName), "|%s", curProgName );
|
||||
}
|
||||
} else {
|
||||
int currProgram = m_plugin->dispatcher(m_plugin, effGetProgram, 0, 0, 0, 0);
|
||||
for (int i = 0; i< (m_plugin->numPrograms >= 256?256:m_plugin->numPrograms); i++) {
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, i, 0, 0);
|
||||
if (i == 0) sprintf( presName, "%s", presetName() );
|
||||
else sprintf( presName + strlen(presName), "|%s", presetName() );
|
||||
}
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, currProgram, 0, 0);
|
||||
}
|
||||
} else sprintf( presName, "%s", presetName() );
|
||||
|
||||
sendMessage( message( IdVstPluginPresetsString ).addString( presName ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline unsigned int endian_swap(unsigned int& x)
|
||||
{
|
||||
return (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24);
|
||||
}
|
||||
|
||||
struct sBank
|
||||
{
|
||||
unsigned int chunkMagic;
|
||||
unsigned int byteSize;
|
||||
unsigned int fxMagic;
|
||||
unsigned int version;
|
||||
unsigned int fxID;
|
||||
unsigned int fxVersion;
|
||||
unsigned int numPrograms;
|
||||
char prgName[28];
|
||||
};
|
||||
|
||||
void RemoteVstPlugin::savePreset( const std::string & _file )
|
||||
{
|
||||
unsigned int chunk_size = 0;
|
||||
sBank * pBank = ( sBank* ) new char[ sizeof( sBank ) ];
|
||||
char progName[ 128 ] = { 0 };
|
||||
char* data = NULL;
|
||||
const bool chunky = ( m_plugin->flags & ( 1 << 5 ) ) != 0;
|
||||
bool isPreset = _file.substr( _file.find_last_of( "." ) + 1 ) == "fxp";
|
||||
int presNameLen = _file.find_last_of( "/" ) + _file.find_last_of( "\\" ) + 2;
|
||||
|
||||
if (isPreset) {
|
||||
for (int i = 0; i < _file.length() - 4 - presNameLen; i++)
|
||||
progName[i] = i < 23 ? _file[presNameLen + i] : 0;
|
||||
m_plugin->dispatcher(m_plugin, 4, 0, 0, progName, 0);
|
||||
} // m_plugin->dispatcher( m_plugin, effGetProgramName, 0, 0, progName, 0.0f );
|
||||
if ( chunky )
|
||||
chunk_size = m_plugin->dispatcher( m_plugin, 23, isPreset, 0, &data, false );
|
||||
else {
|
||||
if (isPreset) {
|
||||
chunk_size = m_plugin->numParams * sizeof( float );
|
||||
data = new char[ chunk_size ];
|
||||
unsigned int* toUIntArray = reinterpret_cast<unsigned int*>( data );
|
||||
for ( int i = 0; i < m_plugin->numParams; i++ )
|
||||
{
|
||||
float value = m_plugin->getParameter( m_plugin, i );
|
||||
unsigned int * pValue = ( unsigned int * ) &value;
|
||||
toUIntArray[ i ] = endian_swap( *pValue );
|
||||
}
|
||||
} else chunk_size = (((m_plugin->numParams * sizeof( float )) + 56)*m_plugin->numPrograms);
|
||||
}
|
||||
|
||||
pBank->chunkMagic = 0x4B6E6343;
|
||||
pBank->byteSize = chunk_size + ( chunky ? sizeof( int ) : 0 ) + 48;
|
||||
if (!isPreset) pBank->byteSize += 100;
|
||||
pBank->byteSize = endian_swap( pBank->byteSize );
|
||||
pBank->fxMagic = chunky ? 0x68435046 : 0x6B437846;
|
||||
if (!isPreset && chunky) pBank->fxMagic = 0x68434246;
|
||||
if (!isPreset &&!chunky) pBank->fxMagic = 0x6B427846;
|
||||
|
||||
pBank->version = 0x01000000;
|
||||
unsigned int uIntToFile = (unsigned int) m_plugin->uniqueID;
|
||||
pBank->fxID = endian_swap( uIntToFile );
|
||||
uIntToFile = (unsigned int) pluginVersion();
|
||||
pBank->fxVersion = endian_swap( uIntToFile );
|
||||
uIntToFile = (unsigned int) chunky ? m_plugin->numPrograms : m_plugin->numParams;
|
||||
if (!isPreset &&!chunky) uIntToFile = (unsigned int) m_plugin->numPrograms;
|
||||
pBank->numPrograms = endian_swap( uIntToFile );
|
||||
|
||||
FILE * stream = fopen( _file.c_str(), "w" );
|
||||
fwrite ( pBank, 1, 28, stream );
|
||||
fwrite ( progName, 1, isPreset ? 28 : 128, stream );
|
||||
if ( chunky ) {
|
||||
uIntToFile = endian_swap( chunk_size );
|
||||
fwrite ( &uIntToFile, 1, 4, stream );
|
||||
}
|
||||
if (pBank->fxMagic != 0x6B427846 )
|
||||
fwrite ( data, 1, chunk_size, stream );
|
||||
else {
|
||||
int numPrograms = m_plugin->numPrograms;
|
||||
int currProgram = m_plugin->dispatcher(m_plugin, effGetProgram, 0, 0, 0, 0);
|
||||
chunk_size = (m_plugin->numParams * sizeof( float ));
|
||||
pBank->byteSize = chunk_size + 48;
|
||||
pBank->byteSize = endian_swap( pBank->byteSize );
|
||||
pBank->fxMagic = 0x6B437846;
|
||||
uIntToFile = (unsigned int) m_plugin->numParams;
|
||||
pBank->numPrograms = endian_swap( uIntToFile );
|
||||
data = new char[ chunk_size ];
|
||||
unsigned int* pValue,* toUIntArray = reinterpret_cast<unsigned int*>( data );
|
||||
float value;
|
||||
for (int j = 0; j < numPrograms; j++) {
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, j, 0, 0);
|
||||
m_plugin->dispatcher(m_plugin, effGetProgramName, 0, 0, pBank->prgName, 0);
|
||||
fwrite ( pBank, 1, 56, stream );
|
||||
for ( int i = 0; i < m_plugin->numParams; i++ )
|
||||
{
|
||||
value = m_plugin->getParameter( m_plugin, i );
|
||||
pValue = ( unsigned int * ) &value;
|
||||
toUIntArray[ i ] = endian_swap( *pValue );
|
||||
}
|
||||
fwrite ( data, 1, chunk_size, stream );
|
||||
}
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, currProgram, 0, 0);
|
||||
}
|
||||
fclose( stream );
|
||||
|
||||
if ( !chunky )
|
||||
delete[] data;
|
||||
delete[] (sBank*)pBank;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::loadChunkFromPresetFile( const std::string & _file )
|
||||
{
|
||||
void * chunk = NULL;
|
||||
unsigned int * pLen = new unsigned int[ 1 ];
|
||||
unsigned int len;
|
||||
sBank * pBank = (sBank*) new char[ sizeof( sBank ) ];
|
||||
FILE * stream = fopen( _file.c_str(), "r" );
|
||||
fread ( pBank, 1, 56, stream );
|
||||
pBank->fxID = endian_swap( pBank->fxID );
|
||||
pBank->numPrograms = endian_swap( pBank->numPrograms );
|
||||
unsigned int toUInt;
|
||||
float * pFloat;
|
||||
|
||||
if (m_plugin->uniqueID != pBank->fxID) {
|
||||
sendMessage( message( IdVstPluginPresetString ).
|
||||
addString( "Error: Plugin UniqID not match" ) );
|
||||
fclose( stream );
|
||||
delete[] (unsigned int*)pLen;
|
||||
delete[] (sBank*)pBank;
|
||||
return;
|
||||
}
|
||||
|
||||
if( _file.substr( _file.find_last_of( "." ) + 1 ) != "fxp" )
|
||||
fseek ( stream , 156 , SEEK_SET );
|
||||
|
||||
if(pBank->fxMagic != 0x6B427846) {
|
||||
if(pBank->fxMagic != 0x6B437846) {
|
||||
fread (pLen, 1, 4, stream);
|
||||
chunk = new char[len = endian_swap(*pLen)];
|
||||
} else chunk = new char[len = sizeof(float)*pBank->numPrograms];
|
||||
fread (chunk, len, 1, stream);
|
||||
fclose( stream );
|
||||
}
|
||||
|
||||
if(_file.substr(_file.find_last_of(".") + 1) == "fxp") {
|
||||
pBank->prgName[23] = 0;
|
||||
m_plugin->dispatcher(m_plugin, 4, 0, 0, pBank->prgName, 0);
|
||||
if(pBank->fxMagic != 0x6B437846)
|
||||
m_plugin->dispatcher(m_plugin, 24, 1, len, chunk, 0);
|
||||
else {
|
||||
unsigned int* toUIntArray = reinterpret_cast<unsigned int*>( chunk );
|
||||
for (int i = 0; i < pBank->numPrograms; i++ ) {
|
||||
toUInt = endian_swap( toUIntArray[ i ] );
|
||||
pFloat = ( float* ) &toUInt;
|
||||
m_plugin->setParameter( m_plugin, i, *pFloat );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(pBank->fxMagic != 0x6B427846) {
|
||||
m_plugin->dispatcher(m_plugin, 24, 0, len, chunk, 0);
|
||||
} else {
|
||||
int numPrograms = pBank->numPrograms;
|
||||
unsigned int * toUIntArray;
|
||||
int currProgram = m_plugin->dispatcher(m_plugin, effGetProgram, 0, 0, 0, 0);
|
||||
chunk = new char[ len = sizeof(float)*m_plugin->numParams ];
|
||||
toUIntArray = reinterpret_cast<unsigned int *>( chunk );
|
||||
for (int i =0; i < numPrograms; i++) {
|
||||
fread (pBank, 1, 56, stream);
|
||||
fread (chunk, len, 1, stream);
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, i, 0, 0);
|
||||
pBank->prgName[23] = 0;
|
||||
m_plugin->dispatcher(m_plugin, 4, 0, 0, pBank->prgName, 0);
|
||||
for (int j = 0; j < m_plugin->numParams; j++ ) {
|
||||
toUInt = endian_swap( toUIntArray[ j ] );
|
||||
pFloat = ( float* ) &toUInt;
|
||||
m_plugin->setParameter( m_plugin, j, *pFloat );
|
||||
}
|
||||
}
|
||||
m_plugin->dispatcher(m_plugin, effSetProgram, 0, currProgram, 0, 0);
|
||||
fclose( stream );
|
||||
}
|
||||
}
|
||||
char presName[30];
|
||||
int currProgram = m_plugin->dispatcher(m_plugin, effGetProgram, 0, 0, 0, 0) + 1;
|
||||
sprintf( presName, " %d/%d: %s", currProgram, m_plugin->numPrograms, presetName() );
|
||||
|
||||
sendMessage( message( IdVstPluginPresetString ).addString( presName ) );
|
||||
|
||||
delete[] (unsigned int*)pLen;
|
||||
delete[] (sBank*)pBank;
|
||||
delete[] (char*)chunk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len )
|
||||
{
|
||||
char * buf = NULL;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "VstPlugin.h"
|
||||
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QLocale>
|
||||
@@ -86,7 +87,9 @@ VstPlugin::VstPlugin( const QString & _plugin ) :
|
||||
m_name(),
|
||||
m_version( 0 ),
|
||||
m_vendorString(),
|
||||
m_productString()
|
||||
m_productString(),
|
||||
m_presetString(),
|
||||
m_presetsString()
|
||||
{
|
||||
setSplittedChannels( true );
|
||||
|
||||
@@ -402,6 +405,14 @@ bool VstPlugin::processMessage( const message & _m )
|
||||
m_productString = _m.getQString();
|
||||
break;
|
||||
|
||||
case IdVstPluginPresetString:
|
||||
m_presetString = _m.getQString();
|
||||
break;
|
||||
|
||||
case IdVstPluginPresetsString:
|
||||
m_presetsString = _m.getQString();
|
||||
break;
|
||||
|
||||
case IdVstPluginUniqueID:
|
||||
// TODO: display graphically in case of failure
|
||||
printf("unique ID: %s\n", _m.getString().c_str() );
|
||||
@@ -420,7 +431,7 @@ bool VstPlugin::processMessage( const message & _m )
|
||||
item.value = _m.getFloat( ++p );
|
||||
m_parameterDump["param" + QString::number( item.index )] =
|
||||
QString::number( item.index ) + ":" +
|
||||
// QString( item.shortLabel ) + ":" +
|
||||
/*uncomented*/ /*QString( item.shortLabel )*/ QString::fromStdString(item.shortLabel) + ":" +
|
||||
QString::number( item.value );
|
||||
}
|
||||
break;
|
||||
@@ -435,6 +446,93 @@ bool VstPlugin::processMessage( const message & _m )
|
||||
|
||||
|
||||
|
||||
void VstPlugin::openPreset( )
|
||||
{
|
||||
|
||||
QFileDialog ofd( NULL, tr( "Open Preset" ), "",
|
||||
tr( "Vst Plugin Preset (*.fxp *.fxb)" ) );
|
||||
ofd.setFileMode( QFileDialog::ExistingFiles );
|
||||
if( ofd.exec () == QDialog::Accepted &&
|
||||
!ofd.selectedFiles().isEmpty() )
|
||||
{
|
||||
lock();
|
||||
sendMessage( message( IdLoadChunkFromPresetFile ).
|
||||
addString(
|
||||
QSTR_TO_STDSTR(
|
||||
QDir::toNativeSeparators( ofd.selectedFiles()[0] ) ) )
|
||||
);
|
||||
waitForMessage( IdLoadChunkFromPresetFile );
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::rollPreset( int step )
|
||||
{
|
||||
lock();
|
||||
sendMessage( message( IdRotateProgram ).
|
||||
addInt( step ) );
|
||||
waitForMessage( IdRotateProgram );
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::loadPrograms( int step )
|
||||
{
|
||||
lock();
|
||||
sendMessage( message( IdLoadPrograms ).
|
||||
addInt( step ) );
|
||||
waitForMessage( IdLoadPrograms );
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::savePreset( )
|
||||
{
|
||||
QString presName = this->presetString() == "" ? tr(": default"): this->presetString();
|
||||
QFileDialog sfd( NULL, tr( "Save Preset" ), presName.section(": ", 1, 1) + tr(".fxp"),
|
||||
tr( "Vst Plugin Preset (*.fxp *.fxb)" ) );
|
||||
|
||||
sfd.setAcceptMode( QFileDialog::AcceptSave );
|
||||
sfd.setFileMode( QFileDialog::AnyFile );
|
||||
if( sfd.exec () == QDialog::Accepted &&
|
||||
!sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" )
|
||||
{
|
||||
QString fns = sfd.selectedFiles()[0];
|
||||
if ((fns.toUpper().indexOf(tr(".FXP")) == -1) && (fns.toUpper().indexOf(tr(".FXB")) == -1))
|
||||
fns = fns + tr(".fxb");
|
||||
else fns = fns.left(fns.length() - 4) + (fns.right( 4 )).toLower();
|
||||
lock();
|
||||
sendMessage( message( IdSavePreset ).
|
||||
addString(
|
||||
QSTR_TO_STDSTR(
|
||||
QDir::toNativeSeparators( fns ) ) )
|
||||
);
|
||||
waitForMessage( IdSavePreset );
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::setParam( int i, float f )
|
||||
{
|
||||
lock();
|
||||
sendMessage( message( IdSetParameter ).addInt( i ).addFloat( f ) );
|
||||
waitForMessage( IdSetParameter );
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::loadChunk( const QByteArray & _chunk )
|
||||
{
|
||||
QTemporaryFile tf;
|
||||
|
||||
@@ -75,6 +75,16 @@ public:
|
||||
return m_productString;
|
||||
}
|
||||
|
||||
inline const QString & presetString() const
|
||||
{
|
||||
return m_presetString;
|
||||
}
|
||||
|
||||
inline const QString & presetsString() const
|
||||
{
|
||||
return m_presetsString;
|
||||
}
|
||||
|
||||
const QMap<QString, QString> & parameterDump();
|
||||
void setParameterDump( const QMap<QString, QString> & _pdump );
|
||||
|
||||
@@ -103,6 +113,11 @@ public:
|
||||
public slots:
|
||||
void setTempo( bpm_t _bpm );
|
||||
void updateSampleRate();
|
||||
void openPreset( void );
|
||||
void rollPreset( int step );
|
||||
void loadPrograms( int step );
|
||||
void savePreset( void );
|
||||
void setParam( int i, float f );
|
||||
|
||||
|
||||
private:
|
||||
@@ -120,6 +135,8 @@ private:
|
||||
Sint32 m_version;
|
||||
QString m_vendorString;
|
||||
QString m_productString;
|
||||
QString m_presetString;
|
||||
QString m_presetsString;
|
||||
|
||||
QMap<QString, QString> m_parameterDump;
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@ enum VstRemoteMessageIDs
|
||||
IdVstPluginVersion,
|
||||
IdVstPluginVendorString,
|
||||
IdVstPluginProductString,
|
||||
IdVstPluginPresetString,
|
||||
IdVstPluginPresetsString,
|
||||
IdVstPluginUniqueID,
|
||||
IdVstParameterCount,
|
||||
IdVstParameterDump,
|
||||
|
||||
@@ -67,6 +67,7 @@ private:
|
||||
|
||||
friend class VstEffectControls;
|
||||
friend class VstEffectControlDialog;
|
||||
friend class manageVSTEffectView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* VstEffectControlDialog.cpp - dialog for displaying VST-effect GUI
|
||||
*
|
||||
* Copyright (c) 2006-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2006-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -24,20 +24,24 @@
|
||||
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QMdiArea>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QPushButton>
|
||||
|
||||
#include "VstEffectControlDialog.h"
|
||||
#include "VstEffect.h"
|
||||
|
||||
|
||||
#include "pixmap_button.h"
|
||||
#include "tooltip.h"
|
||||
|
||||
|
||||
VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
EffectControlDialog( _ctl ),
|
||||
m_pluginWidget( NULL )
|
||||
{
|
||||
QVBoxLayout * l = new QVBoxLayout( this );
|
||||
l->setMargin( 0 );
|
||||
l->setSpacing( 0 );
|
||||
QGridLayout * l = new QGridLayout( this );
|
||||
l->setContentsMargins( 20, 10, 10, 10 );
|
||||
l->setVerticalSpacing( 2 );
|
||||
l->setHorizontalSpacing( 2 );
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
_ctl->m_effect->m_plugin->showEditor();
|
||||
@@ -47,9 +51,151 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
setWindowTitle( m_pluginWidget->windowTitle() );
|
||||
QPushButton * btn = new QPushButton( tr( "Show/hide VST FX GUI" ) );
|
||||
btn->setCheckable( true );
|
||||
l->addWidget( btn );
|
||||
l->addWidget( btn, 0, 0, 1, 13, Qt::AlignCenter );
|
||||
connect( btn, SIGNAL( toggled( bool ) ),
|
||||
m_pluginWidget, SLOT( setVisible( bool ) ) );
|
||||
btn->setMinimumWidth( 200 );
|
||||
btn->setMaximumWidth( 200 );
|
||||
btn->setMinimumHeight( 24 );
|
||||
btn->setMaximumHeight( 24 );
|
||||
|
||||
|
||||
m_managePluginButton = new pixmapButton( this, "" );
|
||||
m_managePluginButton->setCheckable( false );
|
||||
m_managePluginButton->setCursor( Qt::PointingHandCursor );
|
||||
m_managePluginButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"track_op_menu" ) );
|
||||
m_managePluginButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"track_op_menu" ) );
|
||||
connect( m_managePluginButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( managePlugin() ) );
|
||||
toolTip::add( m_managePluginButton, tr( "Control VST-plugin from LMMS host" ) );
|
||||
|
||||
m_managePluginButton->setWhatsThis(
|
||||
tr( "Click here, if you want to control VST-plugin from host." ) );
|
||||
|
||||
|
||||
m_managePluginButton->setMinimumWidth( 21 );
|
||||
m_managePluginButton->setMaximumWidth( 21 );
|
||||
m_managePluginButton->setMinimumHeight( 21 );
|
||||
m_managePluginButton->setMaximumHeight( 21 );
|
||||
|
||||
|
||||
m_openPresetButton = new pixmapButton( this, "" );
|
||||
m_openPresetButton->setCheckable( false );
|
||||
m_openPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_openPresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-up-press" ) );
|
||||
m_openPresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-up" ) );
|
||||
connect( m_openPresetButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( openPreset() ) );
|
||||
toolTip::add( m_openPresetButton, tr( "Open VST-plugin preset" ) );
|
||||
|
||||
m_openPresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to open another *.fxp, *.fxb VST-plugin preset." ) );
|
||||
|
||||
m_openPresetButton->setMinimumWidth( 16 );
|
||||
m_openPresetButton->setMaximumWidth( 16 );
|
||||
m_openPresetButton->setMinimumHeight( 16 );
|
||||
m_openPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
m_rolLPresetButton = new pixmapButton( this, "" );
|
||||
m_rolLPresetButton->setCheckable( false );
|
||||
m_rolLPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_rolLPresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-left-press" ) );
|
||||
m_rolLPresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-left" ) );
|
||||
connect( m_rolLPresetButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( rolrPreset() ) );
|
||||
toolTip::add( m_rolLPresetButton, tr( "Previous (-)" ) );
|
||||
|
||||
m_rolLPresetButton->setShortcut( Qt::Key_Minus );
|
||||
|
||||
m_rolLPresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to switch to another VST-plugin presset program." ) );
|
||||
|
||||
m_rolLPresetButton->setMinimumWidth( 16 );
|
||||
m_rolLPresetButton->setMaximumWidth( 16 );
|
||||
m_rolLPresetButton->setMinimumHeight( 16 );
|
||||
m_rolLPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
m_rolRPresetButton = new pixmapButton( this, "" );
|
||||
m_rolRPresetButton->setCheckable( false );
|
||||
m_rolRPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_rolRPresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-right-press" ) );
|
||||
m_rolRPresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"stepper-right" ) );
|
||||
connect( m_rolRPresetButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( rollPreset() ) );
|
||||
toolTip::add( m_rolRPresetButton, tr( "Next (+)" ) );
|
||||
|
||||
m_rolRPresetButton->setShortcut( Qt::Key_Plus );
|
||||
|
||||
m_rolRPresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to switch to another VST-plugin presset program." ) );
|
||||
|
||||
m_rolRPresetButton->setMinimumWidth( 16 );
|
||||
m_rolRPresetButton->setMaximumWidth( 16 );
|
||||
m_rolRPresetButton->setMinimumHeight( 16 );
|
||||
m_rolRPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
|
||||
_ctl->m_selPresetButton = new QPushButton( tr( "" ), this );
|
||||
|
||||
_ctl->m_selPresetButton->setCheckable( false );
|
||||
_ctl->m_selPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
_ctl->m_selPresetButton->setIcon( PLUGIN_NAME::getIconPixmap( "stepper-down" ) );
|
||||
_ctl->m_selPresetButton->setWhatsThis(
|
||||
tr( "Click here to select presets that are currently loaded in VST." ) );
|
||||
|
||||
_ctl->m_selPresetButton->setMenu(_ctl->menu);
|
||||
|
||||
|
||||
_ctl->m_selPresetButton->setMinimumWidth( 16 );
|
||||
_ctl->m_selPresetButton->setMaximumWidth( 16 );
|
||||
_ctl->m_selPresetButton->setMinimumHeight( 16 );
|
||||
_ctl->m_selPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
m_savePresetButton = new pixmapButton( this, "" );
|
||||
m_savePresetButton->setCheckable( false );
|
||||
m_savePresetButton->setCursor( Qt::PointingHandCursor );
|
||||
m_savePresetButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"project_save", 21, 21 ) );
|
||||
m_savePresetButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"project_save", 21, 21 ) );
|
||||
connect( m_savePresetButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( savePreset() ) );
|
||||
toolTip::add( m_savePresetButton, tr( "Save preset" ) );
|
||||
|
||||
m_savePresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to save current VST-plugin presset program." ) );
|
||||
|
||||
|
||||
m_savePresetButton->setMinimumWidth( 21 );
|
||||
m_savePresetButton->setMaximumWidth( 21 );
|
||||
m_savePresetButton->setMinimumHeight( 21 );
|
||||
m_savePresetButton->setMaximumHeight( 21 );
|
||||
|
||||
|
||||
l->addWidget( m_openPresetButton, 1, 7, Qt::AlignCenter );
|
||||
l->addWidget( m_rolLPresetButton, 1, 4, Qt::AlignCenter );
|
||||
l->addWidget( m_rolRPresetButton, 1, 5, Qt::AlignCenter );
|
||||
l->addWidget(_ctl->m_selPresetButton, 1, 6, Qt::AlignLeft );
|
||||
|
||||
l->addWidget( m_managePluginButton, 1, 10, 2, 2, Qt::AlignLeft );
|
||||
|
||||
l->addWidget( m_savePresetButton, 1, 8, 2, 2, Qt::AlignCenter );
|
||||
|
||||
l->setRowStretch( 3, 1 );
|
||||
l->setColumnStretch( 13, 1 );
|
||||
|
||||
}
|
||||
#endif
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
@@ -66,6 +212,14 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
|
||||
|
||||
|
||||
void VstEffectControlDialog::paintEvent( QPaintEvent * )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VstEffectControlDialog::~VstEffectControlDialog()
|
||||
{
|
||||
delete m_pluginWidget;
|
||||
|
||||
@@ -27,8 +27,15 @@
|
||||
|
||||
#include "EffectControlDialog.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
class VstEffectControls;
|
||||
class pixmapButton;
|
||||
class QPixmap;
|
||||
class QPushButton;
|
||||
class pixmapButton;
|
||||
|
||||
|
||||
class VstEffectControlDialog : public EffectControlDialog
|
||||
@@ -37,9 +44,19 @@ public:
|
||||
VstEffectControlDialog( VstEffectControls * _controls );
|
||||
virtual ~VstEffectControlDialog();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
|
||||
private:
|
||||
QWidget * m_pluginWidget;
|
||||
|
||||
pixmapButton * m_openPresetButton;
|
||||
pixmapButton * m_rolLPresetButton;
|
||||
pixmapButton * m_rolRPresetButton;
|
||||
pixmapButton * m_selPresetButton;
|
||||
pixmapButton * m_managePluginButton;
|
||||
pixmapButton * m_savePresetButton;
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,12 +27,33 @@
|
||||
#include "VstEffectControls.h"
|
||||
#include "VstEffect.h"
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include <QtGui/QMdiArea>
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
|
||||
VstEffectControls::VstEffectControls( VstEffect * _eff ) :
|
||||
EffectControls( _eff ),
|
||||
m_effect( _eff )
|
||||
m_effect( _eff ),
|
||||
m_subWindow( NULL ),
|
||||
knobFModel( NULL ),
|
||||
vstKnobs( NULL ),
|
||||
ctrHandle( NULL ),
|
||||
lastPosInMenu (0)
|
||||
// m_presetLabel ( NULL )
|
||||
{
|
||||
menu = new QMenu;
|
||||
connect( menu, SIGNAL( aboutToShow() ), this, SLOT( updateMenu() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VstEffectControls::~VstEffectControls()
|
||||
{
|
||||
delete ctrHandle;
|
||||
ctrHandle = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +67,29 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
if( m_effect->m_plugin != NULL )
|
||||
{
|
||||
m_effect->m_plugin->loadSettings( _this );
|
||||
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
char paramStr[35];
|
||||
vstKnobs = new knob *[paramCount];
|
||||
knobFModel = new FloatModel *[paramCount];
|
||||
QStringList list1;
|
||||
QWidget * xx = new QWidget();
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
|
||||
vstKnobs[i] = new knob( knobBright_26, xx );
|
||||
vstKnobs[i]->setHintText( list1.at(1) + ":", "");
|
||||
vstKnobs[i]->setLabel( list1.at(1).left(15) );
|
||||
|
||||
knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i]->loadSettings( _this, paramStr );
|
||||
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
|
||||
vstKnobs[i]->setModel( knobFModel[i] );
|
||||
}
|
||||
|
||||
}
|
||||
m_effect->m_pluginMutex.unlock();
|
||||
}
|
||||
@@ -53,6 +97,20 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::setParameter( void )
|
||||
{
|
||||
|
||||
Model *action = qobject_cast<Model *>(sender());
|
||||
int knobUNID = action->displayName().toInt();
|
||||
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->setParam( knobUNID, knobFModel[knobUNID]->value() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
_this.setAttribute( "plugin", m_effect->m_key.attributes["file"] );
|
||||
@@ -60,6 +118,16 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
if( m_effect->m_plugin != NULL )
|
||||
{
|
||||
m_effect->m_plugin->saveSettings( _doc, _this );
|
||||
if (knobFModel != NULL) {
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
char paramStr[35];
|
||||
for (int i = 0; i < paramCount; i++)
|
||||
if (knobFModel[i]->isAutomated() || knobFModel[i]->getControllerConnection()) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
knobFModel[i]->saveSettings( _doc, _this, paramStr );
|
||||
}
|
||||
}
|
||||
}
|
||||
m_effect->m_pluginMutex.unlock();
|
||||
}
|
||||
@@ -75,5 +143,281 @@ int VstEffectControls::controlCount()
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::managePlugin( void )
|
||||
{
|
||||
if ( m_effect->m_plugin != NULL && m_subWindow == NULL ) {
|
||||
manageVSTEffectView * tt = new manageVSTEffectView( m_effect, this);
|
||||
ctrHandle = (QObject *)tt;
|
||||
} else if (m_subWindow != NULL) {
|
||||
m_scrollArea->show();
|
||||
m_subWindow->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::savePreset( void )
|
||||
{
|
||||
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->savePreset( );
|
||||
/* bool converted;
|
||||
QString str = m_vi->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
QWidget::update();*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::updateMenu( void )
|
||||
{
|
||||
|
||||
// get all presets -
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->loadPrograms( 1 );
|
||||
///QWidget::update();
|
||||
|
||||
QString str = m_effect->m_plugin->presetsString();
|
||||
|
||||
QStringList list1 = str.split("|");
|
||||
|
||||
QMenu * to_menu = m_selPresetButton->menu();
|
||||
to_menu->clear();
|
||||
|
||||
QAction *presetActions[list1.size()];
|
||||
|
||||
for (int i = 0; i < list1.size(); i++) {
|
||||
presetActions[i] = new QAction(this);
|
||||
connect(presetActions[i], SIGNAL(triggered()), this, SLOT(selPreset()));
|
||||
|
||||
presetActions[i]->setText(QString("%1. %2").arg(QString::number(i+1), list1.at(i)));
|
||||
presetActions[i]->setData(i);
|
||||
if (i == lastPosInMenu) {
|
||||
presetActions[i]->setIcon(embed::getIconPixmap( "sample_file", 16, 16 ));
|
||||
} else presetActions[i]->setIcon(embed::getIconPixmap( "edit_copy", 16, 16 ));
|
||||
to_menu->addAction( presetActions[i] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::openPreset( void )
|
||||
{
|
||||
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->openPreset( );
|
||||
bool converted;
|
||||
QString str = m_effect->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
//QWidget::update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::rollPreset( void )
|
||||
{
|
||||
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->rollPreset( 1 );
|
||||
bool converted;
|
||||
QString str = m_effect->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
//QWidget::update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::rolrPreset( void )
|
||||
{
|
||||
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->rollPreset( -1 );
|
||||
bool converted;
|
||||
QString str = m_effect->m_plugin->presetString().section("/", 0, 0);
|
||||
if (str != "")
|
||||
lastPosInMenu = str.toInt(&converted, 10) - 1;
|
||||
//QWidget::update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::selPreset( void )
|
||||
{
|
||||
|
||||
QAction *action = qobject_cast<QAction *>(sender());
|
||||
if (action)
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
lastPosInMenu = action->data().toInt();
|
||||
m_effect->m_plugin->rollPreset( lastPosInMenu + 2 );
|
||||
//QWidget::update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstEffectControls::paintEvent( QPaintEvent * )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls * m_vi ) :
|
||||
m_effect( _eff )
|
||||
{
|
||||
m_vi2 = m_vi;
|
||||
widget = new QWidget();
|
||||
m_vi->m_scrollArea = new QScrollArea( widget );
|
||||
l = new QGridLayout( widget );
|
||||
|
||||
m_vi->m_subWindow = engine::mainWindow()->workspace()->addSubWindow(new QMdiSubWindow, Qt::SubWindow |
|
||||
Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
m_vi->m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
|
||||
m_vi->m_subWindow->setFixedSize( 960, 300);
|
||||
m_vi->m_subWindow->setWidget(m_vi->m_scrollArea);
|
||||
m_vi->m_subWindow->setWindowTitle(_eff->m_plugin->name());
|
||||
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
|
||||
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
|
||||
l->setContentsMargins( 20, 10, 10, 10 );
|
||||
l->setVerticalSpacing( 10 );
|
||||
l->setHorizontalSpacing( 23 );
|
||||
|
||||
m_syncButton = new QPushButton( tr( "VST Sync" ), widget );
|
||||
connect( m_syncButton, SIGNAL( clicked() ), this,
|
||||
SLOT( syncPlugin() ) );
|
||||
m_syncButton->setWhatsThis(
|
||||
tr( "Click here if you want to synchronize all parameters with VST plugin." ) );
|
||||
|
||||
l->addWidget( m_syncButton, 0, 0, 1, 2, Qt::AlignLeft );
|
||||
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
|
||||
bool isVstKnobs = true, isKnobFModel = true;
|
||||
|
||||
|
||||
if (m_vi->vstKnobs == NULL) {
|
||||
m_vi->vstKnobs = new knob *[paramCount];
|
||||
isVstKnobs = false;
|
||||
}
|
||||
if (m_vi->knobFModel == NULL) {
|
||||
m_vi->knobFModel = new FloatModel *[paramCount];
|
||||
isKnobFModel = false;
|
||||
}
|
||||
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
|
||||
if (isVstKnobs == false) {
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
|
||||
m_vi->vstKnobs[i] = new knob( knobBright_26, widget);
|
||||
m_vi->vstKnobs[i]->setHintText( list1.at(1) + ":", "");
|
||||
m_vi->vstKnobs[i]->setLabel( list1.at(1).left(15) );
|
||||
|
||||
sprintf( paramStr, "%d", i);
|
||||
m_vi->knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f,
|
||||
_eff, tr( paramStr ) );
|
||||
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
m_vi->vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (int lrow = 0+1; lrow < (int(paramCount / 10) + 1)+1; lrow++) {
|
||||
for (int lcolumn = 0; lcolumn < 10; lcolumn++) {
|
||||
if (i < paramCount)
|
||||
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
l->setRowStretch( (int(paramCount / 10) + 1), 1 );
|
||||
l->setColumnStretch( 10, 1 );
|
||||
|
||||
widget->setLayout(l);
|
||||
widget->setAutoFillBackground(true);
|
||||
|
||||
m_vi->m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
|
||||
m_vi->m_scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_vi->m_scrollArea->setPalette( QApplication::palette( m_vi->m_scrollArea ) );
|
||||
m_vi->m_scrollArea->setMinimumHeight( 64 );
|
||||
|
||||
m_vi->m_scrollArea->setWidget( widget );
|
||||
|
||||
m_vi->m_subWindow->show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVSTEffectView::syncPlugin( void )
|
||||
{
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
float f;
|
||||
|
||||
for (int i = 0; i<(dump).size(); i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
f = (list1.at(2)).toFloat();
|
||||
m_vi2->knobFModel[i]->setValue(f);
|
||||
m_vi2->knobFModel[i]->setInitValue(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVSTEffectView::setParameter( void )
|
||||
{
|
||||
|
||||
Model *action = qobject_cast<Model *>(sender());
|
||||
int knobUNID = action->displayName().toInt();
|
||||
|
||||
if ( m_effect->m_plugin != NULL ) {
|
||||
m_effect->m_plugin->setParam( knobUNID, m_vi2->knobFModel[knobUNID]->value() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
manageVSTEffectView::~manageVSTEffectView()
|
||||
{
|
||||
delete m_vi2->m_subWindow;
|
||||
m_vi2->m_subWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "moc_VstEffectControls.cxx"
|
||||
|
||||
|
||||
@@ -28,6 +28,17 @@
|
||||
#include "EffectControls.h"
|
||||
#include "VstEffectControlDialog.h"
|
||||
|
||||
#include <QtGui/QMenu>
|
||||
#include "embed.h"
|
||||
#include <QtGui/QPushButton>
|
||||
|
||||
#include <QtGui/QMdiSubWindow>
|
||||
#include <QtGui/QScrollArea>
|
||||
#include "knob.h"
|
||||
#include <QtGui/QLayout>
|
||||
#include <QPainter>
|
||||
#include <QObject>
|
||||
|
||||
|
||||
class VstEffect;
|
||||
|
||||
@@ -37,9 +48,7 @@ class VstEffectControls : public EffectControls
|
||||
Q_OBJECT
|
||||
public:
|
||||
VstEffectControls( VstEffect * _eff );
|
||||
virtual ~VstEffectControls()
|
||||
{
|
||||
}
|
||||
virtual ~VstEffectControls();
|
||||
|
||||
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
|
||||
virtual void loadSettings( const QDomElement & _this );
|
||||
@@ -56,10 +65,70 @@ public:
|
||||
}
|
||||
|
||||
|
||||
protected slots:
|
||||
void updateMenu( void );
|
||||
void openPlugin( void );
|
||||
void managePlugin( void );
|
||||
void openPreset( void );
|
||||
void savePreset( void );
|
||||
void rollPreset( void );
|
||||
void rolrPreset( void );
|
||||
void selPreset( void );
|
||||
void setParameter( void );
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
|
||||
private:
|
||||
VstEffect * m_effect;
|
||||
|
||||
QPushButton * m_selPresetButton;
|
||||
QMenu *menu;
|
||||
|
||||
QMdiSubWindow * m_subWindow;
|
||||
QScrollArea * m_scrollArea;
|
||||
FloatModel ** knobFModel;
|
||||
knob ** vstKnobs;
|
||||
|
||||
QObject * ctrHandle;
|
||||
|
||||
int lastPosInMenu;
|
||||
// QLabel * m_presetLabel;
|
||||
|
||||
friend class VstEffectControlDialog;
|
||||
friend class manageVSTEffectView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
class manageVSTEffectView : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
manageVSTEffectView( VstEffect * _eff, VstEffectControls * m_vi );
|
||||
virtual ~manageVSTEffectView();
|
||||
|
||||
|
||||
protected slots:
|
||||
void syncPlugin( void );
|
||||
void setParameter( void );
|
||||
|
||||
private:
|
||||
|
||||
// static QPixmap * s_artwork;
|
||||
|
||||
VstEffectControls * m_vi2;
|
||||
|
||||
|
||||
VstEffect * m_effect;
|
||||
|
||||
|
||||
QWidget *widget;
|
||||
QGridLayout * l;
|
||||
|
||||
QPushButton * m_syncButton;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||