mirror of
https://github.com/LMMS/lmms.git
synced 2026-01-22 21:38:12 -05:00
# Conflicts: # CMakeLists.txt # cmake/linux/package_linux.sh.in # src/3rdparty/CMakeLists.txt # src/core/Track.cpp # src/gui/editors/PianoRoll.cpp # src/tracks/SampleTrack.cpp
382 lines
8.4 KiB
C++
382 lines
8.4 KiB
C++
/*
|
|
* LadspaControl.cpp - model for controlling a LADSPA port
|
|
*
|
|
* Copyright (c) 2008-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
|
* Copyright (c) 2006-2008 Danny McRae <khjklujn/at/users.sourceforge.net>
|
|
*
|
|
* This file is part of LMMS - https://lmms.io
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program (see COPYING); if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA.
|
|
*
|
|
*/
|
|
|
|
#include <cstdio>
|
|
|
|
#include "LadspaControl.h"
|
|
#include "LadspaBase.h"
|
|
|
|
|
|
LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port,
|
|
bool _link ) :
|
|
Model( _parent ),
|
|
m_link( _link ),
|
|
m_port( _port ),
|
|
m_linkEnabledModel( _link, this, tr( "Link channels" ) ),
|
|
m_toggledModel( false, this, m_port->name ),
|
|
m_knobModel( 0, 0, 0, 1, this, m_port->name ),
|
|
m_tempoSyncKnobModel( 0, 0, 0, 1, m_port->max, this, m_port->name )
|
|
{
|
|
if( m_link )
|
|
{
|
|
connect( &m_linkEnabledModel, SIGNAL( dataChanged() ),
|
|
this, SLOT( linkStateChanged() ),
|
|
Qt::DirectConnection );
|
|
}
|
|
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
m_toggledModel.setInitValue(
|
|
static_cast<bool>( m_port->def ) );
|
|
connect( &m_toggledModel, SIGNAL( dataChanged() ),
|
|
this, SLOT( ledChanged() ) );
|
|
if( m_port->def == 1.0f )
|
|
{
|
|
m_toggledModel.setValue( true );
|
|
}
|
|
// TODO: careful: we must prevent saved scales
|
|
m_toggledModel.setScaleLogarithmic( m_port->suggests_logscale );
|
|
break;
|
|
|
|
case INTEGER:
|
|
case ENUM:
|
|
m_knobModel.setRange( static_cast<int>( m_port->max ),
|
|
static_cast<int>( m_port->min ),
|
|
1 + static_cast<int>( m_port->max -
|
|
m_port->min ) / 400 );
|
|
m_knobModel.setInitValue(
|
|
static_cast<int>( m_port->def ) );
|
|
connect( &m_knobModel, SIGNAL( dataChanged() ),
|
|
this, SLOT( knobChanged() ) );
|
|
// TODO: careful: we must prevent saved scales
|
|
m_knobModel.setScaleLogarithmic( m_port->suggests_logscale );
|
|
break;
|
|
|
|
case FLOATING:
|
|
m_knobModel.setRange( m_port->min, m_port->max,
|
|
( m_port->max - m_port->min )
|
|
/ ( m_port->name.toUpper() == "GAIN"
|
|
&& m_port->max == 10.0f ? 4000.0f :
|
|
( m_port->suggests_logscale ? 8000.0f : 800.0f ) ) );
|
|
m_knobModel.setInitValue( m_port->def );
|
|
connect( &m_knobModel, SIGNAL( dataChanged() ),
|
|
this, SLOT( knobChanged() ) );
|
|
// TODO: careful: we must prevent saved scales
|
|
m_knobModel.setScaleLogarithmic( m_port->suggests_logscale );
|
|
break;
|
|
|
|
case TIME:
|
|
m_tempoSyncKnobModel.setRange( m_port->min, m_port->max,
|
|
( m_port->max -
|
|
m_port->min ) / 800.0f );
|
|
m_tempoSyncKnobModel.setInitValue( m_port->def );
|
|
connect( &m_tempoSyncKnobModel, SIGNAL( dataChanged() ),
|
|
this, SLOT( tempoKnobChanged() ) );
|
|
// TODO: careful: we must prevent saved scales
|
|
m_tempoSyncKnobModel.setScaleLogarithmic( m_port->suggests_logscale );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
LadspaControl::~LadspaControl()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
LADSPA_Data LadspaControl::value()
|
|
{
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
return static_cast<LADSPA_Data>( m_toggledModel.value() );
|
|
case INTEGER:
|
|
case ENUM:
|
|
case FLOATING:
|
|
return static_cast<LADSPA_Data>( m_knobModel.value() );
|
|
case TIME:
|
|
return static_cast<LADSPA_Data>( m_tempoSyncKnobModel.value() );
|
|
default:
|
|
qWarning( "LadspaControl::value(): BAD BAD BAD\n" );
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
ValueBuffer * LadspaControl::valueBuffer()
|
|
{
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
case INTEGER:
|
|
case ENUM:
|
|
return NULL;
|
|
case FLOATING:
|
|
return m_knobModel.valueBuffer();
|
|
case TIME:
|
|
return m_tempoSyncKnobModel.valueBuffer();
|
|
default:
|
|
qWarning( "LadspaControl::valueBuffer(): BAD BAD BAD\n" );
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
void LadspaControl::setValue( LADSPA_Data _value )
|
|
{
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
m_toggledModel.setValue( static_cast<bool>( _value ) );
|
|
break;
|
|
case INTEGER:
|
|
case ENUM:
|
|
m_knobModel.setValue( static_cast<int>( _value ) );
|
|
break;
|
|
case FLOATING:
|
|
m_knobModel.setValue( static_cast<float>( _value ) );
|
|
break;
|
|
case TIME:
|
|
m_tempoSyncKnobModel.setValue( static_cast<float>(
|
|
_value ) );
|
|
break;
|
|
default:
|
|
printf("LadspaControl::setValue BAD BAD BAD\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::saveSettings( QDomDocument& doc,
|
|
QDomElement& parent,
|
|
const QString& name )
|
|
{
|
|
QDomElement e = doc.createElement( name );
|
|
|
|
if( m_link )
|
|
{
|
|
m_linkEnabledModel.saveSettings( doc, e, "link" );
|
|
}
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
m_toggledModel.saveSettings( doc, e, "data" );
|
|
break;
|
|
case INTEGER:
|
|
case ENUM:
|
|
case FLOATING:
|
|
m_knobModel.saveSettings( doc, e, "data" );
|
|
break;
|
|
case TIME:
|
|
m_tempoSyncKnobModel.saveSettings( doc, e, "data" );
|
|
break;
|
|
default:
|
|
printf("LadspaControl::saveSettings BAD BAD BAD\n");
|
|
break;
|
|
}
|
|
|
|
parent.appendChild( e );
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::loadSettings( const QDomElement& parent, const QString& name )
|
|
{
|
|
QString dataModelName = "data";
|
|
QString linkModelName = "link";
|
|
QDomElement e = parent.namedItem( name ).toElement();
|
|
|
|
if(e.isNull())
|
|
{
|
|
// the port exists in the current effect, but not in the
|
|
// savefile => it's a new port, so load the default value
|
|
if( m_link )
|
|
m_linkEnabledModel.setValue(m_linkEnabledModel.initValue());
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
m_toggledModel.setValue(m_toggledModel.initValue());
|
|
break;
|
|
case INTEGER:
|
|
case ENUM:
|
|
case FLOATING:
|
|
m_knobModel.setValue(m_knobModel.initValue());
|
|
break;
|
|
case TIME:
|
|
m_tempoSyncKnobModel.setValue(m_tempoSyncKnobModel.initValue());
|
|
break;
|
|
default:
|
|
printf("LadspaControl::loadSettings BAD BAD BAD\n");
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
// COMPAT < 1.0.0: detect old data format where there's either no dedicated sub
|
|
// element or there's a direct sub element with automation link information
|
|
if( e.isNull() || e.hasAttribute( "id" ) )
|
|
{
|
|
dataModelName = name;
|
|
linkModelName = name + "link";
|
|
e = parent;
|
|
}
|
|
|
|
if( m_link )
|
|
{
|
|
m_linkEnabledModel.loadSettings( e, linkModelName );
|
|
}
|
|
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
m_toggledModel.loadSettings( e, dataModelName );
|
|
break;
|
|
case INTEGER:
|
|
case ENUM:
|
|
case FLOATING:
|
|
m_knobModel.loadSettings( e, dataModelName );
|
|
break;
|
|
case TIME:
|
|
m_tempoSyncKnobModel.loadSettings( e, dataModelName );
|
|
break;
|
|
default:
|
|
printf("LadspaControl::loadSettings BAD BAD BAD\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::linkControls( LadspaControl * _control )
|
|
{
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
BoolModel::linkModels( &m_toggledModel, _control->toggledModel() );
|
|
break;
|
|
case INTEGER:
|
|
case ENUM:
|
|
case FLOATING:
|
|
FloatModel::linkModels( &m_knobModel, _control->knobModel() );
|
|
break;
|
|
case TIME:
|
|
TempoSyncKnobModel::linkModels( &m_tempoSyncKnobModel,
|
|
_control->tempoSyncKnobModel() );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::ledChanged()
|
|
{
|
|
emit changed( m_port->port_id, static_cast<LADSPA_Data>(
|
|
m_toggledModel.value() ) );
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::knobChanged()
|
|
{
|
|
emit changed( m_port->port_id, static_cast<LADSPA_Data>(
|
|
m_knobModel.value() ) );
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::tempoKnobChanged()
|
|
{
|
|
emit changed( m_port->port_id, static_cast<LADSPA_Data>(
|
|
m_tempoSyncKnobModel.value() ) );
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::unlinkControls( LadspaControl * _control )
|
|
{
|
|
switch( m_port->data_type )
|
|
{
|
|
case TOGGLED:
|
|
BoolModel::unlinkModels( &m_toggledModel, _control->toggledModel() );
|
|
break;
|
|
case INTEGER:
|
|
case ENUM:
|
|
case FLOATING:
|
|
FloatModel::unlinkModels( &m_knobModel, _control->knobModel() );
|
|
break;
|
|
case TIME:
|
|
TempoSyncKnobModel::unlinkModels( &m_tempoSyncKnobModel,
|
|
_control->tempoSyncKnobModel() );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::linkStateChanged()
|
|
{
|
|
emit linkChanged( m_port->control_id, m_linkEnabledModel.value() );
|
|
}
|
|
|
|
|
|
|
|
|
|
void LadspaControl::setLink( bool _state )
|
|
{
|
|
m_linkEnabledModel.setValue( _state );
|
|
}
|
|
|
|
|
|
|
|
|