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