1 |
schoenebeck |
1667 |
// qsamplerFxSend.cpp |
2 |
|
|
// |
3 |
|
|
/**************************************************************************** |
4 |
|
|
Copyright (C) 2008, Christian Schoenebeck |
5 |
|
|
|
6 |
|
|
This program is free software; you can redistribute it and/or |
7 |
|
|
modify it under the terms of the GNU General Public License |
8 |
|
|
as published by the Free Software Foundation; either version 2 |
9 |
|
|
of the License, or (at your option) any later version. |
10 |
|
|
|
11 |
|
|
This program is distributed in the hope that it will be useful, |
12 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
|
|
GNU General Public License for more details. |
15 |
|
|
|
16 |
|
|
You should have received a copy of the GNU General Public License along |
17 |
|
|
with this program; if not, write to the Free Software Foundation, Inc., |
18 |
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 |
|
|
|
20 |
|
|
*****************************************************************************/ |
21 |
|
|
|
22 |
|
|
#include "qsamplerAbout.h" |
23 |
|
|
#include "qsamplerFxSend.h" |
24 |
|
|
#include "qsamplerUtilities.h" |
25 |
|
|
#include "qsamplerOptions.h" |
26 |
|
|
#include "qsamplerMainForm.h" |
27 |
|
|
|
28 |
|
|
namespace QSampler { |
29 |
|
|
|
30 |
|
|
// marks FxSend objects which don't exist on sampler side yet |
31 |
|
|
#define NEW_FX_SEND -1 |
32 |
|
|
|
33 |
|
|
FxSend::FxSend(int SamplerChannelID, int FxSendID) : |
34 |
|
|
m_iSamplerChannelID(SamplerChannelID), |
35 |
|
|
m_iFxSendID(FxSendID), m_bDelete(false), m_bModified(false) |
36 |
|
|
{ |
37 |
|
|
m_MidiCtrl = 91; |
38 |
|
|
m_Depth = 0.0f; |
39 |
|
|
} |
40 |
|
|
|
41 |
|
|
FxSend::FxSend(int SamplerChannelID) : |
42 |
|
|
m_iSamplerChannelID(SamplerChannelID), |
43 |
|
|
m_iFxSendID(NEW_FX_SEND), m_bDelete(false), m_bModified(true) |
44 |
|
|
{ |
45 |
|
|
m_MidiCtrl = 91; |
46 |
|
|
m_Depth = 0.0f; |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
FxSend::~FxSend() { |
50 |
|
|
} |
51 |
|
|
|
52 |
|
|
int FxSend::id() const { |
53 |
|
|
return m_iFxSendID; |
54 |
|
|
} |
55 |
|
|
|
56 |
|
|
bool FxSend::isNew() const { |
57 |
|
|
return m_iFxSendID == NEW_FX_SEND; |
58 |
|
|
} |
59 |
|
|
|
60 |
|
|
void FxSend::setDeletion(bool bDelete) { |
61 |
|
|
m_bDelete = bDelete; |
62 |
|
|
m_bModified = true; |
63 |
|
|
} |
64 |
|
|
|
65 |
|
|
bool FxSend::deletion() const { |
66 |
|
|
return m_bDelete; |
67 |
|
|
} |
68 |
|
|
|
69 |
|
|
void FxSend::setName(const QString& sName) { |
70 |
|
|
m_FxSendName = sName; |
71 |
|
|
m_bModified = true; |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
bool FxSend::isModified() const { |
75 |
|
|
return m_bModified; |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
const QString& FxSend::name() const { |
79 |
|
|
return m_FxSendName; |
80 |
|
|
} |
81 |
|
|
|
82 |
|
|
void FxSend::setSendDepthMidiCtrl(int iMidiController) { |
83 |
|
|
m_MidiCtrl = iMidiController; |
84 |
|
|
m_bModified = true; |
85 |
|
|
} |
86 |
|
|
|
87 |
|
|
int FxSend::sendDepthMidiCtrl() const { |
88 |
|
|
return m_MidiCtrl; |
89 |
|
|
} |
90 |
|
|
|
91 |
|
|
void FxSend::setCurrentDepth(float depth) { |
92 |
|
|
m_Depth = depth; |
93 |
|
|
m_bModified = true; |
94 |
|
|
} |
95 |
|
|
|
96 |
|
|
float FxSend::currentDepth() const { |
97 |
|
|
return m_Depth; |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
int FxSend::audioChannel(int iAudioSrc) const { |
101 |
|
|
if (iAudioSrc < 0 || iAudioSrc >= m_AudioRouting.size()) |
102 |
|
|
return -1; |
103 |
|
|
|
104 |
|
|
return m_AudioRouting[iAudioSrc]; |
105 |
|
|
} |
106 |
|
|
|
107 |
|
|
bool FxSend::setAudioChannel(int iAudioSrc, int iAudioDst) { |
108 |
|
|
if (iAudioSrc < 0 || iAudioSrc >= m_AudioRouting.size()) |
109 |
|
|
return false; |
110 |
|
|
|
111 |
|
|
m_AudioRouting[iAudioSrc] = iAudioDst; |
112 |
|
|
m_bModified = true; |
113 |
|
|
|
114 |
|
|
return true; |
115 |
|
|
} |
116 |
|
|
|
117 |
|
|
const FxSendRoutingMap& FxSend::audioRouting() const { |
118 |
|
|
return m_AudioRouting; |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
bool FxSend::getFromSampler() { |
122 |
|
|
#if CONFIG_FXSEND |
123 |
|
|
m_bModified = false; |
124 |
|
|
|
125 |
|
|
// in case this is a new, actually not yet existing FX send, ignore update |
126 |
|
|
if (isNew()) |
127 |
|
|
return true; |
128 |
|
|
|
129 |
|
|
MainForm *pMainForm = MainForm::getInstance(); |
130 |
|
|
if (!pMainForm || !pMainForm->client()) |
131 |
|
|
return false; |
132 |
|
|
|
133 |
|
|
lscp_fxsend_info_t* pFxSendInfo = |
134 |
|
|
::lscp_get_fxsend_info( |
135 |
|
|
pMainForm->client(), |
136 |
|
|
m_iSamplerChannelID, |
137 |
|
|
m_iFxSendID); |
138 |
|
|
|
139 |
|
|
if (!pFxSendInfo) { |
140 |
|
|
pMainForm->appendMessagesClient("lscp_get_fxsend_info"); |
141 |
|
|
return false; |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
m_FxSendName = qsamplerUtilities::lscpEscapedTextToRaw(pFxSendInfo->name); |
145 |
|
|
m_MidiCtrl = pFxSendInfo->midi_controller; |
146 |
|
|
m_Depth = pFxSendInfo->level; |
147 |
|
|
|
148 |
|
|
m_AudioRouting.clear(); |
149 |
|
|
if (pFxSendInfo->audio_routing) |
150 |
|
|
for (int i = 0; pFxSendInfo->audio_routing[i]; ++i) |
151 |
|
|
m_AudioRouting[i] = pFxSendInfo->audio_routing[i]; |
152 |
|
|
|
153 |
|
|
return true; |
154 |
|
|
#else // CONFIG_FXSEND |
155 |
|
|
return false; |
156 |
|
|
#endif // CONFIG_FXSEND |
157 |
|
|
} |
158 |
|
|
|
159 |
|
|
bool FxSend::applyToSampler() { |
160 |
|
|
#if CONFIG_FXSEND |
161 |
|
|
MainForm *pMainForm = MainForm::getInstance(); |
162 |
|
|
if (!pMainForm || !pMainForm->client()) |
163 |
|
|
return false; |
164 |
|
|
|
165 |
|
|
// in case FX send doesn't exist on sampler side yet, create it |
166 |
|
|
if (isNew()) { |
167 |
|
|
// doesn't exist and scheduled for deletion? nothing to do |
168 |
|
|
if (deletion()) { |
169 |
|
|
m_bModified = false; |
170 |
|
|
return true; |
171 |
|
|
} |
172 |
|
|
|
173 |
|
|
int result = |
174 |
|
|
::lscp_create_fxsend( |
175 |
|
|
pMainForm->client(), |
176 |
|
|
m_iSamplerChannelID, |
177 |
|
|
m_MidiCtrl, NULL |
178 |
|
|
); |
179 |
|
|
if (result == -1) { |
180 |
|
|
pMainForm->appendMessagesClient("lscp_create_fxsend"); |
181 |
|
|
return false; |
182 |
|
|
} |
183 |
|
|
m_iFxSendID = result; |
184 |
|
|
} |
185 |
|
|
|
186 |
|
|
lscp_status_t result; |
187 |
|
|
|
188 |
|
|
// delete FX send on sampler side |
189 |
|
|
if (deletion()) { |
190 |
|
|
result = |
191 |
|
|
::lscp_destroy_fxsend( |
192 |
|
|
pMainForm->client(), m_iSamplerChannelID, m_iFxSendID |
193 |
|
|
); |
194 |
|
|
if (result != LSCP_OK) { |
195 |
|
|
pMainForm->appendMessagesClient("lscp_destroy_fxsend"); |
196 |
|
|
return false; |
197 |
|
|
} |
198 |
|
|
m_bModified = false; |
199 |
|
|
return true; |
200 |
|
|
} |
201 |
|
|
|
202 |
|
|
// set FX send depth MIDI controller |
203 |
|
|
result = |
204 |
|
|
::lscp_set_fxsend_midi_controller( |
205 |
|
|
pMainForm->client(), |
206 |
|
|
m_iSamplerChannelID, m_iFxSendID, m_MidiCtrl |
207 |
|
|
); |
208 |
|
|
if (result != LSCP_OK) { |
209 |
|
|
pMainForm->appendMessagesClient("lscp_set_fxsend_midi_controller"); |
210 |
|
|
return false; |
211 |
|
|
} |
212 |
|
|
|
213 |
|
|
#if CONFIG_FXSEND_RENAME |
214 |
|
|
// set FX send's name |
215 |
|
|
result = |
216 |
|
|
::lscp_set_fxsend_name( |
217 |
|
|
pMainForm->client(), |
218 |
|
|
m_iSamplerChannelID, m_iFxSendID, |
219 |
|
|
qsamplerUtilities::lscpEscapeText( |
220 |
|
|
m_FxSendName |
221 |
|
|
).toUtf8().constData() |
222 |
|
|
); |
223 |
|
|
if (result != LSCP_OK) { |
224 |
|
|
pMainForm->appendMessagesClient("lscp_set_fxsend_name"); |
225 |
|
|
return false; |
226 |
|
|
} |
227 |
|
|
#endif // CONFIG_FXSEND_RENAME |
228 |
|
|
|
229 |
|
|
// set FX send current send level |
230 |
|
|
result = |
231 |
|
|
::lscp_set_fxsend_level( |
232 |
|
|
pMainForm->client(), |
233 |
|
|
m_iSamplerChannelID, m_iFxSendID, m_Depth |
234 |
|
|
); |
235 |
|
|
if (result != LSCP_OK) { |
236 |
|
|
pMainForm->appendMessagesClient("lscp_set_fxsend_level"); |
237 |
|
|
return false; |
238 |
|
|
} |
239 |
|
|
|
240 |
|
|
// set FX send's audio routing |
241 |
|
|
for (int i = 0; i < m_AudioRouting.size(); ++i) { |
242 |
|
|
result = |
243 |
|
|
::lscp_set_fxsend_audio_channel( |
244 |
|
|
pMainForm->client(), m_iSamplerChannelID, m_iFxSendID, |
245 |
|
|
i, /*audio source*/ |
246 |
|
|
m_AudioRouting[i] /*audio destination*/ |
247 |
|
|
); |
248 |
|
|
if (result != LSCP_OK) { |
249 |
|
|
pMainForm->appendMessagesClient("lscp_set_fxsend_audio_channel"); |
250 |
|
|
return false; |
251 |
|
|
} |
252 |
|
|
} |
253 |
|
|
|
254 |
|
|
m_bModified = false; |
255 |
|
|
return true; |
256 |
|
|
#else // CONFIG_FXSEND |
257 |
|
|
return false; |
258 |
|
|
#endif // CONFIG_FXSEND |
259 |
|
|
} |
260 |
|
|
|
261 |
|
|
QList<int> FxSend::allFxSendsOfSamplerChannel(int samplerChannelID) { |
262 |
|
|
QList<int> sends; |
263 |
|
|
|
264 |
|
|
MainForm *pMainForm = MainForm::getInstance(); |
265 |
|
|
if (!pMainForm || !pMainForm->client()) |
266 |
|
|
return sends; |
267 |
|
|
|
268 |
|
|
#ifdef CONFIG_FXSEND |
269 |
|
|
int *piSends = ::lscp_list_fxsends(pMainForm->client(), samplerChannelID); |
270 |
|
|
if (!piSends) { |
271 |
|
|
if (::lscp_client_get_errno(pMainForm->client())) |
272 |
|
|
pMainForm->appendMessagesClient("lscp_list_fxsends"); |
273 |
|
|
} else { |
274 |
|
|
for (int iSend = 0; piSends[iSend] >= 0; ++iSend) |
275 |
|
|
sends.append(piSends[iSend]); |
276 |
|
|
} |
277 |
|
|
#endif // CONFIG_FXSEND |
278 |
|
|
|
279 |
|
|
return sends; |
280 |
|
|
} |
281 |
|
|
|
282 |
|
|
} // namespace QSampler |
283 |
|
|
|
284 |
|
|
// end of qsamplerFxSend.cpp |