code:
/*
 * DspEffectLibrary.h - library with template-based inline-effects
 *
 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef DSP_EFFECT_LIBRARY_H
#define DSP_EFFECT_LIBRARY_H

#include "lmms_math.h"
#include "lmms_constants.h"
#include "lmms_basics.h"

namespace DspEffectLibrary
{

	template<typename T>
	class MonoBase
	{
	public:
		typedef class MonoBypass bypassType;

		static void process( sample_t * * _buf, const f_cnt_t _frames )
		{
			for( f_cnt_t f = 0; f < _frames; ++f )
			{
				_buf[f][0] = T::nextSample( _buf[f][0] );
			}
		}
	} ;

	template<typename T>
	class StereoBase
	{
	public:
		typedef class StereoBypass bypassType;

		static void process( sample_t * * _buf, const f_cnt_t _frames )
		{
			for( f_cnt_t f = 0; f < _frames; ++f )
			{
				T::nextSample( _buf[f][0], _buf[f][1] );
			}
		}
	} ;

	template<class FXL, class FXR = FXL>
	class MonoToStereoAdaptor : public StereoBase<MonoToStereoAdaptor<FXL, FXR> >
	{
	public:
		MonoToStereoAdaptor( const FXL& monoFX ) :
			m_leftFX( monoFX ),
			m_rightFX( monoFX )
		{
		}

		MonoToStereoAdaptor( const FXL& leftFX, const FXR& rightFX ) :
			m_leftFX( leftFX ),
			m_rightFX( rightFX )
		{
		}

		void nextSample( sample_t& inLeft, sample_t& inRight )
		{
			inLeft = m_leftFX.nextSample( inLeft );
			inRight = m_rightFX.nextSample( inRight );
		}

		FXL& leftFX()
		{
			return( m_leftFX );
		}

		FXR& rightFX()
		{
			return( m_rightFX );
		}

	private:
		FXL m_leftFX;
		FXR m_rightFX;
	} ;

	template<class FX>
	class StereoToMonoAdaptor : public MonoBase<StereoToMonoAdaptor<FX> >
	{
	public:
		StereoToMonoAdaptor( const FX& fx ) :
			m_FX( fx )
		{
		}

		sample_t nextSample( sample_t in )
		{
			sample_t s[2] = { in, in };
			m_FX.nextSample( s[0], s[1] );

			return ( s[0] + s[1] ) / 2.0f;
		}

	private:
		FX m_FX;

	} ;

	class MonoBypass : public MonoBase<MonoBypass>
	{
	public:
		sample_t nextSample( sample_t in )
		{
			return in;
		}
	} ;

	class StereoBypass : public StereoBase<StereoBypass>
	{
	public:
		void nextSample( sample_t&, sample_t& )
		{
		}
	} ;

	/* convenient class to build up static FX chains, for example

	using namespace DspEffectLib;
	chain<MonoToStereoAdaptor<bassBoost<> >,
		chain<StereoEnhancer<>,
			MonoToStereoAdaptor<FoldbackDistortion<> > > >
				fxchain( bassBoost<>( 60.0, 1.0, 4.0f ),
		chain<StereoEnhancer<>,
			MonoToStereoAdaptor<FoldbackDistortion<> > >(
				StereoEnhancer<>( 1.0 ),
					FoldbackDistortion<>( 1.0f, 1.0f ) ) );

	// now you can do simple calls such as which will process a bass-boost-,
	// stereo enhancer- and foldback distortion effect on your buffer
        fx_chain.process( (sample_t * *) buf, frames );
*/

	template<class FX0, class FX1 = typename FX0::bypassType>
	class Chain : public FX0::bypassType
	{
	public:
		typedef typename FX0::sample_t sample_t;
		Chain( const FX0& fx0, const FX1& fx1 = FX1() ) :
			m_FX0( fx0 ),
			m_FX1( fx1 )
		{
		}

		void process( sample_t** buf, const f_cnt_t frames )
		{
			m_FX0.process( buf, frames );
			m_FX1.process( buf, frames );
		}

	private:
		FX0 m_FX0;
		FX1 m_FX1;

	} ;

	template<typename sample_t>
	inline sample_t saturate( sample_t x )
	{
		return qMin<sample_t>( qMax<sample_t>( -1.0f, x ), 1.0f );
	}

	class FastBassBoost : public MonoBase<FastBassBoost>
	{
	public:
		FastBassBoost( const sample_t _frequency,
				const sample_t _gain,
				const sample_t _ratio,
				const FastBassBoost & _orig = FastBassBoost() ) :
			m_frequency( qMax<sample_t>( _frequency, 10.0 ) ),
			m_gain1( 1.0 / ( m_frequency + 1.0 ) ),
			m_gain2( _gain ),
			m_ratio( _ratio ),
			m_cap( _orig.m_cap )
		{
		}

		inline sample_t nextSample( sample_t _in )
		{
			// TODO: somehow remove these horrible aliases...
			m_cap = ( _in + m_cap*m_frequency ) * m_gain1;
			return( ( _in + m_cap*m_ratio ) * m_gain2 );
		}

		void setFrequency( const sample_t _frequency )
		{
			m_frequency = _frequency;
			m_gain1 = 1.0 / ( m_frequency + 1.0 );
		}

		void setGain( const sample_t _gain )
		{
			m_gain2 = _gain;
		}

		void setRatio( const sample_t _ratio )
		{
			m_ratio = _ratio;
		}

	private:
		FastBassBoost() :
			m_cap( 0.0 )
		{
		}

		sample_t m_frequency;
		sample_t m_gain1;
		sample_t m_gain2;
		sample_t m_ratio;
		sample_t m_cap;
	} ;

	template<class T>
	class DistortionBase : public MonoBase<T>
	{
	public:
		DistortionBase( float threshold, float gain ) :
			m_threshold( threshold ),
			m_gain( gain )
		{
		}

		void setThreshold( float threshold )
		{
			m_threshold = threshold;
		}

		void setGain( float gain )
		{
			m_gain = gain;
		}

	protected:
		float m_threshold;
		float m_gain;
	};

	class FoldbackDistortion : public DistortionBase<FoldbackDistortion>
	{
	public:
		using DistortionBase<FoldbackDistortion>::DistortionBase;

		sample_t nextSample( sample_t in )
		{
			if( in >= m_threshold || in < -m_threshold )
			{
				return ( fabsf( fabsf( fmodf( in - m_threshold, m_threshold*4 ) ) - m_threshold*2 ) - m_threshold ) * m_gain;
			}
			return in * m_gain;
		}
	} ;

	class Distortion : public DistortionBase<Distortion>
	{
	public:
		using DistortionBase<Distortion>::DistortionBase;

		sample_t nextSample( sample_t in )
		{
			return m_gain * ( in * ( fabsf( in )+m_threshold ) / ( in*in +( m_threshold-1 )* fabsf( in ) + 1 ) );
		}
	} ;

	class StereoEnhancer : public StereoBase<StereoEnhancer>
	{
	public:
		StereoEnhancer( float wideCoeff ) :
			m_wideCoeff( wideCoeff )
		{
		}

		void setWideCoeff( float wideCoeff )
		{
			m_wideCoeff = wideCoeff;
		}

		float wideCoeff()
		{
			return m_wideCoeff;
		}

		void nextSample( sample_t& inLeft, sample_t& inRight )
		{
			const float toRad = F_PI / 180;
			const sample_t tmp = inLeft;
			inLeft += inRight * sinf( m_wideCoeff * ( .5 * toRad ) );
			inRight -= tmp * sinf( m_wideCoeff * ( .5 * toRad ) );
		}

	private:
		float m_wideCoeff;

	} ;

} ;

#endif


