Merge branch 'stable-0.4' into next
This commit is contained in:
@@ -2,6 +2,7 @@ ADD_SUBDIRECTORY(audio_file_processor)
|
||||
ADD_SUBDIRECTORY(bass_booster)
|
||||
ADD_SUBDIRECTORY(bit_invader)
|
||||
ADD_SUBDIRECTORY(flp_import)
|
||||
ADD_SUBDIRECTORY(HydrogenImport)
|
||||
ADD_SUBDIRECTORY(kicker)
|
||||
ADD_SUBDIRECTORY(ladspa_browser)
|
||||
ADD_SUBDIRECTORY(ladspa_effect)
|
||||
|
||||
4
plugins/HydrogenImport/CMakeLists.txt
Normal file
4
plugins/HydrogenImport/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
|
||||
BUILD_PLUGIN(hydrogenimport HydrogenImport.cpp HydrogenImport.h local_file_mgr.cpp LocalFileMng.h)
|
||||
|
||||
404
plugins/HydrogenImport/HydrogenImport.cpp
Normal file
404
plugins/HydrogenImport/HydrogenImport.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
#include <QtXml/QDomDocument>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QProgressDialog>
|
||||
#include <QTextStream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "LocalFileMng.h"
|
||||
#include "HydrogenImport.h"
|
||||
#include "song.h"
|
||||
#include "engine.h"
|
||||
#include "Instrument.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "note.h"
|
||||
#include "pattern.h"
|
||||
#include "track.h"
|
||||
#include "bb_track.h"
|
||||
#include "bb_track_container.h"
|
||||
#include "Instrument.h"
|
||||
|
||||
#define MAX_LAYERS 4
|
||||
extern "C"
|
||||
{
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT hydrogenimport_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY( PLUGIN_NAME ),
|
||||
"Hydrogen Import",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"Filter for importing Hydrogen files into LMMS" ),
|
||||
"frank mather",
|
||||
0x0100,
|
||||
Plugin::ImportFilter,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
QString filename;
|
||||
class NoteKey
|
||||
{
|
||||
public:
|
||||
enum Key {
|
||||
C = 0,
|
||||
Cs,
|
||||
D,
|
||||
Ef,
|
||||
E,
|
||||
F,
|
||||
Fs,
|
||||
G,
|
||||
Af,
|
||||
A,
|
||||
Bf,
|
||||
B,
|
||||
};
|
||||
|
||||
static int stringToNoteKey( const QString& str )
|
||||
{
|
||||
int m_key;
|
||||
|
||||
|
||||
QString sKey = str.left( str.length() - 1 );
|
||||
QString sOct = str.mid( str.length() - 1, str.length() );
|
||||
|
||||
if ( sKey.endsWith( "-" ) )
|
||||
{
|
||||
sKey.replace( "-", "" );
|
||||
sOct.insert( 0, "-" );
|
||||
}
|
||||
int nOctave = sOct.toInt();
|
||||
|
||||
if ( sKey == "C" )
|
||||
{
|
||||
m_key = NoteKey::C;
|
||||
}
|
||||
else if ( sKey == "Cs" )
|
||||
{
|
||||
m_key = NoteKey::Cs;
|
||||
}
|
||||
else if ( sKey == "D" )
|
||||
{
|
||||
m_key = NoteKey::D;
|
||||
}
|
||||
else if ( sKey == "Ef" )
|
||||
{
|
||||
m_key = NoteKey::Ef;
|
||||
}
|
||||
else if ( sKey == "E" )
|
||||
{
|
||||
m_key = NoteKey::E;
|
||||
}
|
||||
else if ( sKey == "F" )
|
||||
{
|
||||
m_key = NoteKey::F;
|
||||
}
|
||||
else if ( sKey == "Fs" )
|
||||
{
|
||||
m_key = NoteKey::Fs;
|
||||
}
|
||||
else if ( sKey == "G" )
|
||||
{
|
||||
m_key = NoteKey::G;
|
||||
}
|
||||
else if ( sKey == "Af" )
|
||||
{
|
||||
m_key = NoteKey::Af;
|
||||
}
|
||||
else if ( sKey == "A" )
|
||||
{
|
||||
m_key = NoteKey::A;
|
||||
}
|
||||
else if ( sKey == "Bf" )
|
||||
{
|
||||
m_key = NoteKey::Bf;
|
||||
}
|
||||
else if ( sKey == "B" ) {
|
||||
m_key = NoteKey::B;
|
||||
}
|
||||
return m_key + (nOctave*12)+57;
|
||||
}
|
||||
|
||||
};
|
||||
HydrogenImport::HydrogenImport( const QString & _file ) :
|
||||
ImportFilter( _file, &hydrogenimport_plugin_descriptor )
|
||||
{
|
||||
filename = _file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HydrogenImport::~HydrogenImport()
|
||||
{
|
||||
}
|
||||
Instrument * ins;
|
||||
bool HydrogenImport::readSong()
|
||||
{
|
||||
QHash<QString, InstrumentTrack *> drum_track;
|
||||
QHash<QString, int> pattern_length;
|
||||
QHash<QString, int> pattern_id;
|
||||
|
||||
song *s = engine::getSong();
|
||||
int song_num_tracks = s->tracks().size();
|
||||
if ( QFile( filename ).exists() == false )
|
||||
{
|
||||
printf( "Song file not found \n" );
|
||||
return false;
|
||||
}
|
||||
QDomDocument doc = LocalFileMng::openXmlDocument( filename );
|
||||
QDomNodeList nodeList = doc.elementsByTagName( "song" );
|
||||
|
||||
if( nodeList.isEmpty() )
|
||||
{
|
||||
printf( "Error reading song: song node not found\n" );
|
||||
return NULL;
|
||||
}
|
||||
QDomNode songNode = nodeList.at( 0 );
|
||||
|
||||
QString m_sSongVersion = LocalFileMng::readXmlString( songNode , "version", "Unknown version" );
|
||||
|
||||
|
||||
|
||||
|
||||
float fBpm = LocalFileMng::readXmlFloat( songNode, "bpm", 120 );
|
||||
float fVolume = LocalFileMng::readXmlFloat( songNode, "volume", 0.5 );
|
||||
float fMetronomeVolume = LocalFileMng::readXmlFloat( songNode, "metronomeVolume", 0.5 );
|
||||
QString sName( LocalFileMng::readXmlString( songNode, "name", "Untitled Song" ) );
|
||||
QString sAuthor( LocalFileMng::readXmlString( songNode, "author", "Unknown Author" ) );
|
||||
QString sNotes( LocalFileMng::readXmlString( songNode, "notes", "..." ) );
|
||||
QString sLicense( LocalFileMng::readXmlString( songNode, "license", "Unknown license" ) );
|
||||
bool bLoopEnabled = LocalFileMng::readXmlBool( songNode, "loopEnabled", false );
|
||||
QString sMode = LocalFileMng::readXmlString( songNode, "mode", "pattern" );
|
||||
|
||||
|
||||
float fHumanizeTimeValue = LocalFileMng::readXmlFloat( songNode, "humanize_time", 0.0 );
|
||||
float fHumanizeVelocityValue = LocalFileMng::readXmlFloat( songNode, "humanize_velocity", 0.0 );
|
||||
float fSwingFactor = LocalFileMng::readXmlFloat( songNode, "swing_factor", 0.0 );
|
||||
|
||||
|
||||
QDomNode instrumentListNode = songNode.firstChildElement( "instrumentList" );
|
||||
if ( ( ! instrumentListNode.isNull() ) )
|
||||
{
|
||||
|
||||
int instrumentList_count = 0;
|
||||
QDomNode instrumentNode;
|
||||
instrumentNode = instrumentListNode.firstChildElement( "instrument" );
|
||||
while ( ! instrumentNode.isNull() )
|
||||
{
|
||||
instrumentList_count++;
|
||||
QString sId = LocalFileMng::readXmlString( instrumentNode, "id", "" ); // instrument id
|
||||
QString sDrumkit = LocalFileMng::readXmlString( instrumentNode, "drumkit", "" ); // drumkit
|
||||
QString sName = LocalFileMng::readXmlString( instrumentNode, "name", "" ); // name
|
||||
float fVolume = LocalFileMng::readXmlFloat( instrumentNode, "volume", 1.0 ); // volume
|
||||
bool bIsMuted = LocalFileMng::readXmlBool( instrumentNode, "isMuted", false ); // is muted
|
||||
float fPan_L = LocalFileMng::readXmlFloat( instrumentNode, "pan_L", 0.5 ); // pan L
|
||||
float fPan_R = LocalFileMng::readXmlFloat( instrumentNode, "pan_R", 0.5 ); // pan R
|
||||
float fFX1Level = LocalFileMng::readXmlFloat( instrumentNode, "FX1Level", 0.0 ); // FX level
|
||||
float fFX2Level = LocalFileMng::readXmlFloat( instrumentNode, "FX2Level", 0.0 ); // FX level
|
||||
float fFX3Level = LocalFileMng::readXmlFloat( instrumentNode, "FX3Level", 0.0 ); // FX level
|
||||
float fFX4Level = LocalFileMng::readXmlFloat( instrumentNode, "FX4Level", 0.0 ); // FX level
|
||||
float fGain = LocalFileMng::readXmlFloat( instrumentNode, "gain", 1.0, false, false ); // instrument gain
|
||||
|
||||
|
||||
int fAttack = LocalFileMng::readXmlInt( instrumentNode, "Attack", 0, false, false ); // Attack
|
||||
int fDecay = LocalFileMng::readXmlInt( instrumentNode, "Decay", 0, false, false ); // Decay
|
||||
float fSustain = LocalFileMng::readXmlFloat( instrumentNode, "Sustain", 1.0, false, false ); // Sustain
|
||||
int fRelease = LocalFileMng::readXmlInt( instrumentNode, "Release", 1000, false, false ); // Release
|
||||
|
||||
float fRandomPitchFactor = LocalFileMng::readXmlFloat( instrumentNode, "randomPitchFactor", 0.0f, false, false );
|
||||
|
||||
bool bFilterActive = LocalFileMng::readXmlBool( instrumentNode, "filterActive", false );
|
||||
float fFilterCutoff = LocalFileMng::readXmlFloat( instrumentNode, "filterCutoff", 1.0f, false );
|
||||
float fFilterResonance = LocalFileMng::readXmlFloat( instrumentNode, "filterResonance", 0.0f, false );
|
||||
QString sMuteGroup = LocalFileMng::readXmlString( instrumentNode, "muteGroup", "-1", false );
|
||||
QString sMidiOutChannel = LocalFileMng::readXmlString( instrumentNode, "midiOutChannel", "-1", false, false );
|
||||
QString sMidiOutNote = LocalFileMng::readXmlString( instrumentNode, "midiOutNote", "60", false, false );
|
||||
int nMuteGroup = sMuteGroup.toInt();
|
||||
bool isStopNote = LocalFileMng::readXmlBool( instrumentNode, "isStopNote", false );
|
||||
int nMidiOutChannel = sMidiOutChannel.toInt();
|
||||
int nMidiOutNote = sMidiOutNote.toInt();
|
||||
|
||||
if ( sId.isEmpty() ) {
|
||||
printf( "Empty ID for instrument. skipping \n" );
|
||||
instrumentNode = (QDomNode) instrumentNode.nextSiblingElement( "instrument" );
|
||||
continue;
|
||||
}
|
||||
QDomNode filenameNode = instrumentNode.firstChildElement( "filename" );
|
||||
|
||||
if ( ! filenameNode.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned nLayer = 0;
|
||||
QDomNode layerNode = instrumentNode.firstChildElement( "layer" );
|
||||
while ( ! layerNode.isNull() )
|
||||
{
|
||||
if ( nLayer >= MAX_LAYERS )
|
||||
{
|
||||
printf( "nLayer >= MAX_LAYERS" );
|
||||
continue;
|
||||
}
|
||||
QString sFilename = LocalFileMng::readXmlString( layerNode, "filename", "" );
|
||||
bool sIsModified = LocalFileMng::readXmlBool( layerNode, "ismodified", false );
|
||||
QString sMode = LocalFileMng::readXmlString( layerNode, "smode", "forward" );
|
||||
unsigned sStartframe = LocalFileMng::readXmlInt( layerNode, "startframe", 0 );
|
||||
unsigned sLoopFrame = LocalFileMng::readXmlInt( layerNode, "loopframe", 0 );
|
||||
int sLoops = LocalFileMng::readXmlInt( layerNode, "loops", 0 );
|
||||
unsigned sEndframe = LocalFileMng::readXmlInt( layerNode, "endframe", 0 );
|
||||
bool sUseRubber = LocalFileMng::readXmlInt( layerNode, "userubber", 0, false );
|
||||
float sRubberDivider = LocalFileMng::readXmlFloat( layerNode, "rubberdivider", 0.0 );
|
||||
int sRubberCsettings = LocalFileMng::readXmlInt( layerNode, "rubberCsettings", 1 );
|
||||
int sRubberPitch = LocalFileMng::readXmlFloat( layerNode, "rubberPitch", 0.0 );
|
||||
|
||||
float fMin = LocalFileMng::readXmlFloat( layerNode, "min", 0.0 );
|
||||
float fMax = LocalFileMng::readXmlFloat( layerNode, "max", 1.0 );
|
||||
float fGain = LocalFileMng::readXmlFloat( layerNode, "gain", 1.0 );
|
||||
float fPitch = LocalFileMng::readXmlFloat( layerNode, "pitch", 0.0, false, false );
|
||||
if ( nLayer == 0 )
|
||||
{
|
||||
drum_track[sId] = ( InstrumentTrack * ) track::create( track::InstrumentTrack,engine::getBBTrackContainer() );
|
||||
drum_track[sId]->volumeModel()->setValue( fVolume * 100 );
|
||||
drum_track[sId]->panningModel()->setValue( ( fPan_R - fPan_L ) * 100 );
|
||||
ins = drum_track[sId]->loadInstrument( "audiofileprocessor" );
|
||||
ins->loadFile( sFilename );
|
||||
}
|
||||
nLayer++;
|
||||
layerNode = ( QDomNode ) layerNode.nextSiblingElement( "layer" );
|
||||
}
|
||||
}
|
||||
|
||||
instrumentNode = (QDomNode) instrumentNode.nextSiblingElement( "instrument" );
|
||||
}
|
||||
if ( instrumentList_count == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QDomNode patterns = songNode.firstChildElement( "patternList" );
|
||||
int pattern_count = 0;
|
||||
int nbb = engine::getBBTrackContainer()->numOfBBs();
|
||||
QDomNode patternNode = patterns.firstChildElement( "pattern" );
|
||||
int pn = 1;
|
||||
while ( !patternNode.isNull() )
|
||||
{
|
||||
if ( pn > 0 )
|
||||
{
|
||||
pattern_count++;
|
||||
s->addBBTrack();
|
||||
pn = 0;
|
||||
}
|
||||
QString sName; // name
|
||||
sName = LocalFileMng::readXmlString( patternNode, "name", sName );
|
||||
|
||||
QString sCategory = ""; // category
|
||||
sCategory = LocalFileMng::readXmlString( patternNode, "category", sCategory ,false ,false );
|
||||
int nSize = -1;
|
||||
nSize = LocalFileMng::readXmlInt( patternNode, "size", nSize, false, false );
|
||||
pattern_length[sName] = nSize;
|
||||
QDomNode pNoteListNode = patternNode.firstChildElement( "noteList" );
|
||||
if ( ! pNoteListNode.isNull() ) {
|
||||
QDomNode noteNode = pNoteListNode.firstChildElement( "note" );
|
||||
while ( ! noteNode.isNull() ) {
|
||||
unsigned nPosition = LocalFileMng::readXmlInt( noteNode, "position", 0 );
|
||||
float fLeadLag = LocalFileMng::readXmlFloat( noteNode, "leadlag", 0.0 , false , false );
|
||||
float fVelocity = LocalFileMng::readXmlFloat( noteNode, "velocity", 0.8f );
|
||||
float fPan_L = LocalFileMng::readXmlFloat( noteNode, "pan_L", 0.5 );
|
||||
float fPan_R = LocalFileMng::readXmlFloat( noteNode, "pan_R", 0.5 );
|
||||
int nLength = LocalFileMng::readXmlInt( noteNode, "length", -1, true );
|
||||
float nPitch = LocalFileMng::readXmlFloat( noteNode, "pitch", 0.0, false, false );
|
||||
QString sKey = LocalFileMng::readXmlString( noteNode, "key", "C0", false, false );
|
||||
QString nNoteOff = LocalFileMng::readXmlString( noteNode, "note_off", "false", false, false );
|
||||
|
||||
QString instrId = LocalFileMng::readXmlString( noteNode, "instrument", 0,false, false );
|
||||
int i = pattern_count - 1 + nbb;
|
||||
pattern_id[sName] = pattern_count - 1;
|
||||
pattern *p = dynamic_cast<pattern *>( drum_track[instrId]->getTCO( i ) );
|
||||
note n;
|
||||
n.setPos( nPosition );
|
||||
if ( (nPosition + 48) <= nSize )
|
||||
{
|
||||
n.setLength( 48 );
|
||||
}
|
||||
else
|
||||
{
|
||||
n.setLength( nSize - nPosition );
|
||||
}
|
||||
n.setVolume( fVelocity * 100 );
|
||||
n.setPanning( ( fPan_R - fPan_L ) * 100 );
|
||||
n.setKey( NoteKey::stringToNoteKey( sKey ) );
|
||||
p->addNote( n,false );
|
||||
pn = pn + 1;
|
||||
noteNode = ( QDomNode ) noteNode.nextSiblingElement( "note" );
|
||||
}
|
||||
}
|
||||
patternNode = ( QDomNode ) patternNode.nextSiblingElement( "pattern" );
|
||||
}
|
||||
// Pattern sequence
|
||||
QDomNode patternSequenceNode = songNode.firstChildElement( "patternSequence" );
|
||||
QDomNode groupNode = patternSequenceNode.firstChildElement( "group" );
|
||||
int pos = 0;
|
||||
while ( !groupNode.isNull() )
|
||||
{
|
||||
int best_length = 0;
|
||||
QDomNode patternId = groupNode.firstChildElement( "patternID" );
|
||||
while ( !patternId.isNull() )
|
||||
{
|
||||
QString patId = patternId.firstChild().nodeValue();
|
||||
patternId = ( QDomNode ) patternId.nextSiblingElement( "patternID" );
|
||||
|
||||
int i = pattern_id[patId]+song_num_tracks;
|
||||
track *t = ( bbTrack * ) s->tracks().at( i );
|
||||
trackContentObject *tco = t->createTCO( pos );
|
||||
tco->movePosition( pos );
|
||||
|
||||
|
||||
if ( pattern_length[patId] > best_length )
|
||||
{
|
||||
best_length = pattern_length[patId];
|
||||
}
|
||||
}
|
||||
pos = pos + best_length;
|
||||
groupNode = groupNode.nextSiblingElement( "group" );
|
||||
}
|
||||
|
||||
if ( pattern_count == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool HydrogenImport::tryImport( trackContainer * _tc )
|
||||
{
|
||||
if( openFile() == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return readSong();
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data )
|
||||
{
|
||||
return new HydrogenImport( QString::fromUtf8(
|
||||
static_cast<const char *>( _data ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
27
plugins/HydrogenImport/HydrogenImport.h
Normal file
27
plugins/HydrogenImport/HydrogenImport.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef _HYDROGEN_IMPORT_H
|
||||
#define _HYDROGEN_IMPORT_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include "ImportFilter.h"
|
||||
|
||||
|
||||
class HydrogenImport : public ImportFilter
|
||||
{
|
||||
public:
|
||||
HydrogenImport( const QString & _file );
|
||||
bool readSong();
|
||||
|
||||
virtual ~HydrogenImport();
|
||||
|
||||
virtual PluginView * instantiateView( QWidget * )
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
private:
|
||||
virtual bool tryImport( trackContainer * _tc );
|
||||
};
|
||||
#endif
|
||||
|
||||
29
plugins/HydrogenImport/LocalFileMng.h
Normal file
29
plugins/HydrogenImport/LocalFileMng.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef LFILEMNG_H
|
||||
#define LFILEMNG_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <QDomDocument>
|
||||
|
||||
class LocalFileMng
|
||||
{
|
||||
public:
|
||||
LocalFileMng();
|
||||
~LocalFileMng();
|
||||
std::vector<QString> getallPatternList(){
|
||||
return m_allPatternList;
|
||||
}
|
||||
|
||||
static QString readXmlString( QDomNode , const QString& nodeName, const QString& defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
|
||||
static float readXmlFloat( QDomNode , const QString& nodeName, float defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
|
||||
static int readXmlInt( QDomNode , const QString& nodeName, int defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
|
||||
static bool readXmlBool( QDomNode , const QString& nodeName, bool defaultValue, bool bShouldExists = true , bool tinyXmlCompatMode = false );
|
||||
static void convertFromTinyXMLString( QByteArray* str );
|
||||
static bool checkTinyXMLCompatMode( const QString& filename );
|
||||
static QDomDocument openXmlDocument( const QString& filename );
|
||||
std::vector<QString> m_allPatternList;
|
||||
};
|
||||
#endif //LFILEMNG_H
|
||||
|
||||
234
plugins/HydrogenImport/local_file_mgr.cpp
Normal file
234
plugins/HydrogenImport/local_file_mgr.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QApplication>
|
||||
#include <QVector>
|
||||
#include <QDomDocument>
|
||||
#include <QLocale>
|
||||
#include <QTextCodec>
|
||||
|
||||
#include <algorithm>
|
||||
#include "LocalFileMng.h"
|
||||
|
||||
|
||||
/* New QtXml based methods */
|
||||
|
||||
QString LocalFileMng::readXmlString( QDomNode node , const QString& nodeName, const QString& defaultValue, bool bCanBeEmpty, bool bShouldExists, bool tinyXmlCompatMode)
|
||||
{
|
||||
QDomElement element = node.firstChildElement( nodeName );
|
||||
|
||||
if( !node.isNull() && !element.isNull() ){
|
||||
if( !element.text().isEmpty() ){
|
||||
return element.text();
|
||||
} else {
|
||||
if ( !bCanBeEmpty ) {
|
||||
//_WARNINGLOG( "Using default value in " + nodeName );
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
} else {
|
||||
if( bShouldExists ){
|
||||
//_WARNINGLOG( "'" + nodeName + "' node not found" );
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
float LocalFileMng::readXmlFloat( QDomNode node , const QString& nodeName, float defaultValue, bool bCanBeEmpty, bool bShouldExists, bool tinyXmlCompatMode)
|
||||
{
|
||||
QLocale c_locale = QLocale::c();
|
||||
QDomElement element = node.firstChildElement( nodeName );
|
||||
|
||||
if( !node.isNull() && !element.isNull() ){
|
||||
if( !element.text().isEmpty() ){
|
||||
return c_locale.toFloat(element.text());
|
||||
} else {
|
||||
if ( !bCanBeEmpty ) {
|
||||
//_WARNINGLOG( "Using default value in " + nodeName );
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
} else {
|
||||
if( bShouldExists ){
|
||||
//_WARNINGLOG( "'" + nodeName + "' node not found" );
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
int LocalFileMng::readXmlInt( QDomNode node , const QString& nodeName, int defaultValue, bool bCanBeEmpty, bool bShouldExists, bool tinyXmlCompatMode)
|
||||
{
|
||||
QLocale c_locale = QLocale::c();
|
||||
QDomElement element = node.firstChildElement( nodeName );
|
||||
|
||||
if( !node.isNull() && !element.isNull() ){
|
||||
if( !element.text().isEmpty() ){
|
||||
return c_locale.toInt( element.text() );
|
||||
} else {
|
||||
if ( !bCanBeEmpty ) {
|
||||
//_WARNINGLOG( "Using default value in " + nodeName );
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
} else {
|
||||
if( bShouldExists ){
|
||||
//_WARNINGLOG( "'" + nodeName + "' node not found" );
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalFileMng::readXmlBool( QDomNode node , const QString& nodeName, bool defaultValue, bool bShouldExists, bool tinyXmlCompatMode)
|
||||
{
|
||||
QDomElement element = node.firstChildElement( nodeName );
|
||||
|
||||
if( !node.isNull() && !element.isNull() ){
|
||||
if( !element.text().isEmpty() ){
|
||||
if( element.text() == "true"){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//_WARNINGLOG( "Using default value in " + nodeName );
|
||||
return defaultValue;
|
||||
}
|
||||
} else {
|
||||
if( bShouldExists ){
|
||||
//_WARNINGLOG( "'" + nodeName + "' node not found" );
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Convert (in-place) an XML escape sequence into a literal byte,
|
||||
* rather than the character it actually refers to.
|
||||
*/
|
||||
void LocalFileMng::convertFromTinyXMLString( QByteArray* str )
|
||||
{
|
||||
/* When TinyXML encountered a non-ASCII character, it would
|
||||
* simply write the character as "&#xx;" -- where "xx" is
|
||||
* the hex character code. However, this doesn't respect
|
||||
* any encodings (e.g. UTF-8, UTF-16). In XML, &#xx; literally
|
||||
* means "the Unicode character # xx." However, in a UTF-8
|
||||
* sequence, this could be an escape character that tells
|
||||
* whether we have a 2, 3, or 4-byte UTF-8 sequence.
|
||||
*
|
||||
* For example, the UTF-8 sequence 0xD184 was being written
|
||||
* by TinyXML as "Ñ„". However, this is the UTF-8
|
||||
* sequence for the cyrillic small letter EF (which looks
|
||||
* kind of like a thorn or a greek phi). This letter, in
|
||||
* XML, should be saved as ф, or even literally
|
||||
* (no escaping). As a consequence, when Ñ is read
|
||||
* by an XML parser, it will be interpreted as capital N
|
||||
* with a tilde (~). Then „ will be interpreted as
|
||||
* an unknown or control character.
|
||||
*
|
||||
* So, when we know that TinyXML wrote the file, we can
|
||||
* simply exchange these hex sequences to literal bytes.
|
||||
*/
|
||||
int pos = 0;
|
||||
|
||||
pos = str->indexOf("&#x");
|
||||
while( pos != -1 ) {
|
||||
if( isxdigit(str->at(pos+3))
|
||||
&& isxdigit(str->at(pos+4))
|
||||
&& (str->at(pos+5) == ';') ) {
|
||||
char w1 = str->at(pos+3);
|
||||
char w2 = str->at(pos+4);
|
||||
|
||||
w1 = tolower(w1) - 0x30; // '0' = 0x30
|
||||
if( w1 > 9 ) w1 -= 0x27; // '9' = 0x39, 'a' = 0x61
|
||||
w1 = (w1 & 0xF);
|
||||
|
||||
w2 = tolower(w2) - 0x30; // '0' = 0x30
|
||||
if( w2 > 9 ) w2 -= 0x27; // '9' = 0x39, 'a' = 0x61
|
||||
w2 = (w2 & 0xF);
|
||||
|
||||
char ch = (w1 << 4) | w2;
|
||||
(*str)[pos] = ch;
|
||||
++pos;
|
||||
str->remove(pos, 5);
|
||||
}
|
||||
pos = str->indexOf("&#x");
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalFileMng::checkTinyXMLCompatMode( const QString& filename )
|
||||
{
|
||||
/*
|
||||
Check if filename was created with TinyXml or QtXml
|
||||
TinyXML: return true
|
||||
QtXml: return false
|
||||
*/
|
||||
|
||||
QFile file( filename );
|
||||
|
||||
if ( !file.open(QIODevice::ReadOnly) )
|
||||
return false;
|
||||
|
||||
QString line = file.readLine();
|
||||
file.close();
|
||||
if ( line.startsWith( "<?xml" )){
|
||||
return false;
|
||||
} else {
|
||||
//_WARNINGLOG( QString("File '%1' is being read in "
|
||||
// "TinyXML compatability mode")
|
||||
// .arg(filename) );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
QDomDocument LocalFileMng::openXmlDocument( const QString& filename )
|
||||
{
|
||||
bool TinyXMLCompat = LocalFileMng::checkTinyXMLCompatMode( filename );
|
||||
|
||||
QDomDocument doc;
|
||||
QFile file( filename );
|
||||
|
||||
if ( !file.open(QIODevice::ReadOnly) )
|
||||
return QDomDocument();
|
||||
|
||||
if( TinyXMLCompat ) {
|
||||
QString enc = QTextCodec::codecForLocale()->name();
|
||||
if( enc == QString("System") ) {
|
||||
enc = "UTF-8";
|
||||
}
|
||||
QByteArray line;
|
||||
QByteArray buf = QString("<?xml version='1.0' encoding='%1' ?>\n")
|
||||
.arg( enc )
|
||||
.toLocal8Bit();
|
||||
|
||||
//_INFOLOG( QString("Using '%1' encoding for TinyXML file").arg(enc) );
|
||||
|
||||
while( !file.atEnd() ) {
|
||||
line = file.readLine();
|
||||
LocalFileMng::convertFromTinyXMLString( &line );
|
||||
buf += line;
|
||||
}
|
||||
|
||||
if( ! doc.setContent( buf ) ) {
|
||||
file.close();
|
||||
return QDomDocument();
|
||||
}
|
||||
|
||||
} else {
|
||||
if( ! doc.setContent( &file ) ) {
|
||||
file.close();
|
||||
return QDomDocument();
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
@@ -542,7 +542,15 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
|
||||
|
||||
void AudioFileProcessorWaveView::isPlaying( f_cnt_t _frames_played )
|
||||
{
|
||||
m_framesPlayed = _frames_played % ( m_sampleBuffer.endFrame() - m_sampleBuffer.startFrame() );
|
||||
const f_cnt_t nb_frames = m_sampleBuffer.endFrame() - m_sampleBuffer.startFrame();
|
||||
if( nb_frames < 1 )
|
||||
{
|
||||
m_framesPlayed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_framesPlayed = _frames_played % nb_frames;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -919,6 +927,10 @@ void AudioFileProcessorWaveView::slideSamplePointByFrames( knobType _point, f_cn
|
||||
|
||||
void AudioFileProcessorWaveView::slideSampleByFrames( f_cnt_t _frames )
|
||||
{
|
||||
if( m_sampleBuffer.frames() <= 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const double v = double( _frames ) / m_sampleBuffer.frames();
|
||||
m_startKnob->slideBy( v, false );
|
||||
m_endKnob->slideBy( v, false );
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* sf2_player.cpp - a soundfont2 player using fluidSynth
|
||||
*
|
||||
* Copyright (c) 2008 Paul Giblock <drfaygo/at/gmail/dot/com>
|
||||
* Copyright (c) 2009-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2009-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -389,6 +389,8 @@ void sf2Instrument::openFile( const QString & _sf2File )
|
||||
}
|
||||
|
||||
delete[] sf2Ascii;
|
||||
|
||||
instrumentTrack()->setName( QFileInfo( _sf2File ).baseName() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -117,22 +117,31 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
m_plugin->loadSettings( _this );
|
||||
|
||||
const QMap<QString, QString> & dump = m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
paramCount = dump.size();
|
||||
char paramStr[35];
|
||||
vstKnobs = new knob *[paramCount];
|
||||
knobFModel = new FloatModel *[paramCount];
|
||||
QStringList list1;
|
||||
vstKnobs = new knob *[ paramCount ];
|
||||
knobFModel = new FloatModel *[ paramCount ];
|
||||
QStringList s_dumpValues;
|
||||
QWidget * widget = new QWidget();
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i );
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
vstKnobs[i] = new knob( knobBright_26, widget );
|
||||
vstKnobs[i]->setHintText( list1.at(1) + ":", "");
|
||||
vstKnobs[i]->setLabel( list1.at(1).left(15) );
|
||||
vstKnobs[i] = new knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
vstKnobs[i]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
vstKnobs[i]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i]->loadSettings( _this, paramStr );
|
||||
|
||||
if( !( knobFModel[ i ]->isAutomated() ||
|
||||
knobFModel[ i ]->getControllerConnection() ) )
|
||||
{
|
||||
knobFModel[ i ]->setValue( ( s_dumpValues.at( 2 )).toFloat() );
|
||||
knobFModel[ i ]->setInitValue( ( s_dumpValues.at( 2 )).toFloat() );
|
||||
}
|
||||
|
||||
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
|
||||
vstKnobs[i]->setModel( knobFModel[i] );
|
||||
@@ -167,9 +176,10 @@ void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
m_plugin->saveSettings( _doc, _this );
|
||||
if (knobFModel != NULL) {
|
||||
const QMap<QString, QString> & dump = m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
paramCount = dump.size();
|
||||
char paramStr[35];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
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 );
|
||||
@@ -223,7 +233,10 @@ void vestigeInstrument::loadFile( const QString & _file )
|
||||
InstrumentTrack::tr( "Default preset" );
|
||||
m_pluginMutex.unlock();
|
||||
|
||||
closePlugin();
|
||||
if ( m_plugin != NULL )
|
||||
{
|
||||
closePlugin();
|
||||
}
|
||||
|
||||
m_pluginDLL = _file;
|
||||
textFloat * tf = textFloat::displayMessage(
|
||||
@@ -250,7 +263,7 @@ void vestigeInstrument::loadFile( const QString & _file )
|
||||
return;
|
||||
}
|
||||
|
||||
m_plugin->showEditor();
|
||||
m_plugin->showEditor( NULL, false );
|
||||
|
||||
if( set_ch_name )
|
||||
{
|
||||
@@ -308,6 +321,51 @@ bool vestigeInstrument::handleMidiEvent( const midiEvent & _me,
|
||||
|
||||
void vestigeInstrument::closePlugin( void )
|
||||
{
|
||||
// disconnect all signals
|
||||
if( knobFModel != NULL )
|
||||
{
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
delete knobFModel[ i ];
|
||||
delete vstKnobs[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if( vstKnobs != NULL )
|
||||
{
|
||||
delete [] vstKnobs;
|
||||
vstKnobs = NULL;
|
||||
}
|
||||
|
||||
if( knobFModel != NULL )
|
||||
{
|
||||
delete [] knobFModel;
|
||||
knobFModel = NULL;
|
||||
}
|
||||
|
||||
if( m_scrollArea != NULL )
|
||||
{
|
||||
// delete m_scrollArea;
|
||||
m_scrollArea = NULL;
|
||||
}
|
||||
|
||||
if( m_subWindow != NULL )
|
||||
{
|
||||
m_subWindow->setAttribute( Qt::WA_DeleteOnClose );
|
||||
m_subWindow->close();
|
||||
|
||||
if( m_subWindow != NULL )
|
||||
{
|
||||
delete m_subWindow;
|
||||
}
|
||||
m_subWindow = NULL;
|
||||
}
|
||||
|
||||
if( p_subWindow != NULL )
|
||||
{
|
||||
p_subWindow = NULL;
|
||||
}
|
||||
|
||||
m_pluginMutex.lock();
|
||||
if( m_plugin )
|
||||
{
|
||||
@@ -685,8 +743,7 @@ void VestigeInstrumentView::selPreset( void )
|
||||
|
||||
void VestigeInstrumentView::toggleGUI( void )
|
||||
{
|
||||
QMutexLocker ml( &m_vi->m_pluginMutex );
|
||||
if( m_vi->m_plugin == NULL )
|
||||
if( m_vi == NULL || m_vi->m_plugin == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -790,10 +847,16 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * )
|
||||
p.setPen( QColor( 251, 41, 8 ) );
|
||||
f.setBold( false );
|
||||
p.setFont( pointSize<8>( f ) );
|
||||
p.drawText( 10, 114, tr( "by" ) + " " +
|
||||
p.drawText( 10, 114, tr( "by " ) +
|
||||
m_vi->m_plugin->vendorString() );
|
||||
p.drawText( 10, 225, m_vi->m_plugin->currentProgramName() );
|
||||
}
|
||||
|
||||
if( m_vi->m_subWindow != NULL )
|
||||
{
|
||||
m_vi->m_subWindow->setWindowTitle( m_vi->instrumentTrack()->name()
|
||||
+ tr( " - VST plugin control" ) );
|
||||
}
|
||||
// m_pluginMutex.unlock();
|
||||
}
|
||||
|
||||
@@ -814,7 +877,8 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
|
||||
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->setWindowTitle( m_vi->instrumentTrack()->name()
|
||||
+ tr( " - VST plugin control" ) );
|
||||
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
|
||||
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
@@ -831,49 +895,77 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
|
||||
|
||||
l->addWidget( m_syncButton, 0, 0, 1, 2, Qt::AlignLeft );
|
||||
|
||||
m_displayAutomatedOnly = new QPushButton( tr( "Automated" ), this );
|
||||
connect( m_displayAutomatedOnly, SIGNAL( clicked() ), this,
|
||||
SLOT( displayAutomatedOnly() ) );
|
||||
m_displayAutomatedOnly->setWhatsThis(
|
||||
tr( "Click here if you want to display automated parameters only." ) );
|
||||
|
||||
l->addWidget( m_displayAutomatedOnly, 0, 1, 1, 2, Qt::AlignLeft );
|
||||
|
||||
|
||||
m_closeButton = new QPushButton( tr( " Close " ), widget );
|
||||
connect( m_closeButton, SIGNAL( clicked() ), this,
|
||||
SLOT( closeWindow() ) );
|
||||
m_closeButton->setWhatsThis(
|
||||
tr( "Close VST plugin knob-controller window." ) );
|
||||
|
||||
l->addWidget( m_closeButton, 0, 2, 1, 7, Qt::AlignLeft );
|
||||
|
||||
|
||||
for( int i = 0; i < 10; i++ )
|
||||
{
|
||||
l->addItem( new QSpacerItem( 68, 45, QSizePolicy::Fixed, QSizePolicy::Fixed ), 0, i );
|
||||
}
|
||||
|
||||
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
m_vi->paramCount = dump.size();
|
||||
|
||||
bool isVstKnobs = true;
|
||||
|
||||
if (m_vi->vstKnobs == NULL) {
|
||||
m_vi->vstKnobs = new knob *[paramCount];
|
||||
m_vi->vstKnobs = new knob *[ m_vi->paramCount ];
|
||||
isVstKnobs = false;
|
||||
}
|
||||
if (m_vi->knobFModel == NULL) {
|
||||
m_vi->knobFModel = new FloatModel *[paramCount];
|
||||
m_vi->knobFModel = new FloatModel *[ m_vi->paramCount ];
|
||||
}
|
||||
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
QStringList s_dumpValues;
|
||||
|
||||
if (isVstKnobs == false) {
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
s_dumpValues = 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) );
|
||||
m_vi->vstKnobs[ i ] = new knob( knobBright_26, this, s_dumpValues.at( 1 ) );
|
||||
m_vi->vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
m_vi->vstKnobs[ i ]->setLabel( s_dumpValues.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 ) );
|
||||
m_vi->knobFModel[ i ] = new FloatModel( (s_dumpValues.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)
|
||||
for( int lrow = 1; lrow < ( int( m_vi->paramCount / 10 ) + 1 ) + 1; lrow++ )
|
||||
{
|
||||
for( int lcolumn = 0; lcolumn < 10; lcolumn++ )
|
||||
{
|
||||
if( i < m_vi->paramCount )
|
||||
{
|
||||
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
l->setRowStretch( (int(paramCount / 10) + 1), 1 );
|
||||
l->setRowStretch( ( int( m_vi->paramCount / 10) + 1), 1 );
|
||||
l->setColumnStretch( 10, 1 );
|
||||
|
||||
widget->setLayout(l);
|
||||
@@ -892,29 +984,84 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::closeWindow()
|
||||
{
|
||||
m_vi->m_subWindow->hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::syncPlugin( void )
|
||||
{
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
QStringList s_dumpValues;
|
||||
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
|
||||
float f;
|
||||
float f_value;
|
||||
|
||||
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);
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
// only not automated knobs are synced from VST
|
||||
// those auto-setted values are not jurnaled, tracked for undo / redo
|
||||
if( !( m_vi->knobFModel[ i ]->isAutomated() ||
|
||||
m_vi->knobFModel[ i ]->getControllerConnection() ) )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i );
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
f_value = ( s_dumpValues.at( 2 ) ).toFloat();
|
||||
m_vi->knobFModel[ i ]->setAutomatedValue( f_value );
|
||||
m_vi->knobFModel[ i ]->setInitValue( f_value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVestigeInstrumentView::displayAutomatedOnly( void )
|
||||
{
|
||||
bool isAuto = QString::compare( m_displayAutomatedOnly->text(), tr( "Automated" ) ) == 0;
|
||||
|
||||
for( int i = 0; i< m_vi->paramCount; i++ )
|
||||
{
|
||||
|
||||
if( !( m_vi->knobFModel[ i ]->isAutomated() ||
|
||||
m_vi->knobFModel[ i ]->getControllerConnection() ) )
|
||||
{
|
||||
if( m_vi->vstKnobs[ i ]->isVisible() == true && isAuto )
|
||||
{
|
||||
m_vi->vstKnobs[ i ]->hide();
|
||||
m_displayAutomatedOnly->setText( "All" );
|
||||
} else {
|
||||
m_vi->vstKnobs[ i ]->show();
|
||||
m_displayAutomatedOnly->setText( "Automated" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
manageVestigeInstrumentView::~manageVestigeInstrumentView()
|
||||
{
|
||||
if( m_vi->knobFModel != NULL )
|
||||
{
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
delete m_vi->knobFModel[ i ];
|
||||
delete m_vi->vstKnobs[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_vi->vstKnobs != NULL) {
|
||||
delete []m_vi->vstKnobs;
|
||||
m_vi->vstKnobs = NULL;
|
||||
}
|
||||
|
||||
if( m_vi->knobFModel != NULL )
|
||||
{
|
||||
delete [] m_vi->knobFModel;
|
||||
m_vi->knobFModel = NULL;
|
||||
}
|
||||
|
||||
if (m_vi->m_scrollArea != NULL) {
|
||||
delete m_vi->m_scrollArea;
|
||||
@@ -929,6 +1076,8 @@ manageVestigeInstrumentView::~manageVestigeInstrumentView()
|
||||
delete m_vi->m_subWindow;
|
||||
m_vi->m_subWindow = NULL;
|
||||
}
|
||||
|
||||
m_vi->p_subWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -989,6 +1138,8 @@ void manageVestigeInstrumentView::dropEvent( QDropEvent * _de )
|
||||
|
||||
void manageVestigeInstrumentView::paintEvent( QPaintEvent * )
|
||||
{
|
||||
m_vi->m_subWindow->setWindowTitle( m_vi->instrumentTrack()->name()
|
||||
+ tr( " - VST plugin control" ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ private:
|
||||
knob ** vstKnobs;
|
||||
FloatModel ** knobFModel;
|
||||
QObject * p_subWindow;
|
||||
int paramCount;
|
||||
|
||||
|
||||
friend class VestigeInstrumentView;
|
||||
@@ -110,7 +111,9 @@ public:
|
||||
|
||||
protected slots:
|
||||
void syncPlugin( void );
|
||||
void displayAutomatedOnly( void );
|
||||
void setParameter( void );
|
||||
void closeWindow();
|
||||
|
||||
|
||||
protected:
|
||||
@@ -127,6 +130,8 @@ private:
|
||||
QWidget *widget;
|
||||
QGridLayout * l;
|
||||
QPushButton * m_syncButton;
|
||||
QPushButton * m_displayAutomatedOnly;
|
||||
QPushButton * m_closeButton;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -92,7 +92,20 @@ struct ERect
|
||||
#include "midi.h"
|
||||
#include "communication.h"
|
||||
|
||||
#include "VST_sync_shm.h"
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
#define USE_QT_SHMEM
|
||||
#endif
|
||||
|
||||
#ifndef USE_QT_SHMEM
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
|
||||
static VstHostLanguages hlang = LanguageEnglish;
|
||||
|
||||
@@ -303,6 +316,18 @@ private:
|
||||
double m_currentSamplePos;
|
||||
int m_currentProgram;
|
||||
|
||||
// host to plugin synchronisation data structure
|
||||
struct in
|
||||
{
|
||||
float lastppqPos;
|
||||
float m_Timestamp;
|
||||
} ;
|
||||
|
||||
in * m_in;
|
||||
|
||||
int m_shmID;
|
||||
sncVST * m_SncVSTplug;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -324,12 +349,59 @@ RemoteVstPlugin::RemoteVstPlugin( key_t _shm_in, key_t _shm_out ) :
|
||||
m_midiEvents(),
|
||||
m_bpm( 0 ),
|
||||
m_currentSamplePos( 0 ),
|
||||
m_currentProgram( -1 )
|
||||
m_currentProgram( -1 ),
|
||||
m_in( NULL ),
|
||||
m_shmID( -1 ),
|
||||
m_SncVSTplug( NULL )
|
||||
|
||||
{
|
||||
pthread_mutex_init( &m_pluginLock, NULL );
|
||||
|
||||
__plugin = this;
|
||||
|
||||
#ifndef USE_QT_SHMEM
|
||||
key_t key;
|
||||
if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 )
|
||||
{
|
||||
perror( "RemoteVstPlugin.cpp::ftok" );
|
||||
}
|
||||
else
|
||||
{ // connect to shared memory segment
|
||||
if( ( m_shmID = shmget( key, 0, 0 ) ) == -1 )
|
||||
{
|
||||
perror( "RemoteVstPlugin.cpp::shmget" );
|
||||
}
|
||||
else
|
||||
{ // attach segment
|
||||
m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0);
|
||||
if( m_SncVSTplug == (sncVST *)( -1 ) )
|
||||
{
|
||||
perror( "RemoteVstPlugin.cpp::shmat" );
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
m_SncVSTplug = RemotePluginClient::getQtVSTshm();
|
||||
#endif
|
||||
if( m_SncVSTplug == 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_in = ( in* ) new char[ sizeof( in ) ];
|
||||
m_in->lastppqPos = 0;
|
||||
m_in->m_Timestamp = -1;
|
||||
|
||||
// process until we have loaded the plugin
|
||||
while( 1 )
|
||||
{
|
||||
@@ -347,6 +419,21 @@ RemoteVstPlugin::RemoteVstPlugin( key_t _shm_in, key_t _shm_out ) :
|
||||
|
||||
RemoteVstPlugin::~RemoteVstPlugin()
|
||||
{
|
||||
#ifndef USE_QT_SHMEM
|
||||
// detach shared memory segment
|
||||
if( shmdt( m_SncVSTplug ) == -1)
|
||||
{
|
||||
if( __plugin->m_SncVSTplug->hasSHM )
|
||||
{
|
||||
perror( "~RemoteVstPlugin::shmdt" );
|
||||
}
|
||||
if( m_SncVSTplug != NULL )
|
||||
{
|
||||
delete m_SncVSTplug;
|
||||
m_SncVSTplug = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( m_window != NULL )
|
||||
{
|
||||
pluginDispatch( effEditClose );
|
||||
@@ -451,7 +538,7 @@ bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
lock();
|
||||
m_plugin->setParameter( m_plugin, _m.getInt( 0 ), _m.getFloat( 1 ) );
|
||||
unlock();
|
||||
sendMessage( IdVstSetParameter );
|
||||
//sendMessage( IdVstSetParameter );
|
||||
break;
|
||||
|
||||
|
||||
@@ -486,6 +573,12 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )
|
||||
|
||||
updateInOutCount();
|
||||
|
||||
// some plugins have to set samplerate during init
|
||||
if( m_SncVSTplug->hasSHM )
|
||||
{
|
||||
updateSampleRate();
|
||||
}
|
||||
|
||||
/* set program to zero */
|
||||
/* i comment this out because it breaks dfx Geometer
|
||||
* looks like we cant set programs for it
|
||||
@@ -558,10 +651,12 @@ void RemoteVstPlugin::initEditor()
|
||||
}
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
m_window = CreateWindowEx( 0, "LVSL", m_shortName.c_str(),
|
||||
( WS_OVERLAPPEDWINDOW | WS_THICKFRAME ) & ~WS_MAXIMIZEBOX,
|
||||
0, 0, 10, 10, NULL, NULL, hInst, NULL );
|
||||
//m_window = CreateWindowEx( 0, "LVSL", m_shortName.c_str(),
|
||||
// ( WS_OVERLAPPEDWINDOW | WS_THICKFRAME ) & ~WS_MAXIMIZEBOX,
|
||||
// 0, 0, 10, 10, NULL, NULL, hInst, NULL );
|
||||
|
||||
m_window = CreateWindowEx( 0 , "LVSL", m_shortName.c_str(),
|
||||
WS_POPUP | WS_SYSMENU | WS_BORDER , 0, 0, 10, 10, NULL, NULL, hInst, NULL);
|
||||
#else
|
||||
m_windowID = 1; // arbitrary value on win32 to signal
|
||||
// vstPlugin-class that we have an editor
|
||||
@@ -1349,16 +1444,62 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
|
||||
// fields are required (see valid masks above), as some
|
||||
// items may require extensive conversions
|
||||
|
||||
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
|
||||
// Shared memory was initialised? - see song.cpp
|
||||
//assert( __plugin->m_SncVSTplug != NULL );
|
||||
|
||||
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
|
||||
_timeInfo.samplePos = __plugin->m_currentSamplePos;
|
||||
_timeInfo.sampleRate = __plugin->sampleRate();
|
||||
_timeInfo.sampleRate = __plugin->m_SncVSTplug->hasSHM ?
|
||||
__plugin->m_SncVSTplug->m_sampleRate :
|
||||
__plugin->sampleRate();
|
||||
_timeInfo.flags = 0;
|
||||
_timeInfo.tempo = __plugin->m_bpm;
|
||||
_timeInfo.timeSigNumerator = 4;
|
||||
_timeInfo.timeSigDenominator = 4;
|
||||
_timeInfo.flags |= (/* kVstBarsValid|*/kVstTempoValid );
|
||||
_timeInfo.flags |= kVstTransportPlaying;
|
||||
_timeInfo.tempo = __plugin->m_SncVSTplug->hasSHM ?
|
||||
__plugin->m_SncVSTplug->m_bpm :
|
||||
__plugin->m_bpm;
|
||||
_timeInfo.timeSigNumerator = __plugin->m_SncVSTplug->timeSigNumer;
|
||||
_timeInfo.timeSigDenominator = __plugin->m_SncVSTplug->timeSigDenom;
|
||||
_timeInfo.flags |= kVstTempoValid;
|
||||
_timeInfo.flags |= kVstTimeSigValid;
|
||||
|
||||
if( __plugin->m_SncVSTplug->isCycle )
|
||||
{
|
||||
_timeInfo.cycleStartPos = __plugin->m_SncVSTplug->cycleStart;
|
||||
_timeInfo.cycleEndPos = __plugin->m_SncVSTplug->cycleEnd;
|
||||
_timeInfo.flags |= kVstCyclePosValid;
|
||||
_timeInfo.flags |= kVstTransportCycleActive;
|
||||
}
|
||||
|
||||
if( __plugin->m_SncVSTplug->ppqPos !=
|
||||
__plugin->m_in->m_Timestamp )
|
||||
{
|
||||
_timeInfo.ppqPos = __plugin->m_SncVSTplug->ppqPos;
|
||||
_timeInfo.flags |= kVstTransportChanged;
|
||||
__plugin->m_in->lastppqPos = __plugin->m_SncVSTplug->ppqPos;
|
||||
__plugin->m_in->m_Timestamp = __plugin->m_SncVSTplug->ppqPos;
|
||||
}
|
||||
else if( __plugin->m_SncVSTplug->isPlayin )
|
||||
{
|
||||
__plugin->m_in->lastppqPos += (
|
||||
__plugin->m_SncVSTplug->hasSHM ?
|
||||
__plugin->m_SncVSTplug->m_bpm :
|
||||
__plugin->m_bpm ) / (float)10340;
|
||||
_timeInfo.ppqPos = __plugin->m_in->lastppqPos;
|
||||
}
|
||||
// _timeInfo.ppqPos = __plugin->m_SncVSTplug->ppqPos;
|
||||
_timeInfo.flags |= kVstPpqPosValid;
|
||||
|
||||
if( __plugin->m_SncVSTplug->isPlayin )
|
||||
{
|
||||
_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 );
|
||||
|
||||
_timeInfo.flags |= kVstBarsValid;
|
||||
|
||||
#ifdef LMMS_BUILD_WIN64
|
||||
return (long long) &_timeInfo;
|
||||
#else
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "MainWindow.h"
|
||||
#include "song.h"
|
||||
#include "templates.h"
|
||||
#include <QtGui/QLayout>
|
||||
|
||||
|
||||
class vstSubWin : public QMdiSubWindow
|
||||
@@ -200,11 +201,24 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable )
|
||||
|
||||
|
||||
|
||||
void VstPlugin::showEditor( QWidget * _parent )
|
||||
void VstPlugin::showEditor( QWidget * _parent, bool isEffect )
|
||||
{
|
||||
QWidget * w = pluginWidget();
|
||||
if( w )
|
||||
{
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
// hide sw, plugin window wrapper on win32
|
||||
// this is obtained from pluginWidget()
|
||||
if( isEffect )
|
||||
{
|
||||
w->setWindowFlags( Qt::FramelessWindowHint );
|
||||
w->setAttribute( Qt::WA_TranslucentBackground );
|
||||
}
|
||||
else
|
||||
{
|
||||
w->setWindowFlags( Qt::WindowCloseButtonHint );
|
||||
}
|
||||
#endif
|
||||
w->show();
|
||||
return;
|
||||
}
|
||||
@@ -222,13 +236,30 @@ void VstPlugin::showEditor( QWidget * _parent )
|
||||
{
|
||||
vstSubWin * sw = new vstSubWin(
|
||||
engine::mainWindow()->workspace() );
|
||||
sw->setWidget( m_pluginWidget );
|
||||
if( isEffect )
|
||||
{
|
||||
sw->setAttribute( Qt::WA_TranslucentBackground );
|
||||
sw->setWindowFlags( Qt::FramelessWindowHint );
|
||||
sw->setWidget( m_pluginWidget );
|
||||
|
||||
QX11EmbedContainer * xe = new QX11EmbedContainer( sw );
|
||||
xe->embedClient( m_pluginWindowID );
|
||||
xe->setFixedSize( m_pluginGeometry );
|
||||
xe->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
sw->setWindowFlags( Qt::WindowCloseButtonHint );
|
||||
sw->setWidget( m_pluginWidget );
|
||||
|
||||
QX11EmbedContainer * xe = new QX11EmbedContainer( sw );
|
||||
xe->embedClient( m_pluginWindowID );
|
||||
xe->setFixedSize( m_pluginGeometry );
|
||||
xe->move( 4, 24 );
|
||||
xe->show();
|
||||
}
|
||||
}
|
||||
|
||||
QX11EmbedContainer * xe = new QX11EmbedContainer( m_pluginWidget );
|
||||
xe->embedClient( m_pluginWindowID );
|
||||
xe->setFixedSize( m_pluginGeometry );
|
||||
xe->show();
|
||||
#endif
|
||||
|
||||
if( m_pluginWidget )
|
||||
@@ -258,7 +289,7 @@ void VstPlugin::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
if( _this.attribute( "guivisible" ).toInt() )
|
||||
{
|
||||
showEditor();
|
||||
showEditor( NULL, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -574,7 +605,7 @@ void VstPlugin::setParam( int i, float f )
|
||||
{
|
||||
lock();
|
||||
sendMessage( message( IdVstSetParameter ).addInt( i ).addFloat( f ) );
|
||||
waitForMessage( IdVstSetParameter );
|
||||
//waitForMessage( IdVstSetParameter );
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
return m_pluginWindowID != 0;
|
||||
}
|
||||
|
||||
void showEditor( QWidget * _parent = NULL );
|
||||
void showEditor( QWidget * _parent = NULL, bool isEffect = false );
|
||||
void hideEditor();
|
||||
|
||||
inline const QString & name() const
|
||||
|
||||
@@ -65,7 +65,8 @@ VstEffect::VstEffect( Model * _parent,
|
||||
{
|
||||
openPlugin( m_key.attributes["file"] );
|
||||
}
|
||||
setDisplayName( m_key.name );
|
||||
setDisplayName( m_key.attributes["file"].section( ".dll", 0, 0 ).isEmpty()
|
||||
? m_key.name : m_key.attributes["file"].section( ".dll", 0, 0 ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +163,10 @@ void VstEffect::openPlugin( const QString & _plugin )
|
||||
void VstEffect::closePlugin()
|
||||
{
|
||||
m_pluginMutex.lock();
|
||||
if( m_plugin->pluginWidget() != NULL )
|
||||
{
|
||||
delete m_plugin->pluginWidget();
|
||||
}
|
||||
delete m_plugin;
|
||||
m_plugin = NULL;
|
||||
m_pluginMutex.unlock();
|
||||
|
||||
@@ -36,34 +36,54 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
#include "gui_templates.h"
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
|
||||
VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
EffectControlDialog( _ctl ),
|
||||
m_pluginWidget( NULL )
|
||||
m_pluginWidget( NULL ),
|
||||
m_plugin( NULL ),
|
||||
tbLabel( NULL )
|
||||
{
|
||||
QGridLayout * l = new QGridLayout( this );
|
||||
l->setContentsMargins( 20, 10, 10, 10 );
|
||||
l->setContentsMargins( 10, 10, 10, 10 );
|
||||
l->setVerticalSpacing( 2 );
|
||||
l->setHorizontalSpacing( 2 );
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
_ctl->m_effect->m_plugin->showEditor();
|
||||
m_pluginWidget = _ctl->m_effect->m_plugin->pluginWidget();
|
||||
if( _ctl != NULL && _ctl->m_effect != NULL &&
|
||||
_ctl->m_effect->m_plugin != NULL )
|
||||
{
|
||||
m_plugin = _ctl->m_effect->m_plugin;
|
||||
m_plugin->showEditor( NULL, true );
|
||||
m_pluginWidget = m_plugin->pluginWidget();
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
|
||||
if( !m_pluginWidget )
|
||||
{
|
||||
m_pluginWidget = m_plugin->pluginWidget( false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if( m_pluginWidget )
|
||||
{
|
||||
setWindowTitle( m_pluginWidget->windowTitle() );
|
||||
QPushButton * btn = new QPushButton( tr( "Show/hide VST FX GUI" ) );
|
||||
setMinimumWidth( 250 );
|
||||
|
||||
QPushButton * btn = new QPushButton( tr( "Show/hide" ) );
|
||||
btn->setCheckable( true );
|
||||
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 );
|
||||
emit btn->click();
|
||||
|
||||
btn->setMinimumWidth( 78 );
|
||||
btn->setMaximumWidth( 78 );
|
||||
btn->setMinimumHeight( 24 );
|
||||
btn->setMaximumHeight( 24 );
|
||||
|
||||
|
||||
m_managePluginButton = new pixmapButton( this, "" );
|
||||
m_managePluginButton->setCheckable( false );
|
||||
m_managePluginButton->setCursor( Qt::PointingHandCursor );
|
||||
@@ -78,13 +98,11 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
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 );
|
||||
@@ -104,7 +122,6 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
m_openPresetButton->setMinimumHeight( 16 );
|
||||
m_openPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
m_rolLPresetButton = new pixmapButton( this, "" );
|
||||
m_rolLPresetButton->setCheckable( false );
|
||||
m_rolLPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
@@ -114,6 +131,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
"stepper-left" ) );
|
||||
connect( m_rolLPresetButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( rolrPreset() ) );
|
||||
|
||||
connect( m_rolLPresetButton, SIGNAL( clicked() ), this,
|
||||
SLOT( update() ) );
|
||||
|
||||
toolTip::add( m_rolLPresetButton, tr( "Previous (-)" ) );
|
||||
|
||||
m_rolLPresetButton->setShortcut( Qt::Key_Minus );
|
||||
@@ -126,7 +147,6 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
m_rolLPresetButton->setMinimumHeight( 16 );
|
||||
m_rolLPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
m_rolRPresetButton = new pixmapButton( this, "" );
|
||||
m_rolRPresetButton->setCheckable( false );
|
||||
m_rolRPresetButton->setCursor( Qt::PointingHandCursor );
|
||||
@@ -136,6 +156,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
"stepper-right" ) );
|
||||
connect( m_rolRPresetButton, SIGNAL( clicked() ), _ctl,
|
||||
SLOT( rollPreset() ) );
|
||||
|
||||
connect( m_rolRPresetButton, SIGNAL( clicked() ), this,
|
||||
SLOT( update() ) );
|
||||
|
||||
toolTip::add( m_rolRPresetButton, tr( "Next (+)" ) );
|
||||
|
||||
m_rolRPresetButton->setShortcut( Qt::Key_Plus );
|
||||
@@ -148,8 +172,6 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
m_rolRPresetButton->setMinimumHeight( 16 );
|
||||
m_rolRPresetButton->setMaximumHeight( 16 );
|
||||
|
||||
|
||||
|
||||
_ctl->m_selPresetButton = new QPushButton( tr( "" ), this );
|
||||
|
||||
_ctl->m_selPresetButton->setCheckable( false );
|
||||
@@ -160,13 +182,11 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
|
||||
_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 );
|
||||
@@ -181,36 +201,46 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
m_savePresetButton->setWhatsThis(
|
||||
tr( "Click here, if you want to save current VST-plugin preset program." ) );
|
||||
|
||||
|
||||
m_savePresetButton->setMinimumWidth( 21 );
|
||||
m_savePresetButton->setMaximumWidth( 21 );
|
||||
m_savePresetButton->setMinimumHeight( 21 );
|
||||
m_savePresetButton->setMaximumHeight( 21 );
|
||||
|
||||
int newSize = m_pluginWidget->width() + 20;
|
||||
newSize = (newSize < 250) ? 250 : newSize;
|
||||
QWidget* resize = new QWidget(this);
|
||||
resize->resize( newSize, 10 );
|
||||
QWidget* space0 = new QWidget(this);
|
||||
space0->resize(8, 10);
|
||||
QWidget* space1 = new QWidget(this);
|
||||
space1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
QFont f( "Arial", 10 );
|
||||
|
||||
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->addItem( new QSpacerItem( newSize - 20, 30, QSizePolicy::Fixed,
|
||||
QSizePolicy::Fixed ), 1, 0 );
|
||||
l->addWidget( resize, 2, 0, 1, 1, Qt::AlignCenter );
|
||||
l->addWidget( m_pluginWidget, 3, 0, 1, 1, Qt::AlignCenter );
|
||||
l->setRowStretch( 5, 1 );
|
||||
l->setColumnStretch( 1, 1 );
|
||||
|
||||
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 );
|
||||
QToolBar * tb = new QToolBar( this );
|
||||
tb->resize( newSize , 32 );
|
||||
tb->addWidget(space0);
|
||||
tb->addWidget( m_rolLPresetButton );
|
||||
tb->addWidget( m_rolRPresetButton );
|
||||
tb->addWidget( _ctl->m_selPresetButton );
|
||||
tb->addWidget( m_openPresetButton );
|
||||
tb->addWidget( m_savePresetButton );
|
||||
tb->addWidget( m_managePluginButton );
|
||||
tb->addWidget( btn );
|
||||
tb->addWidget(space1);
|
||||
|
||||
tbLabel = new QLabel( tr( "Effect by: " ), this );
|
||||
tbLabel->setFont( pointSize<7>( f ) );
|
||||
tbLabel->setTextFormat(Qt::RichText);
|
||||
tbLabel->setAlignment( Qt::AlignTop | Qt::AlignLeft );
|
||||
tb->addWidget( tbLabel );
|
||||
}
|
||||
#endif
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
_ctl->m_effect->m_plugin->showEditor( this );
|
||||
QWidget * w = _ctl->m_effect->m_plugin->pluginWidget( false );
|
||||
if( w )
|
||||
{
|
||||
setWindowTitle( w->windowTitle() );
|
||||
l->addWidget( w );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +248,12 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
|
||||
void VstEffectControlDialog::paintEvent( QPaintEvent * )
|
||||
{
|
||||
|
||||
if( m_plugin != NULL && tbLabel != NULL )
|
||||
{
|
||||
tbLabel->setText( tr( "Effect by: " ) + m_plugin->vendorString() +
|
||||
tr( " <br />" ) +
|
||||
m_plugin->currentProgramName() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +261,7 @@ void VstEffectControlDialog::paintEvent( QPaintEvent * )
|
||||
|
||||
VstEffectControlDialog::~VstEffectControlDialog()
|
||||
{
|
||||
delete m_pluginWidget;
|
||||
//delete m_pluginWidget;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
#define _VST_EFFECT_CONTROL_DIALOG_H
|
||||
|
||||
#include "EffectControlDialog.h"
|
||||
#include "VstPlugin.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPainter>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
|
||||
class VstEffectControls;
|
||||
@@ -57,6 +59,9 @@ private:
|
||||
pixmapButton * m_managePluginButton;
|
||||
pixmapButton * m_savePresetButton;
|
||||
|
||||
VstPlugin * m_plugin;
|
||||
|
||||
QLabel * tbLabel;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,30 +61,39 @@ VstEffectControls::~VstEffectControls()
|
||||
|
||||
void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_effect->closePlugin();
|
||||
m_effect->openPlugin( _this.attribute( "plugin" ) );
|
||||
//m_effect->closePlugin();
|
||||
//m_effect->openPlugin( _this.attribute( "plugin" ) );
|
||||
m_effect->m_pluginMutex.lock();
|
||||
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();
|
||||
paramCount = dump.size();
|
||||
char paramStr[35];
|
||||
vstKnobs = new knob *[paramCount];
|
||||
knobFModel = new FloatModel *[paramCount];
|
||||
QStringList list1;
|
||||
vstKnobs = new knob *[ paramCount ];
|
||||
knobFModel = new FloatModel *[ paramCount ];
|
||||
QStringList s_dumpValues;
|
||||
QWidget * widget = new QWidget();
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i );
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
vstKnobs[i] = new knob( knobBright_26, widget );
|
||||
vstKnobs[i]->setHintText( list1.at(1) + ":", "");
|
||||
vstKnobs[i]->setLabel( list1.at(1).left(15) );
|
||||
vstKnobs[i] = new knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
vstKnobs[i]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
vstKnobs[i]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i]->loadSettings( _this, paramStr );
|
||||
|
||||
if( !( knobFModel[ i ]->isAutomated() ||
|
||||
knobFModel[ i ]->getControllerConnection() ) )
|
||||
{
|
||||
knobFModel[ i ]->setValue( (s_dumpValues.at( 2 ) ).toFloat() );
|
||||
knobFModel[ i ]->setInitValue( (s_dumpValues.at( 2 ) ).toFloat() );
|
||||
}
|
||||
|
||||
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
|
||||
vstKnobs[i]->setModel( knobFModel[i] );
|
||||
@@ -120,13 +129,15 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
m_effect->m_plugin->saveSettings( _doc, _this );
|
||||
if (knobFModel != NULL) {
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
paramCount = dump.size();
|
||||
char paramStr[35];
|
||||
for (int i = 0; i < paramCount; i++)
|
||||
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();
|
||||
@@ -303,7 +314,7 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
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->setWindowTitle( _eff->m_plugin->name() + tr( " - VST parameter control" ) );
|
||||
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
|
||||
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
@@ -320,51 +331,80 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
|
||||
l->addWidget( m_syncButton, 0, 0, 1, 2, Qt::AlignLeft );
|
||||
|
||||
m_displayAutomatedOnly = new QPushButton( tr( "Automated" ), widget );
|
||||
connect( m_displayAutomatedOnly, SIGNAL( clicked() ), this,
|
||||
SLOT( displayAutomatedOnly() ) );
|
||||
m_displayAutomatedOnly->setWhatsThis(
|
||||
tr( "Click here if you want to display automated parameters only." ) );
|
||||
|
||||
l->addWidget( m_displayAutomatedOnly, 0, 1, 1, 2, Qt::AlignLeft );
|
||||
|
||||
|
||||
m_closeButton = new QPushButton( tr( " Close " ), widget );
|
||||
connect( m_closeButton, SIGNAL( clicked() ), this,
|
||||
SLOT( closeWindow() ) );
|
||||
m_closeButton->setWhatsThis(
|
||||
tr( "Close VST effect knob-controller window." ) );
|
||||
|
||||
l->addWidget( m_closeButton, 0, 2, 1, 7, Qt::AlignLeft );
|
||||
|
||||
|
||||
for( int i = 0; i < 10; i++ )
|
||||
{
|
||||
l->addItem( new QSpacerItem( 68, 45, QSizePolicy::Fixed, QSizePolicy::Fixed ), 0, i );
|
||||
}
|
||||
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
int paramCount = (dump).size();
|
||||
m_vi->paramCount = dump.size();
|
||||
|
||||
bool isVstKnobs = true, isKnobFModel = true;
|
||||
|
||||
|
||||
if (m_vi->vstKnobs == NULL) {
|
||||
m_vi->vstKnobs = new knob *[paramCount];
|
||||
m_vi->vstKnobs = new knob *[ m_vi->paramCount ];
|
||||
isVstKnobs = false;
|
||||
}
|
||||
if (m_vi->knobFModel == NULL) {
|
||||
m_vi->knobFModel = new FloatModel *[paramCount];
|
||||
m_vi->knobFModel = new FloatModel *[ m_vi->paramCount ];
|
||||
isKnobFModel = false;
|
||||
}
|
||||
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
QStringList s_dumpValues;
|
||||
|
||||
if (isVstKnobs == false) {
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i);
|
||||
list1 = dump[paramStr].split(":");
|
||||
s_dumpValues = 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) );
|
||||
m_vi->vstKnobs[ i ] = new knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
m_vi->vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
m_vi->vstKnobs[ i ]->setLabel( s_dumpValues.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] );
|
||||
m_vi->knobFModel[ i ] = new FloatModel( ( s_dumpValues.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)
|
||||
for( int lrow = 1; lrow < ( int( m_vi->paramCount / 10 ) + 1 ) + 1; lrow++ )
|
||||
{
|
||||
for( int lcolumn = 0; lcolumn < 10; lcolumn++ )
|
||||
{
|
||||
if( i < m_vi->paramCount )
|
||||
{
|
||||
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
l->setRowStretch( (int(paramCount / 10) + 1), 1 );
|
||||
l->setRowStretch( ( int( m_vi->paramCount / 10 ) + 1 ), 1 );
|
||||
l->setColumnStretch( 10, 1 );
|
||||
|
||||
widget->setLayout(l);
|
||||
@@ -383,24 +423,63 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
|
||||
|
||||
|
||||
void manageVSTEffectView::closeWindow()
|
||||
{
|
||||
m_vi2->m_subWindow->hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVSTEffectView::syncPlugin( void )
|
||||
{
|
||||
char paramStr[35];
|
||||
QStringList list1;
|
||||
QStringList s_dumpValues;
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
float f;
|
||||
float f_value;
|
||||
|
||||
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);
|
||||
for( int i = 0; i < m_vi2->paramCount; i++ )
|
||||
{
|
||||
// only not automated knobs are synced from VST
|
||||
// those auto-setted values are not jurnaled, tracked for undo / redo
|
||||
if( !( m_vi2->knobFModel[ i ]->isAutomated() ||
|
||||
m_vi2->knobFModel[ i ]->getControllerConnection() ) )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i );
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
f_value = ( s_dumpValues.at( 2 ) ).toFloat();
|
||||
m_vi2->knobFModel[ i ]->setAutomatedValue( f_value );
|
||||
m_vi2->knobFModel[ i ]->setInitValue( f_value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void manageVSTEffectView::displayAutomatedOnly( void )
|
||||
{
|
||||
bool isAuto = QString::compare( m_displayAutomatedOnly->text(), tr( "Automated" ) ) == 0;
|
||||
|
||||
for( int i = 0; i< m_vi2->paramCount; i++ )
|
||||
{
|
||||
|
||||
if( !( m_vi2->knobFModel[ i ]->isAutomated() ||
|
||||
m_vi2->knobFModel[ i ]->getControllerConnection() ) )
|
||||
{
|
||||
if( m_vi2->vstKnobs[ i ]->isVisible() == true && isAuto )
|
||||
{
|
||||
m_vi2->vstKnobs[ i ]->hide();
|
||||
m_displayAutomatedOnly->setText( "All" );
|
||||
} else {
|
||||
m_vi2->vstKnobs[ i ]->show();
|
||||
m_displayAutomatedOnly->setText( "Automated" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void manageVSTEffectView::setParameter( void )
|
||||
{
|
||||
@@ -418,8 +497,46 @@ void manageVSTEffectView::setParameter( void )
|
||||
|
||||
manageVSTEffectView::~manageVSTEffectView()
|
||||
{
|
||||
delete m_vi2->m_subWindow;
|
||||
m_vi2->m_subWindow = NULL;
|
||||
if( m_vi2->knobFModel != NULL )
|
||||
{
|
||||
for( int i = 0; i < m_vi2->paramCount; i++ )
|
||||
{
|
||||
delete m_vi2->knobFModel[ i ];
|
||||
delete m_vi2->vstKnobs[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if( m_vi2->vstKnobs != NULL )
|
||||
{
|
||||
delete [] m_vi2->vstKnobs;
|
||||
m_vi2->vstKnobs = NULL;
|
||||
}
|
||||
|
||||
if( m_vi2->knobFModel != NULL )
|
||||
{
|
||||
delete [] m_vi2->knobFModel;
|
||||
m_vi2->knobFModel = NULL;
|
||||
}
|
||||
|
||||
if( m_vi2->m_scrollArea != NULL )
|
||||
{
|
||||
delete m_vi2->m_scrollArea;
|
||||
m_vi2->m_scrollArea = NULL;
|
||||
}
|
||||
|
||||
if( m_vi2->m_subWindow != NULL )
|
||||
{
|
||||
m_vi2->m_subWindow->setAttribute( Qt::WA_DeleteOnClose );
|
||||
m_vi2->m_subWindow->close();
|
||||
|
||||
if( m_vi2->m_subWindow != NULL )
|
||||
{
|
||||
delete m_vi2->m_subWindow;
|
||||
}
|
||||
m_vi2->m_subWindow = NULL;
|
||||
}
|
||||
//delete m_vi2->m_subWindow;
|
||||
//m_vi2->m_subWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ private:
|
||||
QScrollArea * m_scrollArea;
|
||||
FloatModel ** knobFModel;
|
||||
knob ** vstKnobs;
|
||||
int paramCount;
|
||||
|
||||
QObject * ctrHandle;
|
||||
|
||||
@@ -112,7 +113,9 @@ public:
|
||||
|
||||
protected slots:
|
||||
void syncPlugin( void );
|
||||
void displayAutomatedOnly( void );
|
||||
void setParameter( void );
|
||||
void closeWindow();
|
||||
|
||||
private:
|
||||
|
||||
@@ -128,6 +131,8 @@ private:
|
||||
QGridLayout * l;
|
||||
|
||||
QPushButton * m_syncButton;
|
||||
QPushButton * m_displayAutomatedOnly;
|
||||
QPushButton * m_closeButton;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* LocalZynAddSubFx.cpp - local implementation of ZynAddSubFx plugin
|
||||
*
|
||||
* Copyright (c) 2009-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2009-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -206,10 +206,10 @@ void LocalZynAddSubFx::processMidiEvent( const midiEvent & _e )
|
||||
}
|
||||
if( m_runningNotes[_e.key()] > 0 )
|
||||
{
|
||||
m_master->NoteOff( 0, _e.key() );
|
||||
m_master->NoteOff( _e.channel(), _e.key() );
|
||||
}
|
||||
++m_runningNotes[_e.key()];
|
||||
m_master->NoteOn( 0, _e.key(), _e.velocity() );
|
||||
m_master->NoteOn( _e.channel(), _e.key(), _e.velocity() );
|
||||
break;
|
||||
}
|
||||
case MidiNoteOff:
|
||||
@@ -219,16 +219,16 @@ void LocalZynAddSubFx::processMidiEvent( const midiEvent & _e )
|
||||
}
|
||||
if( --m_runningNotes[_e.key()] <= 0 )
|
||||
{
|
||||
m_master->NoteOff( 0, _e.key() );
|
||||
m_master->NoteOff( _e.channel(), _e.key() );
|
||||
}
|
||||
break;
|
||||
case MidiPitchBend:
|
||||
m_master->SetController( 0, C_pitchwheel,
|
||||
m_master->SetController( _e.channel(), C_pitchwheel,
|
||||
_e.m_data.m_param[0] +
|
||||
_e.m_data.m_param[1]*128-8192 );
|
||||
break;
|
||||
case MidiControlChange:
|
||||
m_master->SetController( 0,
|
||||
m_master->SetController( _e.channel(),
|
||||
midiIn.getcontroller( _e.m_data.m_param[0] ),
|
||||
_e.m_data.m_param[1] );
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ZynAddSubFx.cpp - ZynAddSubxFX-embedding plugin
|
||||
*
|
||||
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -301,6 +301,9 @@ void ZynAddSubFxInstrument::loadFile( const QString & _file )
|
||||
m_pluginMutex.unlock();
|
||||
}
|
||||
|
||||
instrumentTrack()->setName( QFileInfo( _file ).baseName().
|
||||
replace( QRegExp( "^[0-9]{4}-" ), QString() ) );
|
||||
|
||||
m_modifiedControllers.clear();
|
||||
|
||||
emit settingsChanged();
|
||||
@@ -447,7 +450,7 @@ void ZynAddSubFxInstrument::initPlugin()
|
||||
|
||||
void ZynAddSubFxInstrument::sendControlChange( MidiControllers midiCtl, float value )
|
||||
{
|
||||
handleMidiEvent( midiEvent( MidiControlChange, 0, midiCtl, (int) value, this ),
|
||||
handleMidiEvent( midiEvent( MidiControlChange, instrumentTrack()->midiPort()->realOutputChannel(), midiCtl, (int) value, this ),
|
||||
midiTime() );
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ extern int OSCIL_SIZE;
|
||||
/*
|
||||
* The poliphony (notes)
|
||||
*/
|
||||
#define POLIPHONY 60
|
||||
#define POLIPHONY 128
|
||||
|
||||
/*
|
||||
* Number of system effects
|
||||
|
||||
Reference in New Issue
Block a user