1 // qsamplerInstrument.cpp
2 //
3 /****************************************************************************
4    Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5    Copyright (C) 2007, 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 "qsamplerInstrument.h"
25 #include "qsamplerUtilities.h"
26 
27 #include "qsamplerOptions.h"
28 #include "qsamplerMainForm.h"
29 
30 
31 namespace QSampler {
32 
33 //-------------------------------------------------------------------------
34 // QSampler::Instrument - MIDI instrument map structure.
35 //
36 
37 // Constructor.
Instrument(int iMap,int iBank,int iProg)38 Instrument::Instrument ( int iMap, int iBank, int iProg )
39 {
40 	m_iMap          = iMap;
41 	m_iBank         = iBank;
42 	m_iProg         = iProg;
43 	m_iInstrumentNr = 0;
44 	m_fVolume       = 1.0f;
45 	m_iLoadMode     = 0;
46 }
47 
48 // Default destructor.
~Instrument(void)49 Instrument::~Instrument (void)
50 {
51 }
52 
53 
54 // Instrument accessors.
setMap(int iMap)55 void Instrument::setMap ( int iMap )
56 {
57 	m_iMap = iMap;
58 }
59 
map(void) const60 int Instrument::map (void) const
61 {
62 	return m_iMap;
63 }
64 
65 
setBank(int iBank)66 void Instrument::setBank ( int iBank )
67 {
68 	m_iBank = iBank;
69 }
70 
bank(void) const71 int Instrument::bank (void) const
72 {
73 	return m_iBank;
74 }
75 
76 
setProg(int iProg)77 void Instrument::setProg ( int iProg )
78 {
79 	m_iProg = iProg;
80 }
81 
prog(void) const82 int Instrument::prog (void) const
83 {
84 	return m_iProg;
85 }
86 
87 
setName(const QString & sName)88 void Instrument::setName ( const QString& sName )
89 {
90 	m_sName = sName;
91 }
92 
name(void) const93 const QString& Instrument::name (void) const
94 {
95 	return m_sName;
96 }
97 
98 
setEngineName(const QString & sEngineName)99 void Instrument::setEngineName ( const QString& sEngineName )
100 {
101 	m_sEngineName = sEngineName;
102 }
103 
engineName(void) const104 const QString& Instrument::engineName (void) const
105 {
106 	return m_sEngineName;
107 }
108 
109 
setInstrumentFile(const QString & sInstrumentFile)110 void Instrument::setInstrumentFile ( const QString& sInstrumentFile )
111 {
112 	m_sInstrumentFile = sInstrumentFile;
113 }
114 
instrumentFile(void) const115 const QString& Instrument::instrumentFile (void) const
116 {
117 	return m_sInstrumentFile;
118 }
119 
120 
instrumentName(void) const121 const QString& Instrument::instrumentName (void) const
122 {
123 	return m_sInstrumentName;
124 }
125 
126 
setInstrumentNr(int iInstrumentNr)127 void Instrument::setInstrumentNr ( int iInstrumentNr )
128 {
129 	m_iInstrumentNr = iInstrumentNr;
130 }
131 
instrumentNr(void) const132 int Instrument::instrumentNr (void) const
133 {
134 	return m_iInstrumentNr;
135 }
136 
137 
setVolume(float fVolume)138 void Instrument::setVolume ( float fVolume )
139 {
140 	m_fVolume = fVolume;
141 }
142 
volume(void) const143 float Instrument::volume (void) const
144 {
145 	return m_fVolume;
146 }
147 
148 
setLoadMode(int iLoadMode)149 void Instrument::setLoadMode ( int iLoadMode )
150 {
151 	m_iLoadMode = iLoadMode;
152 }
153 
loadMode(void) const154 int Instrument::loadMode (void) const
155 {
156 	return m_iLoadMode;
157 }
158 
159 
160 // Sync methods.
mapInstrument(void)161 bool Instrument::mapInstrument (void)
162 {
163 #ifdef CONFIG_MIDI_INSTRUMENT
164 
165 	MainForm *pMainForm = MainForm::getInstance();
166 	if (pMainForm == nullptr)
167 		return false;
168 	if (pMainForm->client() == nullptr)
169 		return false;
170 
171 	if (m_iMap < 0 || m_iBank < 0 || m_iProg < 0)
172 		return false;
173 
174 	lscp_midi_instrument_t instr;
175 
176 	instr.map  = m_iMap;
177 	instr.bank = (m_iBank & 0x0fff);
178 	instr.prog = (m_iProg & 0x7f);
179 
180 	lscp_load_mode_t load_mode;
181 	switch (m_iLoadMode) {
182 		case 3:
183 			load_mode = LSCP_LOAD_PERSISTENT;
184 			break;
185 		case 2:
186 			load_mode = LSCP_LOAD_ON_DEMAND_HOLD;
187 			break;
188 		case 1:
189 			load_mode = LSCP_LOAD_ON_DEMAND;
190 			break;
191 		case 0:
192 		default:
193 			load_mode = LSCP_LOAD_DEFAULT;
194 			break;
195 	}
196 
197 	if (::lscp_map_midi_instrument(pMainForm->client(), &instr,
198 			m_sEngineName.toUtf8().constData(),
199 			qsamplerUtilities::lscpEscapePath(
200 				m_sInstrumentFile).constData(),
201 			m_iInstrumentNr, m_fVolume, load_mode,
202 			m_sName.toUtf8().constData()) != LSCP_OK) {
203 		pMainForm->appendMessagesClient("lscp_map_midi_instrument");
204 		return false;
205 	}
206 
207 	return true;
208 
209 #else
210 
211 	return false;
212 
213 #endif
214 }
215 
216 
unmapInstrument(void)217 bool Instrument::unmapInstrument (void)
218 {
219 #ifdef CONFIG_MIDI_INSTRUMENT
220 
221 	if (m_iMap < 0 || m_iBank < 0 || m_iProg < 0)
222 		return false;
223 
224 	MainForm *pMainForm = MainForm::getInstance();
225 	if (pMainForm == nullptr)
226 		return false;
227 	if (pMainForm->client() == nullptr)
228 		return false;
229 
230 	lscp_midi_instrument_t instr;
231 
232 	instr.map  = m_iMap;
233 	instr.bank = (m_iBank & 0x0fff);
234 	instr.prog = (m_iProg & 0x7f);
235 
236 	if (::lscp_unmap_midi_instrument(pMainForm->client(), &instr) != LSCP_OK) {
237 		pMainForm->appendMessagesClient("lscp_unmap_midi_instrument");
238 		return false;
239 	}
240 
241 	return true;
242 
243 #else
244 
245 	return false;
246 
247 #endif
248 }
249 
250 
getInstrument(void)251 bool Instrument::getInstrument (void)
252 {
253 #ifdef CONFIG_MIDI_INSTRUMENT
254 
255 	if (m_iMap < 0 || m_iBank < 0 || m_iProg < 0)
256 		return false;
257 
258 	MainForm *pMainForm = MainForm::getInstance();
259 	if (pMainForm == nullptr)
260 		return false;
261 	if (pMainForm->client() == nullptr)
262 		return false;
263 
264 	lscp_midi_instrument_t instr;
265 
266 	instr.map  = m_iMap;
267 	instr.bank = (m_iBank & 0x0fff);
268 	instr.prog = (m_iProg & 0x7f);
269 
270 	lscp_midi_instrument_info_t *pInstrInfo
271 		= ::lscp_get_midi_instrument_info(pMainForm->client(), &instr);
272 	if (pInstrInfo == nullptr) {
273 		pMainForm->appendMessagesClient("lscp_get_midi_instrument_info");
274 		return false;
275 	}
276 
277 	m_sName = qsamplerUtilities::lscpEscapedTextToRaw(pInstrInfo->name);
278 	m_sEngineName = pInstrInfo->engine_name;
279 	m_sInstrumentName = qsamplerUtilities::lscpEscapedTextToRaw(
280 		pInstrInfo->instrument_name);
281 	m_sInstrumentFile = qsamplerUtilities::lscpEscapedPathToPosix(
282 		pInstrInfo->instrument_file);
283 	m_iInstrumentNr = pInstrInfo->instrument_nr;
284 	m_fVolume = pInstrInfo->volume;
285 
286 	switch (pInstrInfo->load_mode) {
287 		case LSCP_LOAD_PERSISTENT:
288 			m_iLoadMode = 3;
289 			break;
290 		case LSCP_LOAD_ON_DEMAND_HOLD:
291 			m_iLoadMode = 2;
292 			break;
293 		case LSCP_LOAD_ON_DEMAND:
294 			m_iLoadMode = 1;
295 			break;
296 		case LSCP_LOAD_DEFAULT:
297 		default:
298 			m_iLoadMode = 0;
299 			break;
300 	}
301 
302 	// Fix something.
303 	if (m_sName.isEmpty())
304 		m_sName = m_sInstrumentName;
305 
306 	return true;
307 
308 #else
309 
310 	return false;
311 
312 #endif
313 }
314 
315 
316 // Instrument map name enumerator.
getMapNames(void)317 QStringList Instrument::getMapNames (void)
318 {
319 	QStringList maps;
320 
321 	MainForm *pMainForm = MainForm::getInstance();
322 	if (pMainForm == nullptr)
323 		return maps;
324 	if (pMainForm->client() == nullptr)
325 		return maps;
326 
327 #ifdef CONFIG_MIDI_INSTRUMENT
328 	int *piMaps = ::lscp_list_midi_instrument_maps(pMainForm->client());
329 	if (piMaps == nullptr) {
330 		if (::lscp_client_get_errno(pMainForm->client()))
331 			pMainForm->appendMessagesClient("lscp_list_midi_instruments");
332 	} else {
333 		for (int iMap = 0; piMaps[iMap] >= 0; iMap++) {
334 			const QString& sMapName = getMapName(piMaps[iMap]);
335 			if (!sMapName.isEmpty())
336 				maps.append(sMapName);
337 		}
338 	}
339 #endif
340 
341 	return maps;
342 }
343 
344 // Instrument map name enumerator.
getMapName(int iMidiMap)345 QString Instrument::getMapName ( int iMidiMap )
346 {
347 	QString sMapName;
348 
349 	MainForm *pMainForm = MainForm::getInstance();
350 	if (pMainForm == nullptr)
351 		return sMapName;
352 	if (pMainForm->client() == nullptr)
353 		return sMapName;
354 
355 #ifdef CONFIG_MIDI_INSTRUMENT
356 	const char *pszMapName
357 		= ::lscp_get_midi_instrument_map_name(pMainForm->client(), iMidiMap);
358 	if (pszMapName == nullptr) {
359 		pszMapName = " -";
360 		if (::lscp_client_get_errno(pMainForm->client()))
361 			pMainForm->appendMessagesClient("lscp_get_midi_instrument_name");
362 	}
363 	sMapName = QString("%1 - %2").arg(iMidiMap)
364 		.arg(qsamplerUtilities::lscpEscapedTextToRaw(pszMapName));
365 #endif
366 
367 	return sMapName;
368 }
369 
370 } // namespace QSampler
371 
372 // end of qsamplerInstrument.cpp
373