code:
/*
 * DummyEffect.h - effect used as fallback if an effect couldn't be loaded
 *
 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef DUMMY_EFFECT_H
#define DUMMY_EFFECT_H

#include "Effect.h"
#include "EffectControls.h"
#include "EffectControlDialog.h"

class DummyEffectControlDialog : public EffectControlDialog
{
public:
	DummyEffectControlDialog( EffectControls * _controls ) :
		EffectControlDialog( _controls )
	{
	}

} ;

class DummyEffectControls : public EffectControls
{
public:
	DummyEffectControls( Effect * _eff ) :
		EffectControls( _eff )
	{
	}

	virtual ~DummyEffectControls()
	{
	}

	int controlCount() override
	{
		return 0;
	}

	void saveSettings( QDomDocument &, QDomElement & ) override
	{
	}

	void loadSettings( const QDomElement & ) override
	{
	}

	QString nodeName() const override
	{
		return "DummyControls";
	}

	EffectControlDialog * createView() override
	{
		return new DummyEffectControlDialog( this );
	}
} ;

class DummyEffect : public Effect
{
	Q_OBJECT
public:
	DummyEffect( Model * _parent, const QDomElement& originalPluginData ) :
		Effect( NULL, _parent, NULL ),
		m_controls( this ),
		m_originalPluginData( originalPluginData )
	{
		setName();
	}

	virtual ~DummyEffect()
	{
	}

	EffectControls * controls() override
	{
		return &m_controls;
	}

	bool processAudioBuffer( sampleFrame *, const fpp_t ) override
	{
		return false;
	}

	const QDomElement& originalPluginData() const
	{
		return m_originalPluginData;
	}

private:
	DummyEffectControls m_controls;
	const QDomElement m_originalPluginData;

	// Parse the display name from the dom
	virtual void setName()
	{
		QDomNodeList keys = originalPluginData().elementsByTagName( "key" );
		for( int i = 0; !keys.item( i ).isNull(); ++i )
		{
			QDomNodeList attributes = keys.item( i ).toElement().elementsByTagName( "attribute" );
			for( int j = 0; !attributes.item( j ).isNull(); ++j )
			{
				QDomElement attribute = attributes.item( j ).toElement();
				if( attribute.hasAttribute( "value" ) )
				{
					QString name = tr("NOT FOUND") + " (" + attribute.attribute( "value" ) + ")";
					setDisplayName(name);
					return;
				}

			}

		}
	}
} ;

#endif

repo_name: CYBERDEViL/LMMS

license: mit


code:
/*
 * DummyInstrument.h - instrument used as fallback if an instrument couldn't
 *                     be loaded
 *
 * Copyright (c) 2005-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef DUMMY_INSTRUMENT_H
#define DUMMY_INSTRUMENT_H

#include "Instrument.h"
#include "InstrumentView.h"
#include "Engine.h"

#include <string.h>

#include "Mixer.h"

class DummyInstrument : public Instrument
{
public:
	DummyInstrument( InstrumentTrack * _instrument_track ) :
		Instrument( _instrument_track, NULL )
	{
	}

	virtual ~DummyInstrument()
	{
	}

	void playNote( NotePlayHandle *, sampleFrame * buffer ) override
	{
		memset( buffer, 0, sizeof( sampleFrame ) *
			Engine::mixer()->framesPerPeriod() );
	}

	void saveSettings( QDomDocument &, QDomElement & ) override
	{
	}

	void loadSettings( const QDomElement & ) override
	{
	}

	QString nodeName() const override
	{
		return "dummyinstrument";
	}

	PluginView * instantiateView( QWidget * _parent ) override
	{
		return new InstrumentViewFixedSize( this, _parent );
	}
} ;

#endif


code:
/*
 * DummyPlugin.h - empty plugin which is used as fallback if a plugin couldn't
 *                 be found
 *
 * Copyright (c) 2005-2009 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef DUMMY_PLUGIN_H
#define DUMMY_PLUGIN_H

#include "Plugin.h"
#include "PluginView.h"

class DummyPlugin : public Plugin
{
public:
	DummyPlugin() :
		Plugin( NULL, NULL )
	{
	}

	virtual ~DummyPlugin()
	{
	}

	void saveSettings( QDomDocument &, QDomElement & ) override
	{
	}

	void loadSettings( const QDomElement & ) override
	{
	}

	QString nodeName() const override
	{
		return "DummyPlugin";
	}

protected:
	PluginView * instantiateView( QWidget * _parent ) override
	{
		return new PluginView( this, _parent );
	}

} ;

#endif


code:
/*
 * Editor.h - declaration of Editor class
 *
 * Copyright (c) 2014 Lukas W <lukaswhl/at/gmail.com>
 *
 * 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.
 *
 */

#ifndef EDITOR_COMMON_H
#define EDITOR_COMMON_H

#include <QMainWindow>
#include <QToolBar>

static const int Quantizations[] = {
	1, 2, 4, 8, 16, 32, 64,
	3, 6, 12, 24, 48, 96, 192
};

class QAction;

class DropToolBar;

/// \brief Superclass for editors with a toolbar.
///
/// Those editors include the Song Editor, the Automation Editor, B&B Editor,
/// and the Piano Roll.
class Editor : public QMainWindow
{
	Q_OBJECT
public:
	void setPauseIcon(bool displayPauseIcon=true);
	QAction *playAction() const;
protected:
	DropToolBar * addDropToolBarToTop(QString const & windowTitle);
	DropToolBar * addDropToolBar(Qt::ToolBarArea whereToAdd, QString const & windowTitle);
	DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle);

	void closeEvent( QCloseEvent * _ce ) override;
protected slots:
	virtual void play() {}
	virtual void record() {}
	virtual void recordAccompany() {}
	virtual void toggleStepRecording() {}
	virtual void stop() {}

private slots:
	/// Called by pressing the space key. Plays or stops.
	void togglePlayStop();

	/// Called by pressing shift+space. Toggles pause state.
	void togglePause();

	void toggleMaximize();

signals:

protected:
	/// \brief	Constructor.
	///
	/// \param	record	If set true, the editor's toolbar will contain record
	///					buttons in addition to the play and stop buttons.
	Editor(bool record = false, bool record_step = false);
	virtual ~Editor();

	DropToolBar* m_toolBar;

	QAction* m_playAction;
	QAction* m_recordAction;
	QAction* m_recordAccompanyAction;
	QAction* m_toggleStepRecordingAction;
	QAction* m_stopAction;
};

/// Small helper class: A QToolBar that accepts and exposes drop events as signals
class DropToolBar : public QToolBar
{
	Q_OBJECT
public:
	DropToolBar(QWidget* parent=0);

signals:
	void dragEntered(QDragEnterEvent* event);
	void dropped(QDropEvent* event);

protected:
	void dragEnterEvent(QDragEnterEvent* event) override;
	void dropEvent(QDropEvent* event) override;
};

#endif


code:
/*
 * Effect.h - base class for effects
 *
 * Copyright (c) 2006-2007 Danny McRae <khjklujn/at/users.sourceforge.net>
 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_H
#define EFFECT_H

#include "Plugin.h"
#include "Engine.h"
#include "Mixer.h"
#include "AutomatableModel.h"
#include "TempoSyncKnobModel.h"
#include "MemoryManager.h"

class EffectChain;
class EffectControls;

class LMMS_EXPORT Effect : public Plugin
{
	MM_OPERATORS
	Q_OBJECT
public:
	Effect( const Plugin::Descriptor * _desc,
			Model * _parent,
			const Descriptor::SubPluginFeatures::Key * _key );
	virtual ~Effect();

	void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
	void loadSettings( const QDomElement & _this ) override;

	inline QString nodeName() const override
	{
		return "effect";
	}

	virtual bool processAudioBuffer( sampleFrame * _buf,
						const fpp_t _frames ) = 0;

	inline ch_cnt_t processorCount() const
	{
		return m_processors;
	}

	inline void setProcessorCount( ch_cnt_t _processors )
	{
		m_processors = _processors;
	}

	inline bool isOkay() const
	{
		return m_okay;
	}

	inline void setOkay( bool _state )
	{
		m_okay = _state;
	}

	inline bool isRunning() const
	{
		return m_running;
	}

	inline void startRunning()
	{
		m_bufferCount = 0;
		m_running = true;
	}

	inline void stopRunning()
	{
		m_running = false;
	}

	inline bool isEnabled() const
	{
		return m_enabledModel.value();
	}

	inline f_cnt_t timeout() const
	{
		const float samples = Engine::mixer()->processingSampleRate() * m_autoQuitModel.value() / 1000.0f;
		return 1 + ( static_cast<int>( samples ) / Engine::mixer()->framesPerPeriod() );
	}

	inline float wetLevel() const
	{
		return m_wetDryModel.value();
	}

	inline float dryLevel() const
	{
		return 1.0f - m_wetDryModel.value();
	}

	inline float gate() const
	{
		const float level = m_gateModel.value();
		return level*level * m_processors;
	}

	inline f_cnt_t bufferCount() const
	{
		return m_bufferCount;
	}

	inline void resetBufferCount()
	{
		m_bufferCount = 0;
	}

	inline void incrementBufferCount()
	{
		++m_bufferCount;
	}

	inline bool dontRun() const
	{
		return m_noRun;
	}

	inline void setDontRun( bool _state )
	{
		m_noRun = _state;
	}

	EffectChain * effectChain() const
	{
		return m_parent;
	}

	virtual EffectControls * controls() = 0;

	static Effect * instantiate( const QString & _plugin_name,
				Model * _parent,
				Descriptor::SubPluginFeatures::Key * _key );

protected:
	/**
		Effects should call this at the end of audio processing

		If the setting "Keep effects running even without input" is disabled,
		after "decay" ms of a signal below "gate", the effect is turned off
		and won't be processed again until it receives new audio input
	*/
	void checkGate( double _out_sum );

	PluginView * instantiateView( QWidget * ) override;

	// some effects might not be capable of higher sample-rates so they can
	// sample it down before processing and back after processing
	inline void sampleDown( const sampleFrame * _src_buf,
							sampleFrame * _dst_buf,
							sample_rate_t _dst_sr )
	{
		resample( 0, _src_buf,
				Engine::mixer()->processingSampleRate(),
					_dst_buf, _dst_sr,
					Engine::mixer()->framesPerPeriod() );
	}

	inline void sampleBack( const sampleFrame * _src_buf,
							sampleFrame * _dst_buf,
							sample_rate_t _src_sr )
	{
		resample( 1, _src_buf, _src_sr, _dst_buf,
				Engine::mixer()->processingSampleRate(),
			Engine::mixer()->framesPerPeriod() * _src_sr /
				Engine::mixer()->processingSampleRate() );
	}
	void reinitSRC();

private:
	EffectChain * m_parent;
	void resample( int _i, const sampleFrame * _src_buf,
					sample_rate_t _src_sr,
					sampleFrame * _dst_buf, sample_rate_t _dst_sr,
					const f_cnt_t _frames );

	ch_cnt_t m_processors;

	bool m_okay;
	bool m_noRun;
	bool m_running;
	f_cnt_t m_bufferCount;

	BoolModel m_enabledModel;
	FloatModel m_wetDryModel;
	FloatModel m_gateModel;
	TempoSyncKnobModel m_autoQuitModel;

	bool m_autoQuitDisabled;

	SRC_DATA m_srcData[2];
	SRC_STATE * m_srcState[2];

	friend class EffectView;
	friend class EffectChain;

} ;

typedef Effect::Descriptor::SubPluginFeatures::Key EffectKey;
typedef Effect::Descriptor::SubPluginFeatures::KeyList EffectKeyList;

#endif


code:
/*
 * EffectChain.h - class for processing and effects chain
 *
 * Copyright (c) 2006-2008 Danny McRae <khjklujn/at/users.sourceforge.net>
 * Copyright (c) 2008-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_CHAIN_H
#define EFFECT_CHAIN_H

#include "Model.h"
#include "SerializingObject.h"
#include "AutomatableModel.h"

class Effect;

class LMMS_EXPORT EffectChain : public Model, public SerializingObject
{
	Q_OBJECT
public:
	EffectChain( Model * _parent );
	virtual ~EffectChain();

	void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
	void loadSettings( const QDomElement & _this ) override;

	inline QString nodeName() const override
	{
		return "fxchain";
	}

	void appendEffect( Effect * _effect );
	void removeEffect( Effect * _effect );
	void moveDown( Effect * _effect );
	void moveUp( Effect * _effect );
	bool processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, bool hasInputNoise );
	void startRunning();

	void clear();

private:
	typedef QVector<Effect *> EffectList;
	EffectList m_effects;

	BoolModel m_enabledModel;

	friend class EffectRackView;

signals:
	void aboutToClear();

} ;

#endif


code:
/*
 * EffectControlDialog.h - base-class for effect-dialogs for displaying and
 *                         editing control port values
 *
 * Copyright (c) 2006-2009 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_CONTROL_DIALOG_H
#define EFFECT_CONTROL_DIALOG_H

#include <QWidget>

#include "ModelView.h"

class EffectControls;

class LMMS_EXPORT EffectControlDialog : public QWidget, public ModelView
{
	Q_OBJECT
public:
	EffectControlDialog( EffectControls * _controls );
	virtual ~EffectControlDialog();

	virtual bool isResizable() const {return false;}

signals:
	void closed();

protected:
	void closeEvent( QCloseEvent * _ce ) override;

	EffectControls * m_effectControls;

} ;

#endif


code:
/*
 * EffectControls.h - model for effect-controls
 *
 * Copyright (c) 2008-2010 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_CONTROLS_H
#define EFFECT_CONTROLS_H

#include "Model.h"
#include "JournallingObject.h"
#include "Effect.h"

class EffectControlDialog;

class EffectControls : public JournallingObject, public Model
{
public:
	EffectControls( Effect * _eff ) :
		JournallingObject(),
		Model( _eff ),
		m_effect( _eff ),
		m_viewVisible( false )
	{
	}

	virtual ~EffectControls()
	{
	}

	virtual int controlCount() = 0;
	virtual EffectControlDialog * createView() = 0;

	void setViewVisible( bool _visible )
	{
		m_viewVisible = _visible;
	}

	bool isViewVisible() const
	{
		return m_viewVisible;
	}

	Effect * effect()
	{
		return m_effect;
	}

private:
	Effect * m_effect;
	bool m_viewVisible;

} ;

#endif


code:
/*
 * EffectRackView.h - view for effectChain-model
 *
 * Copyright (c) 2006-2007 Danny McRae <khjklujn@netscape.net>
 * Copyright (c) 2008-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_RACK_VIEW_H
#define EFFECT_RACK_VIEW_H

#include <QWidget>

#include "EffectChain.h"
#include "ModelView.h"
#include "lmms_basics.h"

class QScrollArea;
class QVBoxLayout;

class EffectView;
class GroupBox;

class EffectRackView : public QWidget, public ModelView
{
	Q_OBJECT
public:
	EffectRackView( EffectChain* model, QWidget* parent = NULL );
	virtual ~EffectRackView();

	static constexpr int DEFAULT_WIDTH = 245;

public slots:
	void clearViews();
	void moveUp( EffectView* view );
	void moveDown( EffectView* view );
	void deletePlugin( EffectView* view );

private slots:
	virtual void update();
	void addEffect();

private:
	void modelChanged() override;

	inline EffectChain* fxChain()
	{
		return castModel<EffectChain>();
	}

	inline const EffectChain* fxChain() const
	{
		return castModel<EffectChain>();
	}

	QVector<EffectView *> m_effectViews;

	GroupBox* m_effectsGroupBox;
	QScrollArea* m_scrollArea;

	int m_lastY;

} ;

#endif


code:
/*
 * EffectSelectDialog.h - dialog to choose effect plugin
 *
 * Copyright (c) 2006-2009 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_SELECT_DIALOG_H
#define EFFECT_SELECT_DIALOG_H

#include <QDialog>
#include <QSortFilterProxyModel>
#include <QStandardItemModel>

#include "EffectChain.h"
#include "Effect.h"

namespace Ui { class EffectSelectDialog; }

class EffectSelectDialog : public QDialog
{
	Q_OBJECT
public:
	EffectSelectDialog( QWidget * _parent );
	virtual ~EffectSelectDialog();

	Effect * instantiateSelectedPlugin( EffectChain * _parent );

protected slots:
	void acceptSelection();
	void rowChanged( const QModelIndex &, const QModelIndex & );
	void sortAgain();
	void updateSelection();

private:
	Ui::EffectSelectDialog * ui;

	EffectKeyList m_effectKeys;
	EffectKey m_currentSelection;

	QStandardItemModel m_sourceModel;
	QSortFilterProxyModel m_model;
	QWidget * m_descriptionWidget;

} ;

#endif


code:
/*
 * EffectView.h - view-component for an effect
 *
 * Copyright (c) 2006-2007 Danny McRae <khjklujn/at/users.sourceforge.net>
 * Copyright (c) 2007-2010 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EFFECT_VIEW_H
#define EFFECT_VIEW_H

#include "AutomatableModel.h"
#include "PluginView.h"
#include "Effect.h"

class QGroupBox;
class QLabel;
class QPushButton;
class QMdiSubWindow;

class EffectControlDialog;
class Knob;
class LedCheckBox;
class TempoSyncKnob;

class EffectView : public PluginView
{
	Q_OBJECT
public:
	EffectView( Effect * _model, QWidget * _parent );
	virtual ~EffectView();

	inline Effect * effect()
	{
		return castModel<Effect>();
	}
	inline const Effect * effect() const
	{
		return castModel<Effect>();
	}

	static constexpr int DEFAULT_WIDTH = 215;

public slots:
	void editControls();
	void moveUp();
	void moveDown();
	void deletePlugin();
	void closeEffects();

signals:
	void moveUp( EffectView * _plugin );
	void moveDown( EffectView * _plugin );
	void deletePlugin( EffectView * _plugin );

protected:
	void contextMenuEvent( QContextMenuEvent * _me ) override;
	void paintEvent( QPaintEvent * _pe ) override;
	void modelChanged() override;

private:
	QPixmap m_bg;
	LedCheckBox * m_bypass;
	Knob * m_wetDry;
	TempoSyncKnob * m_autoQuit;
	Knob * m_gate;
	QMdiSubWindow * m_subWindow;
	EffectControlDialog * m_controlView;

} ;

#endif


code:
/*
 * Engine.h - engine-system of LMMS
 *
 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef ENGINE_H
#define ENGINE_H

#include <QtCore/QString>
#include <QtCore/QObject>

#include "lmmsconfig.h"
#include "lmms_export.h"
#include "lmms_basics.h"

class BBTrackContainer;
class FxMixer;
class ProjectJournal;
class Mixer;
class Song;
class Ladspa2LMMS;

// Note: This class is called 'LmmsCore' instead of 'Engine' because of naming
// conflicts caused by ZynAddSubFX. See https://github.com/LMMS/lmms/issues/2269
// and https://github.com/LMMS/lmms/pull/2118 for more details.
//
// The workaround was to rename Lmms' Engine so that it has a different symbol
// name in the object files, but typedef it back to 'Engine' and keep it inside
// of Engine.h so that the rest of the codebase can be oblivious to this issue
// (and it could be fixed without changing every single file).

class LmmsCore;
typedef LmmsCore Engine;

class LMMS_EXPORT LmmsCore : public QObject
{
	Q_OBJECT
public:
	static void init( bool renderOnly );
	static void destroy();

	// core
	static Mixer *mixer()
	{
		return s_mixer;
	}

	static FxMixer * fxMixer()
	{
		return s_fxMixer;
	}

	static Song * getSong()
	{
		return s_song;
	}

	static BBTrackContainer * getBBTrackContainer()
	{
		return s_bbTrackContainer;
	}

	static ProjectJournal * projectJournal()
	{
		return s_projectJournal;
	}

	static bool ignorePluginBlacklist();

#ifdef LMMS_HAVE_LV2
	static class Lv2Manager * getLv2Manager()
	{
		return s_lv2Manager;
	}
#endif

	static Ladspa2LMMS * getLADSPAManager()
	{
		return s_ladspaManager;
	}

	static float framesPerTick()
	{
		return s_framesPerTick;
	}

	static float framesPerTick(sample_rate_t sample_rate);

	static void updateFramesPerTick();

	static inline LmmsCore * inst()
	{
		if( s_instanceOfMe == NULL )
		{
			s_instanceOfMe = new LmmsCore();
		}
		return s_instanceOfMe;
	}

	static void setDndPluginKey(void* newKey);
	static void* pickDndPluginKey();

signals:
	void initProgress(const QString &msg);

private:
	// small helper function which sets the pointer to NULL before actually deleting
	// the object it refers to
	template<class T>
	static inline void deleteHelper( T * * ptr )
	{
		T * tmp = *ptr;
		*ptr = NULL;
		delete tmp;
	}

	static float s_framesPerTick;

	// core
	static Mixer *s_mixer;
	static FxMixer * s_fxMixer;
	static Song * s_song;
	static BBTrackContainer * s_bbTrackContainer;
	static ProjectJournal * s_projectJournal;

#ifdef LMMS_HAVE_LV2
	static class Lv2Manager* s_lv2Manager;
#endif
	static Ladspa2LMMS * s_ladspaManager;
	static void* s_dndPluginKey;

	// even though most methods are static, an instance is needed for Qt slots/signals
	static LmmsCore * s_instanceOfMe;

	friend class GuiApplication;
};

#endif


code:
/*
 * EnvelopeAndLfoParameters.h - class EnvelopeAndLfoParameters
 *
 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef ENVELOPE_AND_LFO_PARAMETERS_H
#define ENVELOPE_AND_LFO_PARAMETERS_H

#include <QtCore/QVector>

#include "JournallingObject.h"
#include "AutomatableModel.h"
#include "SampleBuffer.h"
#include "TempoSyncKnobModel.h"
#include "lmms_basics.h"

class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObject
{
	Q_OBJECT
public:
	class LfoInstances
	{
	public:
		LfoInstances()
		{
		}

		~LfoInstances()
		{
		}

		inline bool isEmpty() const
		{
			return m_lfos.isEmpty();
		}

		void trigger();
		void reset();

		void add( EnvelopeAndLfoParameters * lfo );
		void remove( EnvelopeAndLfoParameters * lfo );

	private:
		QMutex m_lfoListMutex;
		typedef QList<EnvelopeAndLfoParameters *> LfoList;
		LfoList m_lfos;

	} ;

	EnvelopeAndLfoParameters( float _value_for_zero_amount,
							Model * _parent );
	virtual ~EnvelopeAndLfoParameters();

	static inline float expKnobVal( float _val )
	{
		return ( ( _val < 0 ) ? -_val : _val ) * _val;
	}

	static LfoInstances * instances()
	{
		return s_lfoInstances;
	}

	void fillLevel( float * _buf, f_cnt_t _frame,
				const f_cnt_t _release_begin,
				const fpp_t _frames );

	inline bool isUsed() const
	{
		return m_used;
	}

	void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
	void loadSettings( const QDomElement & _this ) override;
	QString nodeName() const override
	{
		return "el";
	}

	inline f_cnt_t PAHD_Frames() const
	{
		return m_pahdFrames;
	}

	inline f_cnt_t releaseFrames() const
	{
		return m_rFrames;
	}

public slots:
	void updateSampleVars();

protected:
	void fillLfoLevel( float * _buf, f_cnt_t _frame, const fpp_t _frames );

private:
	static LfoInstances * s_lfoInstances;
	bool m_used;

	QMutex m_paramMutex;

	FloatModel m_predelayModel;
	FloatModel m_attackModel;
	FloatModel m_holdModel;
	FloatModel m_decayModel;
	FloatModel m_sustainModel;
	FloatModel m_releaseModel;
	FloatModel m_amountModel;

	float  m_sustainLevel;
	float  m_amount;
	float  m_valueForZeroAmount;
	float  m_amountAdd;
	f_cnt_t m_pahdFrames;
	f_cnt_t m_rFrames;
	sample_t * m_pahdEnv;
	sample_t * m_rEnv;
	f_cnt_t m_pahdBufSize;
	f_cnt_t m_rBufSize;

	FloatModel m_lfoPredelayModel;
	FloatModel m_lfoAttackModel;
	TempoSyncKnobModel m_lfoSpeedModel;
	FloatModel m_lfoAmountModel;
	IntModel m_lfoWaveModel;

	BoolModel m_x100Model;
	BoolModel m_controlEnvAmountModel;

	f_cnt_t m_lfoPredelayFrames;
	f_cnt_t m_lfoAttackFrames;
	f_cnt_t m_lfoOscillationFrames;
	f_cnt_t m_lfoFrame;
	float m_lfoAmount;
	bool m_lfoAmountIsZero;
	sample_t * m_lfoShapeData;
	sample_t m_random;
	bool m_bad_lfoShapeData;
	SampleBuffer m_userWave;

	enum LfoShapes
	{
		SineWave,
		TriangleWave,
		SawWave,
		SquareWave,
		UserDefinedWave,
		RandomWave,
		NumLfoShapes
	} ;

	sample_t lfoShapeSample( fpp_t _frame_offset );
	void updateLfoShapeData();

	friend class EnvelopeAndLfoView;

} ;

#endif


code:
/*
 * EnvelopeAndLfoView.h - declaration of class EnvelopeAndLfoView which
 *                        is used by envelope/lfo/filter-tab of instrument track
 *
 * Copyright (c) 2004-2009 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef ENVELOPE_AND_LFO_VIEW_H
#define ENVELOPE_AND_LFO_VIEW_H

#include <QWidget>

#include "ModelView.h"

class QPaintEvent;
class QPixmap;

class EnvelopeAndLfoParameters;

class automatableButtonGroup;
class Knob;
class LedCheckBox;
class PixmapButton;
class TempoSyncKnob;

class EnvelopeAndLfoView : public QWidget, public ModelView
{
	Q_OBJECT
public:
	EnvelopeAndLfoView( QWidget * _parent );
	virtual ~EnvelopeAndLfoView();

protected:
	void modelChanged() override;

	void dragEnterEvent( QDragEnterEvent * _dee ) override;
	void dropEvent( QDropEvent * _de ) override;
	void mousePressEvent( QMouseEvent * _me ) override;
	void paintEvent( QPaintEvent * _pe ) override;

protected slots:
	void lfoUserWaveChanged();

private:
	static QPixmap * s_envGraph;
	static QPixmap * s_lfoGraph;

	EnvelopeAndLfoParameters * m_params;

	// envelope stuff
	Knob * m_predelayKnob;
	Knob * m_attackKnob;
	Knob * m_holdKnob;
	Knob * m_decayKnob;
	Knob * m_sustainKnob;
	Knob * m_releaseKnob;
	Knob * m_amountKnob;

	// LFO stuff
	Knob * m_lfoPredelayKnob;
	Knob * m_lfoAttackKnob;
	TempoSyncKnob * m_lfoSpeedKnob;
	Knob * m_lfoAmountKnob;
	PixmapButton * m_userLfoBtn;
	automatableButtonGroup * m_lfoWaveBtnGrp;

	LedCheckBox * m_x100Cb;
	LedCheckBox * m_controlEnvAmountCb;

	float m_randomGraph;
} ;

#endif


code:
/*
 * ExportFilter.h - declaration of class ExportFilter, the base-class for all
 *                  file export filters
 *
 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EXPORT_FILTER_H
#define EXPORT_FILTER_H

#include <QtCore/QFile>

#include "TrackContainer.h"
#include "Plugin.h"

class LMMS_EXPORT ExportFilter : public Plugin
{
public:
	ExportFilter( const Descriptor * _descriptor ) : Plugin( _descriptor, NULL ) {}
	virtual ~ExportFilter() {}

	virtual bool tryExport(const TrackContainer::TrackList &tracks,
				const TrackContainer::TrackList &tracksBB,
				int tempo, int masterPitch, const QString &filename ) = 0;
protected:

	void saveSettings( QDomDocument &, QDomElement & ) override
	{
	}

	void loadSettings( const QDomElement & ) override
	{
	}

	QString nodeName() const override
	{
		return "import_filter";
	}

private:

} ;

#endif


code:
/*
 * ExportProjectDialog.h - declaration of class ExportProjectDialog which is
 *                           responsible for exporting project
 *
 * Copyright (c) 2004-2012 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef EXPORT_PROJECT_DIALOG_H
#define EXPORT_PROJECT_DIALOG_H

#include <QDialog>
#include <memory>
#include "ui_export_project.h"

#include "ProjectRenderer.h"
#include "RenderManager.h"

class ExportProjectDialog : public QDialog, public Ui::ExportProjectDialog
{
	Q_OBJECT
public:
	ExportProjectDialog( const QString & _file_name, QWidget * _parent, bool multi_export );

protected:
	void reject( void ) override;
	void closeEvent( QCloseEvent * _ce ) override;

private slots:
	void startBtnClicked( void );
	void updateTitleBar( int );
	void accept() override;
	void startExport();

	void onFileFormatChanged(int);

private:
	QString m_fileName;
	QString m_dirName;
	QString m_fileExtension;
	bool m_multiExport;

	ProjectRenderer::ExportFileFormats m_ft;
	std::unique_ptr<RenderManager> m_renderManager;
} ;

#endif


code:
/*
 * FadeButton.h - declaration of class fadeButton
 *
 * Copyright (c) 2005-2009 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef FADE_BUTTON_H
#define FADE_BUTTON_H

#include <QAbstractButton>
#include <QColor>
#include <QElapsedTimer>

class FadeButton : public QAbstractButton
{
	Q_OBJECT
public:
	FadeButton( const QColor & _normal_color,
		const QColor & _activated_color,
		const QColor & _hold_color,
		QWidget * _parent );

	virtual ~FadeButton();
	void setActiveColor( const QColor & activated_color );

public slots:
	void activate();
	void activateOnce();
	void noteEnd();

protected:
	void paintEvent( QPaintEvent * _pe ) override;

private:
	QElapsedTimer m_stateTimer;
	QElapsedTimer m_releaseTimer;

	// the default color of the widget
	QColor m_normalColor;
	// the color on note play
	QColor m_activatedColor;
	// the color after the "play" fade is done but a note is still playing
	QColor m_holdColor;
	int activeNotes;

	QColor fadeToColor(QColor, QColor, QElapsedTimer, float);

} ;

#endif


code:
/*
 * Fader.h - fader-widget used in FX-mixer - partly taken from Hydrogen
 *
 * Copyright (c) 2008-2012 Tobias Doerffel <tobydox/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.
 *
 */

