/[svn]/linuxsampler/trunk/src/effects/EffectChain.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/effects/EffectChain.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2124 - (show annotations) (download)
Sat Sep 18 09:24:41 2010 UTC (13 years, 6 months ago) by schoenebeck
File size: 5031 byte(s)
* implemented support for internal LADSPA effects (work in progress)

1 /***************************************************************************
2 * *
3 * Copyright (C) 2008 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 #include "EffectChain.h"
22
23 #include "../common/global_private.h"
24
25 namespace LinuxSampler {
26
27 EffectChain::EffectChain(AudioOutputDevice* pDevice) {
28 this->pDevice = pDevice;
29 }
30
31 void EffectChain::AppendEffect(Effect* pEffect) {
32 pEffect->InitEffect(pDevice);
33 _ChainEntry entry = { pEffect, true };
34 vEntries.push_back(entry);
35 }
36
37 void EffectChain::InsertEffect(Effect* pEffect, int iChainPos) throw (Exception) {
38 if (iChainPos < 0 || iChainPos >= vEntries.size())
39 throw Exception(
40 "Cannot insert effect at chain position " +
41 ToString(iChainPos) + ", index out of bounds."
42 );
43 pEffect->InitEffect(pDevice); // might throw Exception !
44 std::vector<_ChainEntry>::iterator iter = vEntries.begin();
45 for (int i = 0; i < iChainPos; ++i) ++iter;
46 _ChainEntry entry = { pEffect, true };
47 vEntries.insert(iter, entry);
48 }
49
50 void EffectChain::RemoveEffect(int iChainPos) throw (Exception) {
51 if (iChainPos < 0 || iChainPos >= vEntries.size())
52 throw Exception(
53 "Cannot remove effect at chain position " +
54 ToString(iChainPos) + ", index out of bounds."
55 );
56 std::vector<_ChainEntry>::iterator iter = vEntries.begin();
57 for (int i = 0; i < iChainPos; ++i) ++iter;
58 vEntries.erase(iter);
59 }
60
61 void EffectChain::RenderAudio(uint Samples) {
62 for (int i = 0; i < vEntries.size(); ++i) {
63 Effect* pCurrentEffect = vEntries[i].pEffect;
64 if (i) { // import signal from previous effect
65 Effect* pPrevEffect = vEntries[i - 1].pEffect;
66 for (int iChan = 0; iChan < pPrevEffect->OutputChannelCount() && iChan < pCurrentEffect->InputChannelCount(); ++iChan) {
67 pPrevEffect->OutputChannel(iChan)->MixTo(
68 pCurrentEffect->InputChannel(iChan),
69 Samples
70 );
71 }
72 }
73 if (IsEffectActive(i)) pCurrentEffect->RenderAudio(Samples);
74 else { //TODO: lazy, suboptimal implementation of inactive, bypassed effects
75 for (int iChan = 0; iChan < pCurrentEffect->OutputChannelCount() && iChan < pCurrentEffect->InputChannelCount(); ++iChan) {
76 pCurrentEffect->InputChannel(iChan)->MixTo(
77 pCurrentEffect->OutputChannel(iChan),
78 Samples
79 );
80 }
81 }
82 }
83 }
84
85 Effect* EffectChain::GetEffect(int iChainPos) const {
86 if (iChainPos < 0 || iChainPos >= vEntries.size()) return NULL;
87 return vEntries[iChainPos].pEffect;
88 }
89
90 int EffectChain::EffectCount() const {
91 return vEntries.size();
92 }
93
94 void EffectChain::SetEffectActive(int iChainPos, bool bOn) throw (Exception) {
95 if (iChainPos < 0 || iChainPos >= vEntries.size())
96 throw Exception(
97 "Cannot change active state of effect at chain position " +
98 ToString(iChainPos) + ", index out of bounds."
99 );
100 vEntries[iChainPos].bActive = bOn;
101 }
102
103 bool EffectChain::IsEffectActive(int iChainPos) const {
104 if (iChainPos < 0 || iChainPos >= vEntries.size()) return false;
105 return vEntries[iChainPos].bActive;
106 }
107
108 void EffectChain::ClearAllChannels() {
109 for (int iEffect = 0; iEffect < vEntries.size(); ++iEffect) {
110 Effect* pEffect = vEntries[iEffect].pEffect;
111 for (int i = 0; i < pEffect->InputChannelCount(); ++i)
112 pEffect->InputChannel(i)->Clear(); // zero out buffers
113 for (int i = 0; i < pEffect->OutputChannelCount(); ++i)
114 pEffect->OutputChannel(i)->Clear(); // zero out buffers
115 }
116 }
117
118 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC