1 /***************************************************************************
2  *                                                                         *
3  *   Copyright (C) 2008 - 2013 Christian Schoenebeck                       *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the Free Software           *
17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
18  *   MA  02111-1307  USA                                                   *
19  ***************************************************************************/
20 
21 #ifndef LS_EFFECTCHAIN_H
22 #define LS_EFFECTCHAIN_H
23 
24 #include "Effect.h"
25 
26 namespace LinuxSampler {
27 
28 // just symbol prototyping
29 class AudioOutputDevice;
30 
31 /**
32  * Container for a series of effects. The effects are sequentially processed,
33  * that is the output of the first effect is passed to the input of the next
34  * effect in the chain and so on.
35  */
36 class EffectChain {
37 public:
38     /**
39      * Constructor.
40      *
41      * @param pDevice - audio output context for the effects, providing
42      *                  informations like samplerate and buffer size
43      * @param iEffectChainId - (optional) numerical ID of the effect chain,
44      *                         intended for master effect chains, unique among
45      *                         all master effect chains which share the same
46      *                         audio output device
47      */
48     EffectChain(AudioOutputDevice* pDevice, int iEffectChainId = -1);
49 
50     /**
51      * Add the given effect to the end of the effect chain.
52      */
53     void AppendEffect(Effect* pEffect);
54 
55     /**
56      * Insert the given effect into the position given by @a iChainPos .
57      *
58      * @throw Exception - if given position is invalid
59      */
60     void InsertEffect(Effect* pEffect, int iChainPos) throw (Exception);
61 
62     /**
63      * Remove effect at chain position @a iChainPos from the effect chain.
64      *
65      * @throws Exception - if given position is invalid
66      */
67     void RemoveEffect(int iChainPos) throw (Exception);
68 
69     /**
70      * Sequentially render the whole effects chain. The final signal
71      * will be available in the output channels of the last effect in
72      * the chain after this call, which then has to be copied to the
73      * desired destination (e.g. the AudioOutputDevice's output channels).
74      */
75     void RenderAudio(uint Samples);
76 
77     /**
78      * Returns effect at chain position @a iChainPos .
79      */
80     Effect* GetEffect(int iChainPos) const;
81 
82     /**
83      * Returns amount of effects this effect chain currently contains.
84      */
85     int EffectCount() const;
86 
87     /**
88      * Enable / disable the given effect. Currently, disabled effects are
89      * automatically bypassed. We might add explicit "bypass" control in
90      * future though.
91      *
92      * @throw Exception - if chain position is invalid
93      */
94     void SetEffectActive(int iChainPos, bool bOn) throw (Exception);
95 
96     /**
97      * Whether the given effect is currently enabled.
98      */
99     bool IsEffectActive(int iChainPos) const;
100 
101     /**
102      * Should / will be called whenever the effect chaing is moving to
103      * another audio output device and also when an important audio
104      * parameter like sample rate or buffer size has been changed.
105      * Calling this method will cause all effects to inform about this
106      * change and prepare them for the new given audio output device.
107      *
108      * @param pDevice - audio output context for the effects, providing
109      *                  informations like samplerate and buffer size
110      */
111     void Reconnect(AudioOutputDevice* pDevice);
112 
113     /**
114      * Clears the audio input and output channels of all effects in the chain.
115      */
116     void ClearAllChannels();
117 
118     /**
119      * Returns numerical ID of this effect chain, intended for master effect
120      * chains. The ID is unique among all master effect chains which share the
121      * same audio output device.
122      *
123      * There is no ID for insert effect chains, since a sampler channel
124      * always provides exactly one insert effect chain.
125      *
126      * @returns id equal or larger than zero if master effect chain, negative
127      *          number if this is an insert effect chain
128      */
129     int ID() const;
130 
131 private:
132     struct _ChainEntry {
133         Effect* pEffect;
134         bool    bActive;
135     };
136 
137     std::vector<_ChainEntry> vEntries;
138     AudioOutputDevice*       pDevice;
139     int                      iID;
140 };
141 
142 } // namespace LinuxSampler
143 
144 #endif // LS_EFFECTCHAIN_H
145