/*
 * Hydrogen
 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
 *
 * http://www.hydrogen-music.org
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef FADER_H
#define FADER_H

#include <QElapsedTimer>
#include <QPixmap>
#include <QWidget>

#include "AutomatableModelView.h"

class TextFloat;

class LMMS_EXPORT Fader : public QWidget, public FloatModelView
{
	Q_OBJECT
public:
	Q_PROPERTY( QColor peakGreen READ peakGreen WRITE setPeakGreen )
	Q_PROPERTY( QColor peakRed READ peakRed WRITE setPeakRed )
	Q_PROPERTY( QColor peakYellow READ peakYellow WRITE setPeakYellow )
	Q_PROPERTY( bool levelsDisplayedInDBFS READ getLevelsDisplayedInDBFS WRITE setLevelsDisplayedInDBFS )

	Fader( FloatModel * _model, const QString & _name, QWidget * _parent );
	Fader( FloatModel * _model, const QString & _name, QWidget * _parent, QPixmap * back, QPixmap * leds, QPixmap * knob );
	virtual ~Fader() = default;

	void init(FloatModel * model, QString const & name);

	void setPeak_L( float fPeak );
	float getPeak_L() {	return m_fPeakValue_L;	}

	void setPeak_R( float fPeak );
	float getPeak_R() {	return m_fPeakValue_R;	}

	inline float getMinPeak() const { return m_fMinPeak; }
	inline void setMinPeak(float minPeak) { m_fMinPeak = minPeak; }

	inline float getMaxPeak() const { return m_fMaxPeak; }
	inline void setMaxPeak(float maxPeak) { m_fMaxPeak = maxPeak; }

	QColor const & peakGreen() const;
	void setPeakGreen( const QColor & c );

	QColor const & peakRed() const;
	void setPeakRed( const QColor & c );

	QColor const & peakYellow() const;
	void setPeakYellow( const QColor & c );

	inline bool getLevelsDisplayedInDBFS() const { return m_levelsDisplayedInDBFS; }
	inline void setLevelsDisplayedInDBFS(bool value = true) { m_levelsDisplayedInDBFS = value; }

	void setDisplayConversion( bool b )
	{
		m_conversionFactor = b ? 100.0 : 1.0;
	}

	inline void setHintText( const QString & _txt_before,
						const QString & _txt_after )
	{
		setDescription( _txt_before );
		setUnit( _txt_after );
	}

private:
	void contextMenuEvent( QContextMenuEvent * _me ) override;
	void mousePressEvent( QMouseEvent *ev ) override;
	void mouseDoubleClickEvent( QMouseEvent* mouseEvent ) override;
	void mouseMoveEvent( QMouseEvent *ev ) override;
	void mouseReleaseEvent( QMouseEvent * _me ) override;
	void wheelEvent( QWheelEvent *ev ) override;
	void paintEvent( QPaintEvent *ev ) override;

	inline bool clips(float const & value) const { return value >= 1.0f; }

	void paintDBFSLevels(QPaintEvent *ev, QPainter & painter);
	void paintLinearLevels(QPaintEvent *ev, QPainter & painter);

	int knobPosY() const
	{
		float fRange = model()->maxValue() - model()->minValue();
		float realVal = model()->value() - model()->minValue();

		return height() - ( ( height() - m_knob->height() ) * ( realVal / fRange ) );
	}

	void setPeak( float fPeak, float &targetPeak, float &persistentPeak, QElapsedTimer &lastPeakTimer );
	int calculateDisplayPeak( float fPeak );

	void updateTextFloat();

	// Private members
private:
	float m_fPeakValue_L;
	float m_fPeakValue_R;
	float m_persistentPeak_L;
	float m_persistentPeak_R;
	float m_fMinPeak;
	float m_fMaxPeak;

	QElapsedTimer m_lastPeakTimer_L;
	QElapsedTimer m_lastPeakTimer_R;

	static QPixmap * s_back;
	static QPixmap * s_leds;
	static QPixmap * s_knob;

	QPixmap * m_back;
	QPixmap * m_leds;
	QPixmap * m_knob;

	bool m_levelsDisplayedInDBFS;

	int m_moveStartPoint;
	float m_startValue;

	static TextFloat * s_textFloat;

	QColor m_peakGreen;
	QColor m_peakRed;
	QColor m_peakYellow;
} ;

#endif


code:
/*
 * FifoBuffer.h - FIFO fixed-size buffer
 *
 * Copyright (c) 2007 Javier Serrano Polo <jasp00/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.
 *
 */

