Merge branch 'stable-1.2'

# Conflicts:
#	.travis.yml
#	.travis/linux..script.sh
#	.travis/linux.win32.script.sh
#	.travis/linux.win64.script.sh
#	.travis/osx..install.sh
#	.travis/osx..script.sh
#	data/locale/en.ts
#	data/locale/id.ts
#	include/Graph.h
#	include/VstSyncController.h
#	include/lmms_math.h
#	plugins/vst_base/RemoteVstPlugin.cpp
#	src/core/RemotePlugin.cpp
#	src/core/Song.cpp
#	src/core/Track.cpp
#	src/gui/SubWindow.cpp
#	src/gui/widgets/Graph.cpp
This commit is contained in:
Hyunjin Song
2019-02-24 20:43:45 +09:00
92 changed files with 5767 additions and 3727 deletions

View File

@@ -275,7 +275,8 @@ void MidiExport::writePattern(MidiNoteVector &pat, QDomNode n,
// TODO interpret pan="0" fxch="0" pitchrange="1"
MidiNote mnote;
mnote.pitch = qMax(0, qMin(127, note.attribute("key", "0").toInt() + base_pitch));
mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100"))), 127);
// Map from LMMS volume to MIDI velocity
mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100")) * (127.0 / 200.0)), 127);
mnote.time = base_time + note.attribute("pos", "0").toInt();
mnote.duration = note.attribute("len", "0").toInt();
pat.push_back(mnote);

View File

@@ -428,7 +428,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
Note n( (ticks < 1 ? 1 : ticks ),
noteEvt->get_start_time() * ticksPerBeat,
noteEvt->get_identifier() - 12,
noteEvt->get_loud());
noteEvt->get_loud() * (200.f / 127.f)); // Map from MIDI velocity to LMMS volume
ch->addNote( n );
}

View File

@@ -54,8 +54,10 @@ void Alg_atoms::expand()
maxlen += (maxlen >> 2); // add 25%
char **new_atoms = new Alg_attribute[maxlen];
// now do copy
memcpy(new_atoms, atoms, len * sizeof(Alg_attribute));
if (atoms) delete[] atoms;
if (atoms) {
memcpy(new_atoms, atoms, len * sizeof(Alg_attribute));
delete[] atoms;
}
atoms = new_atoms;
}

View File

@@ -90,7 +90,13 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2)));
}
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
#if QT_VERSION < 0x050000
connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ),
this, SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( knobFModel[i], &FloatModel::dataChanged, this,
[this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection);
#endif
}
}
@@ -100,10 +106,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
void VstEffectControls::setParameter( void )
void VstEffectControls::setParameter( Model * action )
{
Model *action = qobject_cast<Model *>(sender());
int knobUNID = action->displayName().toInt();
if ( m_effect->m_plugin != NULL ) {
@@ -377,9 +381,16 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
m_vi->knobFModel[ i ] = new FloatModel( LocaleHelper::toFloat(s_dumpValues.at(2)),
0.0f, 1.0f, 0.01f, _eff, tr( paramStr ) );
}
connect( m_vi->knobFModel[ i ], SIGNAL( dataChanged() ), this,
SLOT( setParameter() ) );
vstKnobs[ i ] ->setModel( m_vi->knobFModel[ i ] );
FloatModel * model = m_vi->knobFModel[i];
#if QT_VERSION < 0x050000
connect( model, SIGNAL( dataChanged( Model * ) ), this,
SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( model, &FloatModel::dataChanged, this,
[this, model]() { setParameter( model ); }, Qt::DirectConnection);
#endif
vstKnobs[ i ] ->setModel( model );
}
int i = 0;
@@ -472,10 +483,8 @@ void manageVSTEffectView::displayAutomatedOnly( void )
void manageVSTEffectView::setParameter( void )
void manageVSTEffectView::setParameter( Model * action )
{
Model *action = qobject_cast<Model *>(sender());
int knobUNID = action->displayName().toInt();
if ( m_effect->m_plugin != NULL ) {

View File

@@ -70,7 +70,7 @@ protected slots:
void rollPreset( void );
void rolrPreset( void );
void selPreset( void );
void setParameter( void );
void setParameter( Model * action );
protected:
virtual void paintEvent( QPaintEvent * _pe );
@@ -110,7 +110,7 @@ public:
protected slots:
void syncPlugin( void );
void displayAutomatedOnly( void );
void setParameter( void );
void setParameter( Model * action );
void closeWindow();
private:

View File

@@ -474,6 +474,7 @@ void bitInvaderView::modelChanged()
void bitInvaderView::sinWaveClicked()
{
m_graph->model()->clearInvisible();
m_graph->model()->setWaveToSine();
Engine::getSong()->setModified();
}
@@ -483,6 +484,7 @@ void bitInvaderView::sinWaveClicked()
void bitInvaderView::triangleWaveClicked()
{
m_graph->model()->clearInvisible();
m_graph->model()->setWaveToTriangle();
Engine::getSong()->setModified();
}
@@ -492,6 +494,7 @@ void bitInvaderView::triangleWaveClicked()
void bitInvaderView::sawWaveClicked()
{
m_graph->model()->clearInvisible();
m_graph->model()->setWaveToSaw();
Engine::getSong()->setModified();
}
@@ -501,6 +504,7 @@ void bitInvaderView::sawWaveClicked()
void bitInvaderView::sqrWaveClicked()
{
m_graph->model()->clearInvisible();
m_graph->model()->setWaveToSquare();
Engine::getSong()->setModified();
}
@@ -510,6 +514,7 @@ void bitInvaderView::sqrWaveClicked()
void bitInvaderView::noiseWaveClicked()
{
m_graph->model()->clearInvisible();
m_graph->model()->setWaveToNoise();
Engine::getSong()->setModified();
}
@@ -520,35 +525,12 @@ void bitInvaderView::noiseWaveClicked()
void bitInvaderView::usrWaveClicked()
{
QString fileName = m_graph->model()->setWaveToUser();
ToolTip::add( m_usrWaveBtn, fileName );
Engine::getSong()->setModified();
/*
m_graph->model()->setWaveToNoise();
Engine::getSong()->setModified();
// zero sample_shape
for (int i = 0; i < sample_length; i++)
if (!fileName.isEmpty())
{
sample_shape[i] = 0;
ToolTip::add(m_usrWaveBtn, fileName);
m_graph->model()->clearInvisible();
Engine::getSong()->setModified();
}
// load user shape
sampleBuffer buffer;
QString af = buffer.openAudioFile();
if ( af != "" )
{
buffer.setAudioFile( af );
// copy buffer data
sample_length = min( sample_length, static_cast<int>(
buffer.frames() ) );
for ( int i = 0; i < sample_length; i++ )
{
sample_shape[i] = (float)*buffer.data()[i];
}
}
sampleChanged();
*/
}

View File

@@ -65,7 +65,7 @@ PeakControllerEffect::PeakControllerEffect(
Effect( &peakcontrollereffect_plugin_descriptor, _parent, _key ),
m_effectId( rand() ),
m_peakControls( this ),
m_lastSample( m_peakControls.m_baseModel.value() ), //sets the value to the Peak Controller's Base value (rather than 0 like in previous versions)
m_lastSample( 0 ),
m_autoController( NULL )
{
m_autoController = new PeakController( Engine::getSong(), this );

View File

@@ -53,6 +53,7 @@ PeakControllerEffectControls( PeakControllerEffect * _eff ) :
void PeakControllerEffectControls::loadSettings( const QDomElement & _this )
{
m_baseModel.loadSettings( _this, "base" );
m_effect->m_lastSample = m_baseModel.value(); //Set initial Peak Controller output to Base
m_amountModel.loadSettings( _this, "amount" );
m_muteModel.loadSettings( _this, "mute" );

View File

@@ -114,6 +114,9 @@ public:
void createUI( QWidget *parent ) override
{
Q_UNUSED(parent);
if ( !hasEditor() ) {
return;
}
if ( embedMethod() != "none" ) {
m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() ));
VstPlugin::createUI( m_pluginSubWindow.get() );
@@ -214,7 +217,13 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2)));
}
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
#if QT_VERSION < 0x050000
connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ),
this, SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( knobFModel[i], &FloatModel::dataChanged, this,
[this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection);
#endif
}
}
m_pluginMutex.unlock();
@@ -223,10 +232,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
void vestigeInstrument::setParameter( void )
void vestigeInstrument::setParameter( Model * action )
{
Model *action = qobject_cast<Model *>(sender());
int knobUNID = action->displayName().toInt();
if ( m_plugin != NULL ) {
@@ -969,8 +976,16 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
m_vi->knobFModel[ i ] = new FloatModel( LocaleHelper::toFloat(s_dumpValues.at(2)),
0.0f, 1.0f, 0.01f, castModel<vestigeInstrument>(), tr( paramStr ) );
}
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
FloatModel * model = m_vi->knobFModel[i];
#if QT_VERSION < 0x050000
connect( model, SIGNAL( dataChanged( Model * ) ), this,
SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( model, &FloatModel::dataChanged, this,
[this, model]() { setParameter( model ); }, Qt::DirectConnection);
#endif
vstKnobs[i] ->setModel( model );
}
int i = 0;
@@ -1101,10 +1116,8 @@ manageVestigeInstrumentView::~manageVestigeInstrumentView()
void manageVestigeInstrumentView::setParameter( void )
void manageVestigeInstrumentView::setParameter( Model * action )
{
Model *action = qobject_cast<Model *>(sender());
int knobUNID = action->displayName().toInt();
if ( m_vi->m_plugin != NULL ) {

View File

@@ -73,7 +73,7 @@ public:
virtual PluginView * instantiateView( QWidget * _parent );
protected slots:
void setParameter( void );
void setParameter( Model * action );
void handleConfigChange( QString cls, QString attr, QString value );
void reloadPlugin();
@@ -109,7 +109,7 @@ public:
protected slots:
void syncPlugin( void );
void displayAutomatedOnly( void );
void setParameter( void );
void setParameter( Model * action );
void closeWindow();

View File

@@ -65,6 +65,7 @@
# include <mutex>
#endif
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
@@ -415,8 +416,8 @@ private:
// host to plugin synchronisation data structure
struct in
{
float lastppqPos;
float m_Timestamp;
double lastppqPos;
double m_Timestamp;
int32_t m_lastFlags;
} ;
@@ -913,6 +914,14 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out )
static char eventsBuffer[sizeof( VstEvents ) + sizeof( VstMidiEvent * ) * MIDI_EVENT_BUFFER_COUNT];
static VstMidiEvent vme[MIDI_EVENT_BUFFER_COUNT];
// first sort events chronologically, since some plugins
// (e.g. Sinnah) can hang if they're out of order
std::stable_sort( m_midiEvents.begin(), m_midiEvents.end(),
[]( const VstMidiEvent &a, const VstMidiEvent &b )
{
return a.deltaFrames < b.deltaFrames;
} );
VstEvents* events = (VstEvents *) eventsBuffer;
events->reserved = 0;
events->numEvents = m_midiEvents.size();
@@ -1609,10 +1618,20 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
}
else if( __plugin->m_vstSyncData->isPlaying )
{
__plugin->m_in->lastppqPos += (
__plugin->m_vstSyncData->hasSHM ?
__plugin->m_vstSyncData->m_bpm :
__plugin->m_bpm ) / (float)10340;
if( __plugin->m_vstSyncData->hasSHM )
{
__plugin->m_in->lastppqPos +=
__plugin->m_vstSyncData->m_bpm / 60.0
* __plugin->m_vstSyncData->m_bufferSize
/ __plugin->m_vstSyncData->m_sampleRate;
}
else
{
__plugin->m_in->lastppqPos +=
__plugin->m_bpm / 60.0
* __plugin->bufferSize()
/ __plugin->sampleRate();
}
_timeInfo.ppqPos = __plugin->m_in->lastppqPos;
}
// _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos;
@@ -1945,7 +1964,9 @@ DWORD WINAPI RemoteVstPlugin::processingThread( LPVOID _param )
RemotePluginClient::message m;
while( ( m = _this->receiveMessage() ).id != IdQuit )
{
if( m.id == IdStartProcessing || m.id == IdMidiEvent )
if( m.id == IdStartProcessing
|| m.id == IdMidiEvent
|| m.id == IdVstSetParameter )
{
_this->processMessage( m );
}

View File

@@ -163,6 +163,10 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp "${WINRC}")
INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION "${PLUGIN_DIR}")
IF(LMMS_BUILD_WIN32)
SET_TARGET_PROPERTIES(RemoteZynAddSubFx PROPERTIES LINK_FLAGS "${LINK_FLAGS} -mwindows")
ENDIF(LMMS_BUILD_WIN32)
# Remove useless dependencies from FLTK. Use fltk-config to avoid static library
# in older environments
SET(FLTK_FILTERED_LDFLAGS ${FLTK_LIBRARIES})

