Beispiel #1
0
LadspaEffect::LadspaEffect( Model * _parent,
			const Descriptor::SubPluginFeatures::Key * _key ) :
	Effect( &ladspaeffect_plugin_descriptor, _parent, _key ),
	m_controls( NULL ),
	m_maxSampleRate( 0 ),
	m_key( LadspaSubPluginFeatures::subPluginKeyToLadspaKey( _key ) )
{
	Ladspa2LMMS * manager = Engine::getLADSPAManager();
	if( manager->getDescription( m_key ) == NULL )
	{
		if( !Engine::suppressMessages() )
		{
			QMessageBox::warning( 0, tr( "Effect" ), 
				tr( "Unknown LADSPA plugin %1 requested." ).
							arg( m_key.second ),
				QMessageBox::Ok, QMessageBox::NoButton );
		}
		setOkay( false );
		return;
	}

	setDisplayName( manager->getShortName( m_key ) );

	pluginInstantiation();

	connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
					this, SLOT( changeSampleRate() ) );
}
void LadspaSubPluginFeatures::listSubPluginKeys(
    const Plugin::Descriptor * _desc, KeyList & _kl ) const
{
    Ladspa2LMMS * lm = Engine::getLADSPAManager();

    l_sortable_plugin_t plugins;
    switch( m_type )
    {
    case Plugin::Instrument:
        plugins = lm->getInstruments();
        break;
    case Plugin::Effect:
        plugins = lm->getValidEffects();
        //plugins += lm->getInvalidEffects();
        break;
    case Plugin::Tool:
        plugins = lm->getAnalysisTools();
        break;
    case Plugin::Other:
        plugins = lm->getOthers();
        break;
    default:
        break;
    }

    for( l_sortable_plugin_t::const_iterator it = plugins.begin();
            it != plugins.end(); ++it )
    {
        if( lm->getDescription( ( *it ).second )->inputChannels <=
                Engine::mixer()->audioDev()->channels() )
        {
            _kl.push_back( ladspaKeyToSubPluginKey( _desc, ( *it ).first, ( *it ).second ) );
        }
    }
}
void LadspaSubPluginFeatures::fillDescriptionWidget( QWidget * _parent,
        const Key * _key  ) const
{
    const ladspa_key_t & lkey = subPluginKeyToLadspaKey( _key );
    Ladspa2LMMS * lm = Engine::getLADSPAManager();

    QLabel * label = new QLabel( _parent );
    label->setText( QWidget::tr( "Name: " ) + lm->getName( lkey ) );

    QLabel* fileInfo = new QLabel( _parent );
    fileInfo->setText( QWidget::tr( "File: %1" ).arg( lkey.first ) );

    QWidget * maker = new QWidget( _parent );
    QHBoxLayout * l = new QHBoxLayout( maker );
    l->setMargin( 0 );
    l->setSpacing( 0 );

    QLabel * maker_label = new QLabel( maker );
    maker_label->setText( QWidget::tr( "Maker: " ) );
    maker_label->setAlignment( Qt::AlignTop );
    QLabel * maker_content = new QLabel( maker );
    maker_content->setText( lm->getMaker( lkey ) );
    maker_content->setWordWrap( true );
    l->addWidget( maker_label );
    l->addWidget( maker_content, 1 );

    QWidget * copyright = new QWidget( _parent );
    l = new QHBoxLayout( copyright );
    l->setMargin( 0 );
    l->setSpacing( 0 );

    copyright->setMinimumWidth( _parent->minimumWidth() );
    QLabel * copyright_label = new QLabel( copyright );
    copyright_label->setText( QWidget::tr( "Copyright: " ) );
    copyright_label->setAlignment( Qt::AlignTop );

    QLabel * copyright_content = new QLabel( copyright );
    copyright_content->setText( lm->getCopyright( lkey ) );
    copyright_content->setWordWrap( true );
    l->addWidget( copyright_label );
    l->addWidget( copyright_content, 1 );

    QLabel * requiresRealTime = new QLabel( _parent );
    requiresRealTime->setText( QWidget::tr( "Requires Real Time: " ) +
                               ( lm->hasRealTimeDependency( lkey ) ?
                                 QWidget::tr( "Yes" ) :
                                 QWidget::tr( "No" ) ) );

    QLabel * realTimeCapable = new QLabel( _parent );
    realTimeCapable->setText( QWidget::tr( "Real Time Capable: " ) +
                              ( lm->isRealTimeCapable( lkey ) ?
                                QWidget::tr( "Yes" ) :
                                QWidget::tr( "No" ) ) );

    QLabel * inplaceBroken = new QLabel( _parent );
    inplaceBroken->setText( QWidget::tr( "In Place Broken: " ) +
                            ( lm->isInplaceBroken( lkey ) ?
                              QWidget::tr( "Yes" ) :
                              QWidget::tr( "No" ) ) );

    QLabel * channelsIn = new QLabel( _parent );
    channelsIn->setText( QWidget::tr( "Channels In: " ) +
                         QString::number( lm->getDescription( lkey )->inputChannels ) );

    QLabel * channelsOut = new QLabel( _parent );
    channelsOut->setText( QWidget::tr( "Channels Out: " ) +
                          QString::number( lm->getDescription( lkey )->outputChannels ) );
}
Beispiel #4
0
void LadspaEffect::pluginInstantiation()
{
	m_maxSampleRate = maxSamplerate( displayName() );

	Ladspa2LMMS * manager = Engine::getLADSPAManager();

	// Calculate how many processing units are needed.
	const ch_cnt_t lmms_chnls = Engine::mixer()->audioDev()->channels();
	int effect_channels = manager->getDescription( m_key )->inputChannels;
	setProcessorCount( lmms_chnls / effect_channels );

	// get inPlaceBroken property
	m_inPlaceBroken = manager->isInplaceBroken( m_key );

	// Categorize the ports, and create the buffers.
	m_portCount = manager->getPortCount( m_key );

	int inputch = 0;
	int outputch = 0;
	LADSPA_Data * inbuf [2];
	inbuf[0] = NULL;
	inbuf[1] = NULL;
	for( ch_cnt_t proc = 0; proc < processorCount(); proc++ )
	{
		multi_proc_t ports;
		for( int port = 0; port < m_portCount; port++ )
		{
			port_desc_t * p = new PortDescription;

			p->name = manager->getPortName( m_key, port );
			p->proc = proc;
			p->port_id = port;
			p->control = NULL;
			p->buffer = NULL;

			// Determine the port's category.
			if( manager->isPortAudio( m_key, port ) )
			{
				if( p->name.toUpper().contains( "IN" ) &&
					manager->isPortInput( m_key, port ) )
				{
					p->rate = CHANNEL_IN;
					p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() );
					inbuf[ inputch ] = p->buffer;
					inputch++;
				}
				else if( p->name.toUpper().contains( "OUT" ) &&
					manager->isPortOutput( m_key, port ) )
				{
					p->rate = CHANNEL_OUT;
					if( ! m_inPlaceBroken && inbuf[ outputch ] )
					{
						p->buffer = inbuf[ outputch ];
						outputch++;
					}
					else
					{
						p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() );
						m_inPlaceBroken = true;
					}
				}
				else if( manager->isPortInput( m_key, port ) )
				{
					p->rate = AUDIO_RATE_INPUT;
					p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() );
				}
				else
				{
					p->rate = AUDIO_RATE_OUTPUT;
					p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() );
				}
			}
			else
			{
				p->buffer = MM_ALLOC( LADSPA_Data, 1 );

				if( manager->isPortInput( m_key, port ) )
				{
					p->rate = CONTROL_RATE_INPUT;
				}
				else
				{
					p->rate = CONTROL_RATE_OUTPUT;
				}
			}

			p->scale = 1.0f;
			if( manager->isPortToggled( m_key, port ) )
			{
				p->data_type = TOGGLED;
			}
			else if( manager->isInteger( m_key, port ) )
			{
				p->data_type = INTEGER;
			}
			else if( p->name.toUpper().contains( "(SECONDS)" ) )
			{
				p->data_type = TIME;
				p->scale = 1000.0f;
				int loc = p->name.toUpper().indexOf(
								"(SECONDS)" );
				p->name.replace( loc, 9, "(ms)" );
			}
			else if( p->name.toUpper().contains( "(S)" ) )
			{
				p->data_type = TIME;
				p->scale = 1000.0f;
				int loc = p->name.toUpper().indexOf( "(S)" );
				p->name.replace( loc, 3, "(ms)" );
			}
			else if( p->name.toUpper().contains( "(MS)" ) )
			{
				p->data_type = TIME;
				int loc = p->name.toUpper().indexOf( "(MS)" );
				p->name.replace( loc, 4, "(ms)" );
			}
			else
			{
				p->data_type = FLOATING;
			}

			// Get the range and default values.
			p->max = manager->getUpperBound( m_key, port );
			if( p->max == NOHINT )
			{
				p->max = p->name.toUpper() == "GAIN" ? 10.0f :
					1.0f;
			}

			if( manager->areHintsSampleRateDependent(
								m_key, port ) )
			{
				p->max *= m_maxSampleRate;
			}

			p->min = manager->getLowerBound( m_key, port );
			if( p->min == NOHINT )
			{
				p->min = 0.0f;
			}

			if( manager->areHintsSampleRateDependent(
								m_key, port ) )
			{
				p->min *= m_maxSampleRate;
			}

			p->def = manager->getDefaultSetting( m_key, port );
			if( p->def == NOHINT )
			{
				if( p->data_type != TOGGLED )
				{
					p->def = ( p->min + p->max ) / 2.0f;
				}
				else
				{
					p->def = 1.0f;
				}
			}
			else if( manager->areHintsSampleRateDependent( m_key, port ) )
			{
				p->def *= m_maxSampleRate;
			}


			p->max *= p->scale;
			p->min *= p->scale;
			p->def *= p->scale;

			p->value = p->def;

			p->suggests_logscale = manager->isLogarithmic( m_key, port );

			ports.append( p );

	// For convenience, keep a separate list of the ports that are used 
	// to control the processors.
			if( p->rate == AUDIO_RATE_INPUT || 
					p->rate == CONTROL_RATE_INPUT )
			{
				p->control_id = m_portControls.count();
				m_portControls.append( p );
			}
		}
		m_ports.append( ports );
	}

	// Instantiate the processing units.
	m_descriptor = manager->getDescriptor( m_key );
	if( m_descriptor == NULL )
	{
		QMessageBox::warning( 0, "Effect", 
			"Can't get LADSPA descriptor function: " + m_key.second,
			QMessageBox::Ok, QMessageBox::NoButton );
		setOkay( false );
		return;
	}
	if( m_descriptor->run == NULL )
	{
		QMessageBox::warning( 0, "Effect",
			"Plugin has no processor: " + m_key.second,
			QMessageBox::Ok, QMessageBox::NoButton );
		setDontRun( true );
	}
	for( ch_cnt_t proc = 0; proc < processorCount(); proc++ )
	{
		LADSPA_Handle effect = manager->instantiate( m_key,
							m_maxSampleRate );
		if( effect == NULL )
		{
			QMessageBox::warning( 0, "Effect",
				"Can't get LADSPA instance: " + m_key.second,
				QMessageBox::Ok, QMessageBox::NoButton );
			setOkay( false );
			return;
		}
		m_handles.append( effect );
	}

	// Connect the ports.
	for( ch_cnt_t proc = 0; proc < processorCount(); proc++ )
	{
		for( int port = 0; port < m_portCount; port++ )
		{
			port_desc_t * pp = m_ports.at( proc ).at( port );
			if( !manager->connectPort( m_key,
						m_handles[proc],
						port,
						pp->buffer ) )
			{
				QMessageBox::warning( 0, "Effect", 
				"Failed to connect port: " + m_key.second, 
				QMessageBox::Ok, QMessageBox::NoButton );
				setDontRun( true );
				return;
			}
		}
	}

	// Activate the processing units.
	for( ch_cnt_t proc = 0; proc < processorCount(); proc++ )
	{
		manager->activate( m_key, m_handles[proc] );
	}
	m_controls = new LadspaControls( this );
}