#ifndef FIFO_BUFFER_H
#define FIFO_BUFFER_H

#include <QtCore/QSemaphore>

template<typename T>
class FifoBuffer
{
public:
	FifoBuffer(int size) :
		m_readSem(size),
		m_writeSem(size),
		m_readIndex(0),
		m_writeIndex(0),
		m_size(size)
	{
		m_buffer = new T[size];
		m_readSem.acquire(size);
	}

	~FifoBuffer()
	{
		delete[] m_buffer;
		m_readSem.release(m_size);
	}

	void write(T element)
	{
		m_writeSem.acquire();
		m_buffer[m_writeIndex++] = element;
		m_writeIndex %= m_size;
		m_readSem.release();
	}

	T read()
	{
		m_readSem.acquire();
		T element = m_buffer[m_readIndex++];
		m_readIndex %= m_size;
		m_writeSem.release();
		return element;
	}

	void waitUntilRead()
	{
		m_writeSem.acquire(m_size);
		m_writeSem.release(m_size);
	}

	bool available()
	{
		return m_readSem.available();
	}

private:
	QSemaphore m_readSem;
	QSemaphore m_writeSem;
	int m_readIndex;
	int m_writeIndex;
	int m_size;
	T * m_buffer;
} ;

#endif


code:
/*
 * FileBrowser.h - include file for FileBrowser
 *
 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef FILE_BROWSER_H
#define FILE_BROWSER_H

#include <QCheckBox>
#include <QtCore/QDir>
#include <QtCore/QMutex>
#include <QTreeWidget>

#include "SideBarWidget.h"

class QLineEdit;

class FileItem;
class InstrumentTrack;
class FileBrowserTreeWidget;
class PlayHandle;
class TrackContainer;

class FileBrowser : public SideBarWidget
{
	Q_OBJECT
public:
	/**
		Create a file browser side bar widget
		@param directories '*'-separated list of directories to search for.
			If a directory of factory files should be in the list it
			must be the last one (for the factory files delimiter to work)
		@param filter Filter as used in QDir::match
		@param recurse *to be documented*
	*/
	FileBrowser( const QString & directories, const QString & filter,
			const QString & title, const QPixmap & pm,
			QWidget * parent, bool dirs_as_items = false, bool recurse = false,
			const QString& userDir = "",
			const QString& factoryDir = "");

	virtual ~FileBrowser() = default;

private slots:
	void reloadTree( void );
	void expandItems( QTreeWidgetItem * item=nullptr, QList<QString> expandedDirs = QList<QString>() );
	// call with item=NULL to filter the entire tree
	bool filterItems( const QString & filter, QTreeWidgetItem * item=nullptr );
	void giveFocusToFilter();

private:
	void keyPressEvent( QKeyEvent * ke ) override;

	void addItems( const QString & path );

	FileBrowserTreeWidget * m_fileBrowserTreeWidget;

	QLineEdit * m_filterEdit;

	QString m_directories; //!< Directories to search, split with '*'
	QString m_filter; //!< Filter as used in QDir::match()

	bool m_dirsAsItems;
	bool m_recurse;

	void addContentCheckBox();
	QCheckBox* m_showUserContent = nullptr;
	QCheckBox* m_showFactoryContent = nullptr;
	QString m_userDir;
	QString m_factoryDir;
} ;

class FileBrowserTreeWidget : public QTreeWidget
{
	Q_OBJECT
public:
	FileBrowserTreeWidget( QWidget * parent );
	virtual ~FileBrowserTreeWidget() = default;

	//! This method returns a QList with paths (QString's) of all directories
	//! that are expanded in the tree.
	QList<QString> expandedDirs( QTreeWidgetItem * item = nullptr ) const;

protected:
	void contextMenuEvent( QContextMenuEvent * e ) override;
	void mousePressEvent( QMouseEvent * me ) override;
	void mouseMoveEvent( QMouseEvent * me ) override;
	void mouseReleaseEvent( QMouseEvent * me ) override;
	void keyPressEvent( QKeyEvent * ke ) override;
	void keyReleaseEvent( QKeyEvent * ke ) override;
	void hideEvent( QHideEvent * he ) override;
	void focusOutEvent( QFocusEvent * fe ) override;

private:
	//! Start a preview of a file item
	void previewFileItem(FileItem* file);
	//! If a preview is playing, stop it.
	void stopPreview();

	void handleFile( FileItem * fi, InstrumentTrack * it );
	void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item );

	bool m_mousePressed;
	QPoint m_pressPos;

	//! This should only be accessed or modified when m_pphMutex is held
	PlayHandle* m_previewPlayHandle;
	QMutex m_pphMutex;

	QList<QAction*> getContextActions(FileItem* item, bool songEditor);

private slots:
	void activateListItem( QTreeWidgetItem * item, int column );
	void openInNewInstrumentTrack( FileItem* item, bool songEditor );
	bool openInNewSampleTrack( FileItem* item );
	void sendToActiveInstrumentTrack( FileItem* item );
	void updateDirectory( QTreeWidgetItem * item );
	void openContainingFolder( FileItem* item );

} ;

class Directory : public QTreeWidgetItem
{
public:
	Directory( const QString & filename, const QString & path,
						const QString & filter );

	void update( void );

	inline QString fullName( QString path = QString() )
	{
		if( path.isEmpty() )
		{
			path = m_directories[0];
		}
		if( ! path.isEmpty() )
		{
			path += QDir::separator();
		}
		return( QDir::cleanPath( path + text( 0 ) ) +
							QDir::separator() );
	}

	inline void addDirectory( const QString & dir )
	{
		m_directories.push_back( dir );
	}

private:
	void initPixmaps( void );

	bool addItems( const QString & path );

	static QPixmap * s_folderPixmap;
	static QPixmap * s_folderOpenedPixmap;
	static QPixmap * s_folderLockedPixmap;

	//! Directories that lead here
	//! Initially, this is just set to the current path of a directory
	//! If, however, you have e.g. 'TripleOscillator/xyz' in two of the
	//! file browser's search directories 'a' and 'b', this will have two
	//! entries 'a/TripleOscillator' and 'b/TripleOscillator'
	//! and 'xyz' in the tree widget
	QStringList m_directories;
	//! Filter as used in QDir::match()
	QString m_filter;

	int m_dirCount;

} ;

class FileItem : public QTreeWidgetItem
{
public:
	enum FileTypes
	{
		ProjectFile,
		PresetFile,
		SampleFile,
		SoundFontFile,
		PatchFile,
		MidiFile,
		VstPluginFile,
		UnknownFile,
		NumFileTypes
	} ;

	enum FileHandling
	{
		NotSupported,
		LoadAsProject,
		LoadAsPreset,
		LoadByPlugin,
		ImportAsProject
	} ;