View File

@@ -121,13 +121,20 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument(
{
initPlugin();
connect( &m_portamentoModel, SIGNAL( dataChanged() ), this, SLOT( updatePortamento() ) );
connect( &m_filterFreqModel, SIGNAL( dataChanged() ), this, SLOT( updateFilterFreq() ) );
connect( &m_filterQModel, SIGNAL( dataChanged() ), this, SLOT( updateFilterQ() ) );
connect( &m_bandwidthModel, SIGNAL( dataChanged() ), this, SLOT( updateBandwidth() ) );
connect( &m_fmGainModel, SIGNAL( dataChanged() ), this, SLOT( updateFmGain() ) );
connect( &m_resCenterFreqModel, SIGNAL( dataChanged() ), this, SLOT( updateResCenterFreq() ) );
connect( &m_resBandwidthModel, SIGNAL( dataChanged() ), this, SLOT( updateResBandwidth() ) );
connect( &m_portamentoModel, SIGNAL( dataChanged() ),
this, SLOT( updatePortamento() ), Qt::DirectConnection );
connect( &m_filterFreqModel, SIGNAL( dataChanged() ),
this, SLOT( updateFilterFreq() ), Qt::DirectConnection );
connect( &m_filterQModel, SIGNAL( dataChanged() ),
this, SLOT( updateFilterQ() ), Qt::DirectConnection );
connect( &m_bandwidthModel, SIGNAL( dataChanged() ),
this, SLOT( updateBandwidth() ), Qt::DirectConnection );
connect( &m_fmGainModel, SIGNAL( dataChanged() ),
this, SLOT( updateFmGain() ), Qt::DirectConnection );
connect( &m_resCenterFreqModel, SIGNAL( dataChanged() ),
this, SLOT( updateResCenterFreq() ), Qt::DirectConnection );
connect( &m_resBandwidthModel, SIGNAL( dataChanged() ),
this, SLOT( updateResBandwidth() ), Qt::DirectConnection );
// now we need a play-handle which cares for calling play()
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrumentTrack );
@@ -137,7 +144,7 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument(
this, SLOT( reloadPlugin() ) );
connect( instrumentTrack()->pitchRangeModel(), SIGNAL( dataChanged() ),
this, SLOT( updatePitchRange() ) );
this, SLOT( updatePitchRange() ), Qt::DirectConnection );
}