	FileItem( QTreeWidget * parent, const QString & name,
							const QString & path );
	FileItem( const QString & name, const QString & path );

	QString fullName() const
	{
		return QFileInfo(m_path, text(0)).absoluteFilePath();
	}

	inline FileTypes type( void ) const
	{
		return( m_type );
	}

	inline FileHandling handling( void ) const
	{
		return( m_handling );
	}

	inline bool isTrack( void ) const
	{
		return m_handling == LoadAsPreset || m_handling == LoadByPlugin;
	}

	QString extension( void );
	static QString extension( const QString & file );

private:
	void initPixmaps( void );
	void determineFileType( void );

	static QPixmap * s_projectFilePixmap;
	static QPixmap * s_presetFilePixmap;
	static QPixmap * s_sampleFilePixmap;
	static QPixmap * s_soundfontFilePixmap;
	static QPixmap * s_vstPluginFilePixmap;
	static QPixmap * s_midiFilePixmap;
	static QPixmap * s_unknownFilePixmap;

	QString m_path;
	FileTypes m_type;
	FileHandling m_handling;

} ;

#endif


code:
/*
 * FileDialog.h - declaration of class FileDialog
 *
 * Copyright (c) 2014 Lukas W <lukaswhl/at/gmail.com>
 *
 * 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.
 *
 */

#ifndef FILEDIALOG_H
#define FILEDIALOG_H

#include <QFileDialog>

#include "lmms_export.h"

class LMMS_EXPORT FileDialog : public QFileDialog
{
	Q_OBJECT
public:
	explicit FileDialog( QWidget *parent = 0, const QString &caption = QString(),
						const QString &directory = QString(),
						const QString &filter = QString() );

	static QString getExistingDirectory(QWidget *parent,
										const QString &caption,
										const QString &directory,
										QFileDialog::Options options = QFileDialog::ShowDirsOnly);
    static QString getOpenFileName(QWidget *parent = 0,
									const QString &caption = QString(),
									const QString &directory = QString(),
									const QString &filter = QString(),
									QString *selectedFilter = 0);
	void clearSelection();
};

#endif // FILEDIALOG_HPP


code:
/*
 * FxLine.h - FX line widget
 *
 * Copyright (c) 2009 Andrew Kelley <superjoe30/at/gmail/dot/com>
 * Copyright (c) 2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef FX_LINE_H
#define FX_LINE_H

#include <QColorDialog>
#include <QGraphicsView>
#include <QLineEdit>
#include <QWidget>

#include "ColorChooser.h"
#include "Knob.h"
#include "LcdWidget.h"
#include "SendButtonIndicator.h"

class FxMixerView;
class SendButtonIndicator;

class FxLine : public QWidget
{
	Q_OBJECT
public:
	Q_PROPERTY( QBrush backgroundActive READ backgroundActive WRITE setBackgroundActive )
	Q_PROPERTY( QColor strokeOuterActive READ strokeOuterActive WRITE setStrokeOuterActive )
	Q_PROPERTY( QColor strokeOuterInactive READ strokeOuterInactive WRITE setStrokeOuterInactive )
	Q_PROPERTY( QColor strokeInnerActive READ strokeInnerActive WRITE setStrokeInnerActive )
	Q_PROPERTY( QColor strokeInnerInactive READ strokeInnerInactive WRITE setStrokeInnerInactive )
	FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex);
	~FxLine();

	void paintEvent( QPaintEvent * ) override;
	void mousePressEvent( QMouseEvent * ) override;
	void mouseDoubleClickEvent( QMouseEvent * ) override;
	void contextMenuEvent( QContextMenuEvent * ) override;

	inline int channelIndex() { return m_channelIndex; }
	void setChannelIndex(int index);

	Knob * m_sendKnob;
	SendButtonIndicator * m_sendBtn;

	QBrush backgroundActive() const;
	void setBackgroundActive( const QBrush & c );

	QColor strokeOuterActive() const;
	void setStrokeOuterActive( const QColor & c );

	QColor strokeOuterInactive() const;
	void setStrokeOuterInactive( const QColor & c );

	QColor strokeInnerActive() const;
	void setStrokeInnerActive( const QColor & c );

	QColor strokeInnerInactive() const;
	void setStrokeInnerInactive( const QColor & c );

	static const int FxLineHeight;

	bool eventFilter (QObject *dist, QEvent *event) override;

private:
	void drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool sendToThis, bool receiveFromThis );
	QString elideName( const QString & name );

	FxMixerView * m_mv;
	LcdWidget* m_lcd;
	int m_channelIndex;
	QBrush m_backgroundActive;
	QColor m_strokeOuterActive;
	QColor m_strokeOuterInactive;
	QColor m_strokeInnerActive;
	QColor m_strokeInnerInactive;
	static QPixmap * s_sendBgArrow;
	static QPixmap * s_receiveBgArrow;
	bool m_inRename;
	QLineEdit * m_renameLineEdit;
	QGraphicsView * m_view;

public slots:
	void renameChannel();
	void resetColor();
	void changeColor();
	void randomColor();

private slots:
	void renameFinished();
	void removeChannel();
	void removeUnusedChannels();
	void moveChannelLeft();
	void moveChannelRight();
};

#endif // FXLINE_H


code:
/*
 * FxLineLcdSpinBox.h - a specialization of LcdSpnBox for setting FX channels
 *
 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef FX_LINE_LCD_SPIN_BOX_H
#define FX_LINE_LCD_SPIN_BOX_H

#include "LcdSpinBox.h"

class TrackView;

class FxLineLcdSpinBox : public LcdSpinBox
{
	Q_OBJECT
public:
	FxLineLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = NULL) :
		LcdSpinBox(numDigits, parent, name), m_tv(tv)
	{}
	virtual ~FxLineLcdSpinBox() {}

	void setTrackView(TrackView * tv);

protected:
	void mouseDoubleClickEvent(QMouseEvent* event) override;
	void contextMenuEvent(QContextMenuEvent* event) override;

private:
	TrackView * m_tv;

};

#endif


code:
/*
 * FxMixer.h - effect-mixer for LMMS
 *
 * Copyright (c) 2008-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef FX_MIXER_H
#define FX_MIXER_H

#include "Model.h"
#include "EffectChain.h"
#include "JournallingObject.h"
#include "ThreadableJob.h"

#include <atomic>

#include <QColor>

class FxRoute;
typedef QVector<FxRoute *> FxRouteVector;

class FxChannel : public ThreadableJob
{
	public:
		FxChannel( int idx, Model * _parent );
		virtual ~FxChannel();

		EffectChain m_fxChain;

		// set to true when input fed from mixToChannel or child channel
		bool m_hasInput;
		// set to true if any effect in the channel is enabled and running
		bool m_stillRunning;

		float m_peakLeft;
		float m_peakRight;
		sampleFrame * m_buffer;
		bool m_muteBeforeSolo;
		BoolModel m_muteModel;
		BoolModel m_soloModel;
		FloatModel m_volumeModel;
		QString m_name;
		QMutex m_lock;
		int m_channelIndex; // what channel index are we
		bool m_queued; // are we queued up for rendering yet?
		bool m_muted; // are we muted? updated per period so we don't have to call m_muteModel.value() twice

		// pointers to other channels that this one sends to
		FxRouteVector m_sends;

		// pointers to other channels that send to this one
		FxRouteVector m_receives;

		bool requiresProcessing() const override { return true; }
		void unmuteForSolo();

		void setColor (QColor newColor)
		{
			m_color = newColor;
			m_hasColor = true;
		}

		// TODO C++17 and above: use std::optional instead
		QColor m_color;
		bool m_hasColor;

		std::atomic_int m_dependenciesMet;
		void incrementDeps();
		void processed();

	private:
		void doProcessing() override;
};

class FxRoute : public QObject
{
	Q_OBJECT
	public:
		FxRoute( FxChannel * from, FxChannel * to, float amount );
		virtual ~FxRoute();

	fx_ch_t senderIndex() const
	{
		return m_from->m_channelIndex;
	}

	fx_ch_t receiverIndex() const
	{
		return m_to->m_channelIndex;
	}

	FloatModel * amount()
	{
		return &m_amount;
	}

	FxChannel * sender() const
	{
		return m_from;
	}

	FxChannel * receiver() const
	{
		return m_to;
	}

	void updateName();

	private:
		FxChannel * m_from;
		FxChannel * m_to;
		FloatModel m_amount;
};

class LMMS_EXPORT FxMixer : public Model, public JournallingObject
{
	Q_OBJECT
public:
	FxMixer();
	virtual ~FxMixer();

	void mixToChannel( const sampleFrame * _buf, fx_ch_t _ch );

	void prepareMasterMix();
	void masterMix( sampleFrame * _buf );

	void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
	void loadSettings( const QDomElement & _this ) override;

	QString nodeName() const override
	{
		return "fxmixer";
	}

	FxChannel * effectChannel( int _ch )
	{
		return m_fxChannels[_ch];
	}

	// make the output of channel fromChannel go to the input of channel toChannel
	// it is safe to call even if the send already exists
	FxRoute * createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel,
						   float amount = 1.0f);
	FxRoute * createRoute( FxChannel * from, FxChannel * to, float amount );

	// delete the connection made by createChannelSend
	void deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel);
	void deleteChannelSend( FxRoute * route );

	// determine if adding a send from sendFrom to
	// sendTo would result in an infinite mixer loop.
	bool isInfiniteLoop(fx_ch_t fromChannel, fx_ch_t toChannel);
	bool checkInfiniteLoop( FxChannel * from, FxChannel * to );

	// return the FloatModel of fromChannel sending its output to the input of
	// toChannel. NULL if there is no send.
	FloatModel * channelSendModel(fx_ch_t fromChannel, fx_ch_t toChannel);

	// add a new channel to the Fx Mixer.
	// returns the index of the channel that was just added
	int createChannel();

	// delete a channel from the FX mixer.
	void deleteChannel(int index);

	// delete all the mixer channels except master and remove all effects
	void clear();

	// re-arrange channels
	void moveChannelLeft(int index);
	void moveChannelRight(int index);

	// reset a channel's name, fx, sends, etc
	void clearChannel(fx_ch_t channelIndex);

	// rename channels when moving etc. if they still have their original name
	void validateChannelName( int index, int oldIndex );

	void toggledSolo();
	void activateSolo();
	void deactivateSolo();

	inline fx_ch_t numChannels() const
	{
		return m_fxChannels.size();
	}

	FxRouteVector m_fxRoutes;

private:
	// the fx channels in the mixer. index 0 is always master.
	QVector<FxChannel *> m_fxChannels;

	// make sure we have at least num channels
	void allocateChannelsTo(int num);

	int m_lastSoloed;

} ;

#endif


code:
/*
 * FxMixerView.h - effect-mixer-view for LMMS
 *
 * Copyright (c) 2008-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef FX_MIXER_VIEW_H
#define FX_MIXER_VIEW_H

#include <QWidget>
#include <QHBoxLayout>
#include <QStackedLayout>
#include <QScrollArea>

#include "ModelView.h"
#include "Engine.h"
#include "Fader.h"
#include "PixmapButton.h"
#include "ToolTip.h"
#include "embed.h"
#include "EffectRackView.h"

class QButtonGroup;
class FxLine;

class LMMS_EXPORT FxMixerView : public QWidget, public ModelView,
					public SerializingObjectHook
{
	Q_OBJECT
public:
	class FxChannelView
	{
	public:
		FxChannelView(QWidget * _parent, FxMixerView * _mv, int _chIndex );

		void setChannelIndex( int index );

		FxLine * m_fxLine;
		PixmapButton * m_muteBtn;
		PixmapButton * m_soloBtn;
		Fader * m_fader;
		EffectRackView * m_rackView;
	};

	FxMixerView();
	virtual ~FxMixerView();

	void keyPressEvent(QKeyEvent * e) override;

	void saveSettings( QDomDocument & _doc, QDomElement & _this ) override;
	void loadSettings( const QDomElement & _this ) override;

	inline FxLine * currentFxLine()
	{
		return m_currentFxLine;
	}

	inline FxChannelView * channelView(int index)
	{
		return m_fxChannelViews[index];
	}

	void setCurrentFxLine( FxLine * _line );
	void setCurrentFxLine( int _line );

	void clear();

	// display the send button and knob correctly
	void updateFxLine(int index);

	// notify the view that an fx channel was deleted
	void deleteChannel(int index);

	// delete all unused channels
	void deleteUnusedChannels();

	// move the channel to the left or right
	void moveChannelLeft(int index);
	void moveChannelLeft(int index, int focusIndex);
	void moveChannelRight(int index);

	void renameChannel(int index);

	// make sure the display syncs up with the fx mixer.
	// useful for loading projects
	void refreshDisplay();

public slots:
	int addNewChannel();

protected:
	void closeEvent( QCloseEvent * _ce ) override;

private slots:
	void updateFaders();
	void toggledSolo();

private:

	QVector<FxChannelView *> m_fxChannelViews;

	FxLine * m_currentFxLine;

	QScrollArea * channelArea;
	QHBoxLayout * chLayout;
	QWidget * m_channelAreaWidget;
	QStackedLayout * m_racksLayout;
	QWidget * m_racksWidget;

	void updateMaxChannelSelector();

	friend class FxChannelView;
} ;

#endif


code:
/*
 * Graph.h - a QT widget for displaying and manipulating waveforms
 *
 * Copyright (c) 2006-2007 Andreas Brandmaier <andy/at/brandmaier/dot/de>
 *               2008 Paul Giblock <drfaygo/at/gmail/dot/com>
 *
 * 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.
 *
 */

#ifndef GRAPH_H
#define GRAPH_H

#include <QWidget>
#include <QPixmap>
#include <QCursor>

#include "Model.h"
#include "ModelView.h"
#include "lmms_basics.h"

class graphModel;

class LMMS_EXPORT Graph : public QWidget, public ModelView
{
	Q_OBJECT
public:
	enum graphStyle
	{
		NearestStyle, //!< draw as stairs
		LinearStyle, //!< connect each 2 samples with a line, with wrapping
		LinearNonCyclicStyle, //!< LinearStyle without wrapping
		BarStyle, //!< draw thick bars
		NumGraphStyles
	};

	/**
	 * @brief Constructor
	 * @param _width Pixel width of widget
	 * @param _height Pixel height of widget
	 */
	Graph( QWidget * _parent, graphStyle _style = Graph::LinearStyle,
		int _width = 132,
		int _height = 104
	);
	virtual ~Graph() = default;

	void setForeground( const QPixmap & _pixmap );

	void setGraphColor( const QColor );

	inline graphModel * model()
	{
		return castModel<graphModel>();
	}

	inline graphStyle getGraphStyle()
	{
		return m_graphStyle;
	}

	inline void setGraphStyle( graphStyle _s )
	{
		m_graphStyle = _s;
		update();
	}

signals:
	void drawn();
protected:
	void paintEvent( QPaintEvent * _pe ) override;
	void dropEvent( QDropEvent * _de ) override;
	void dragEnterEvent( QDragEnterEvent * _dee ) override;
	void mousePressEvent( QMouseEvent * _me ) override;
	void mouseMoveEvent( QMouseEvent * _me ) override;
	void mouseReleaseEvent( QMouseEvent * _me ) override;

protected slots:
	void updateGraph( int _startPos, int _endPos );
	void updateGraph();

private:
	void modelChanged() override;

	void changeSampleAt( int _x, int _y );
	void drawLineAt( int _x, int _y, int _lastx );

	QPixmap m_foreground;
	QColor m_graphColor;

	graphStyle m_graphStyle;

	bool m_mouseDown;
	int m_lastCursorX;

} ;

/**
	@brief 2 dimensional function plot

	Function plot graph with discrete x scale and continous y scale
	This makes it possible to display "#x" samples
*/
class LMMS_EXPORT graphModel : public Model
{
	Q_OBJECT
public:
	/**
	 * @brief Constructor
	 * @param _min Minimum y value to display
	 * @param _max Maximum y value to display
	 * @param _size Number of samples (e.g. x value)
	 * @param _step Step size on y axis where values snap to, or 0.0f
	 *   for "no snapping"
	 */
	graphModel( float _min,
			float _max,
			int _size,
			:: Model * _parent,
			bool _default_constructed = false,
			float _step = 0.0 );

	virtual ~graphModel() = default;

	// TODO: saveSettings, loadSettings?

	inline float minValue() const
	{
		return( m_minValue );
	}

	inline float maxValue() const
	{
		return( m_maxValue );
	}

	inline int length() const
	{
		return m_length;
	}

	inline const float * samples() const
	{
		return( m_samples.data() );
	}

	//! Make cyclic convolution
	//! @param convolution Samples to convolve with
	//! @param convolutionLength Number of samples to take for each sum
	//! @param centerOffset Offset for resulting values
	void convolve(const float *convolution,
		const int convolutionLength, const int centerOffset);

public slots:
	//! Set range of y values
	void setRange( float _min, float _max );

	void setLength( int _size );
	//! Update one sample
	void setSampleAt( int x, float val );
	//! Update samples array
	void setSamples( const float * _value );

	void setWaveToSine();
	void setWaveToTriangle();
	void setWaveToSaw();
	void setWaveToSquare();
	void setWaveToNoise();
	QString setWaveToUser( );

	void smooth();
	void smoothNonCyclic();
	void normalize();
	void invert();
	void shiftPhase( int _deg );
	void clear();
	void clearInvisible();

signals:
	void lengthChanged();
	void samplesChanged( int startPos, int endPos );
	void rangeChanged();

private:
	void drawSampleAt( int x, float val );

	QVector<float> m_samples;
	int m_length;
	float m_minValue;
	float m_maxValue;
	float m_step;

	friend class Graph;

};

#endif


code:
/*
 * GroupBox.h - LMMS-groupbox
 *
 * Copyright (c) 2005-2008 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef GROUP_BOX_H
#define GROUP_BOX_H

#include <QWidget>

#include "AutomatableModelView.h"
#include "PixmapButton.h"

class QPixmap;

class GroupBox : public QWidget, public BoolModelView
{
	Q_OBJECT
public:
	GroupBox( const QString & _caption, QWidget * _parent = NULL );
	virtual ~GroupBox();

	void modelChanged() override;

	PixmapButton * ledButton()
	{
		return m_led;
	}

	int titleBarHeight() const
	{
		return m_titleBarHeight;
	}

protected:
	void mousePressEvent( QMouseEvent * _me ) override;
	void paintEvent( QPaintEvent * _pe ) override;

private:
	void updatePixmap();

	PixmapButton * m_led;
	QString m_caption;
	const int m_titleBarHeight;

} ;

#endif


code:
/*
 * GuiApplication.h
 *
 * Copyright (c) 2014 Lukas W <lukaswhl/at/gmail.com>
 *
 * 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.
 *
 */

#ifndef GUIAPPLICATION_H
#define GUIAPPLICATION_H

#include <QtCore/QObject>

#include "lmms_export.h"
#include "lmmsconfig.h"

class QLabel;

class AutomationEditorWindow;
class BBEditor;
class ControllerRackView;
class FxMixerView;
class MainWindow;
class PianoRollWindow;
class ProjectNotes;
class SongEditorWindow;

class LMMS_EXPORT GuiApplication : public QObject
{
	Q_OBJECT;
public:
	explicit GuiApplication();
	~GuiApplication();

	static GuiApplication* instance();
#ifdef LMMS_BUILD_WIN32
	static QFont getWin32SystemFont();
#endif

	MainWindow* mainWindow() { return m_mainWindow; }
	FxMixerView* fxMixerView() { return m_fxMixerView; }
	SongEditorWindow* songEditor() { return m_songEditor; }
	BBEditor* getBBEditor() { return m_bbEditor; }
	PianoRollWindow* pianoRoll() { return m_pianoRoll; }
	ProjectNotes* getProjectNotes() { return m_projectNotes; }
	AutomationEditorWindow* automationEditor() { return m_automationEditor; }
	ControllerRackView* getControllerRackView() { return m_controllerRackView; }

public slots:
	void displayInitProgress(const QString &msg);

private slots:
	void childDestroyed(QObject *obj);

private:
	static GuiApplication* s_instance;

	MainWindow* m_mainWindow;
	FxMixerView* m_fxMixerView;
	SongEditorWindow* m_songEditor;
	AutomationEditorWindow* m_automationEditor;
	BBEditor* m_bbEditor;
	PianoRollWindow* m_pianoRoll;
	ProjectNotes* m_projectNotes;
	ControllerRackView* m_controllerRackView;
	QLabel* m_loadingProgressLabel;
};

#define gui GuiApplication::instance()

#endif // GUIAPPLICATION_H


code:
/*
 * ImportFilter.h - declaration of class ImportFilter, the base-class for all
 *                  file import filters
 *
 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef IMPORT_FILTER_H
#define IMPORT_FILTER_H

#include <QtCore/QFile>

#include "Plugin.h"

class TrackContainer;

class LMMS_EXPORT ImportFilter : public Plugin
{
public:
	ImportFilter( const QString & _file_name,
					const Descriptor * _descriptor );
	virtual ~ImportFilter();

	// tries to import given file to given track-container by having all
	// available import-filters to try to import the file
	static void import( const QString & _file_to_import,
						TrackContainer* tc );

protected:
	virtual bool tryImport( TrackContainer* tc ) = 0;

	const QFile & file() const
	{
		return m_file;
	}

	bool openFile();

	inline void closeFile()
	{
		m_file.close();
	}

	inline int readByte()
	{
		unsigned char c;
		if( m_file.getChar( (char*) &c ) )
		{
			return static_cast<int>( c );
		}
		return -1;
	}

	inline int readBlock( char * _data, int _len )
	{
		return m_file.read( _data, _len );
	}

	inline QByteArray readAllData()
	{
		m_file.seek(0);
		return m_file.readAll();
	}

	inline void ungetChar( char _ch )
	{
		m_file.ungetChar( _ch );
	}

	void saveSettings( QDomDocument &, QDomElement & ) override
	{
	}

	void loadSettings( const QDomElement & ) override
	{
	}

	QString nodeName() const override
	{
		return "import_filter";
	}

private:
	QFile m_file;

} ;

#endif


code:
/*
 * InlineAutomation.h - class for automating something "inline"
 *
 * Copyright (c) 2008-2010 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef INLINE_AUTOMATION_H
#define INLINE_AUTOMATION_H

#include "AutomationPattern.h"
#include "shared_object.h"

class InlineAutomation : public FloatModel, public sharedObject
{
public:
	InlineAutomation() :
		FloatModel(),
		sharedObject(),
		m_autoPattern( NULL )
	{
	}

	virtual ~InlineAutomation()
	{
		if( m_autoPattern )
		{
			delete m_autoPattern;
		}
	}

	virtual float defaultValue() const = 0;

	bool hasAutomation() const
	{
		if( m_autoPattern != NULL && m_autoPattern->getTimeMap().isEmpty() == false )
		{
			// prevent saving inline automation if there's just one value which equals value
			// of model which is going to be saved anyways
			if( isAtInitValue() &&
				m_autoPattern->getTimeMap().size() == 1 &&
				m_autoPattern->getTimeMap().keys().first() == 0 &&
				m_autoPattern->getTimeMap().values().first() == value() )
			{
				return false;
			}

			return true;
		}

		return false;
	}

	AutomationPattern * automationPattern()
	{
		if( m_autoPattern == NULL )
		{
			m_autoPattern = new AutomationPattern( NULL );
			m_autoPattern->addObject( this );
		}
		return m_autoPattern;
	}

	void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
	void loadSettings( const QDomElement & _this ) override;

private:
	AutomationPattern * m_autoPattern;

} ;

#endif


code:
/*
 * Instrument.h - declaration of class Instrument, which provides a
 *                standard interface for all instrument plugins
 *
 * Copyright (c) 2005-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef INSTRUMENT_H
#define INSTRUMENT_H

#include <QString>
#include "lmms_export.h"
#include "lmms_basics.h"
#include "MemoryManager.h"
#include "Plugin.h"
#include "TimePos.h"

// forward-declarations
class InstrumentTrack;
class MidiEvent;
class NotePlayHandle;
class Track;

class LMMS_EXPORT Instrument : public Plugin
{
	MM_OPERATORS
public:
	enum Flag
	{
		NoFlags = 0x00,
		IsSingleStreamed = 0x01,	/*! Instrument provides a single audio stream for all notes */
		IsMidiBased = 0x02,			/*! Instrument is controlled by MIDI events rather than NotePlayHandles */
		IsNotBendable = 0x04,		/*! Instrument can't react to pitch bend changes */
	};

	Q_DECLARE_FLAGS(Flags, Flag);

	Instrument(InstrumentTrack * _instrument_track,
			const Descriptor * _descriptor,
			const Descriptor::SubPluginFeatures::Key * key = nullptr);
	virtual ~Instrument() = default;

	// --------------------------------------------------------------------
	// functions that can/should be re-implemented:
	// --------------------------------------------------------------------

	virtual bool hasNoteInput() const { return true; }

	// if the plugin doesn't play each note, it can create an instrument-
	// play-handle and re-implement this method, so that it mixes its
	// output buffer only once per mixer-period
	virtual void play( sampleFrame * _working_buffer );

	// to be implemented by actual plugin
	virtual void playNote( NotePlayHandle * /* _note_to_play */,
					sampleFrame * /* _working_buf */ )
	{
	}

	// needed for deleting plugin-specific-data of a note - plugin has to
	// cast void-ptr so that the plugin-data is deleted properly
	// (call of dtor if it's a class etc.)
	virtual void deleteNotePluginData( NotePlayHandle * _note_to_play );

	// Get number of sample-frames that should be used when playing beat
	// (note with unspecified length)
	// Per default this function returns 0. In this case, channel is using
	// the length of the longest envelope (if one active).
	virtual f_cnt_t beatLen( NotePlayHandle * _n ) const;

	// some instruments need a certain number of release-frames even
	// if no envelope is active - such instruments can re-implement this
	// method for returning how many frames they at least like to have for
	// release
	virtual f_cnt_t desiredReleaseFrames() const
	{
		return 0;
	}

	virtual Flags flags() const
	{
		return NoFlags;
	}

	// sub-classes can re-implement this for receiving all incoming
	// MIDI-events
	inline virtual bool handleMidiEvent( const MidiEvent&, const TimePos& = TimePos(), f_cnt_t offset = 0 )
	{
		return true;
	}

	QString fullDisplayName() const override;

	// --------------------------------------------------------------------
	// provided functions:
	// --------------------------------------------------------------------

	//! instantiate instrument-plugin with given name or return NULL
	//! on failure
	static Instrument * instantiate(const QString & _plugin_name,
		InstrumentTrack * _instrument_track,
		const Plugin::Descriptor::SubPluginFeatures::Key* key,
		bool keyFromDnd = false);

	virtual bool isFromTrack( const Track * _track ) const;

	inline InstrumentTrack * instrumentTrack() const
	{
		return m_instrumentTrack;
	}

protected:
	// fade in to prevent clicks
	void applyFadeIn(sampleFrame * buf, NotePlayHandle * n);

	// instruments may use this to apply a soft fade out at the end of
	// notes - method does this only if really less or equal
	// desiredReleaseFrames() frames are left
	void applyRelease( sampleFrame * buf, const NotePlayHandle * _n );

private:
	InstrumentTrack * m_instrumentTrack;

} ;

Q_DECLARE_OPERATORS_FOR_FLAGS(Instrument::Flags)

#endif


code:
/*
 * InstrumentFunctionViews.h - views for instrument-functions-tab
 *
 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/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.
 *
 */

#ifndef INSTRUMENT_FUNCTION_VIEWS_H
#define INSTRUMENT_FUNCTION_VIEWS_H

#include "ModelView.h"

#include <QWidget>

class QLabel;
class ComboBox;
class GroupBox;
class Knob;
class TempoSyncKnob;

class InstrumentFunctionArpeggio;
class InstrumentFunctionNoteStacking;

class InstrumentFunctionNoteStackingView : public QWidget, public ModelView
{
	Q_OBJECT
public:
	InstrumentFunctionNoteStackingView( InstrumentFunctionNoteStacking* cc, QWidget* parent = NULL );
	virtual ~InstrumentFunctionNoteStackingView();

private:
	void modelChanged() override;

	InstrumentFunctionNoteStacking * m_cc;

	GroupBox * m_chordsGroupBox;
	ComboBox * m_chordsComboBox;
	Knob * m_chordRangeKnob;

} ;

class InstrumentFunctionArpeggioView : public QWidget, public ModelView
{
	Q_OBJECT
public:
	InstrumentFunctionArpeggioView( InstrumentFunctionArpeggio* arp, QWidget* parent = NULL );
	virtual ~InstrumentFunctionArpeggioView();

private:
	void modelChanged() override;

	InstrumentFunctionArpeggio * m_a;
	GroupBox * m_arpGroupBox;
	ComboBox * m_arpComboBox;
	Knob * m_arpRangeKnob;
	Knob * m_arpRepeatsKnob;
	Knob * m_arpCycleKnob;
	Knob * m_arpSkipKnob;
	Knob * m_arpMissKnob;
	TempoSyncKnob * m_arpTimeKnob;
	Knob * m_arpGateKnob;

	ComboBox * m_arpDirectionComboBox;
	ComboBox * m_arpModeComboBox;

} ;

#endif