/[svn]/qsampler/trunk/src/qsamplerChannel.cpp
ViewVC logotype

Contents of /qsampler/trunk/src/qsamplerChannel.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 400 - (show annotations) (download)
Mon Feb 21 15:02:58 2005 UTC (19 years, 1 month ago) by capela
File size: 16458 byte(s)
Major internal switch regarding channel strip change management.

1 // qsamplerChannel.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2003-2005, rncbc aka Rui Nuno Capela. All rights reserved.
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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 *****************************************************************************/
21
22 #include "qsamplerChannel.h"
23
24 #include "qsamplerMainForm.h"
25 #include "qsamplerChannelForm.h"
26
27 #include "config.h"
28
29 #include <qfileinfo.h>
30
31 #ifdef CONFIG_LIBGIG
32 #include "gig.h"
33 #endif
34
35 #define QSAMPLER_INSTRUMENT_MAX 8
36
37
38 //-------------------------------------------------------------------------
39 // qsamplerChannel - Sampler channel structure.
40 //
41
42 // Constructor.
43 qsamplerChannel::qsamplerChannel ( qsamplerMainForm *pMainForm, int iChannelID )
44 {
45 m_pMainForm = pMainForm;
46 m_iChannelID = iChannelID;
47
48 // m_sEngineName = noEngineName();
49 // m_sInstrumentName = noInstrumentName();
50 // m_sInstrumentFile = m_sInstrumentName;
51 m_iInstrumentNr = -1;
52 m_iInstrumentStatus = -1;
53 m_sMidiDriver = "Alsa"; // DEPRECATED.
54 m_iMidiDevice = -1;
55 m_iMidiPort = -1;
56 m_iMidiChannel = -1;
57 m_sAudioDriver = "Alsa"; // DEPRECATED.
58 m_iAudioDevice = -1;
59 m_fVolume = 0.0;
60
61 }
62
63 // Default destructor.
64 qsamplerChannel::~qsamplerChannel (void)
65 {
66 }
67
68
69 // The global options settings delegated property.
70 qsamplerOptions *qsamplerChannel::options (void)
71 {
72 if (m_pMainForm == NULL)
73 return NULL;
74
75 return m_pMainForm->options();
76 }
77
78
79 // The client descriptor delegated property.
80 lscp_client_t *qsamplerChannel::client (void)
81 {
82 if (m_pMainForm == NULL)
83 return NULL;
84
85 return m_pMainForm->client();
86 }
87
88
89 // Create a new sampler channel, if not already.
90 bool qsamplerChannel::addChannel (void)
91 {
92 if (client() == NULL)
93 return false;
94
95 // Are we a new channel?
96 if (m_iChannelID < 0) {
97 m_iChannelID = ::lscp_add_channel(client());
98 if (m_iChannelID < 0) {
99 appendMessagesClient("lscp_add_channel");
100 appendMessagesError(QObject::tr("Could not create the new channel.\n\nSorry."));
101 } // Otherwise it's created...
102 else appendMessages(QObject::tr("Channel %1 created.").arg(m_iChannelID));
103 }
104
105 // Return whether we're a valid channel...
106 return (m_iChannelID >= 0);
107 }
108
109
110 // Remove sampler channel.
111 bool qsamplerChannel::removeChannel (void)
112 {
113 if (client() == NULL)
114 return false;
115
116 // Are we an existing channel?
117 if (m_iChannelID >= 0) {
118 if (::lscp_remove_channel(client(), m_iChannelID) != LSCP_OK) {
119 appendMessagesClient("lscp_remove_channel");
120 appendMessagesError(QObject::tr("Could not remove channel.\n\nSorry."));
121 } else {
122 // Otherwise it's removed.
123 appendMessages(QObject::tr("Channel %1 removed.").arg(m_iChannelID));
124 m_iChannelID = -1;
125 }
126 }
127
128 // Return whether we've removed the channel...
129 return (m_iChannelID < 0);
130 }
131
132
133 // Channel-ID (aka Sammpler-Channel) accessors.
134 int qsamplerChannel::channelID (void)
135 {
136 return m_iChannelID;
137 }
138
139 void qsamplerChannel::setChannelID ( int iChannelID )
140 {
141 m_iChannelID = iChannelID;
142 }
143
144
145 // Readable channel name.
146 QString qsamplerChannel::channelName (void)
147 {
148 return (m_iChannelID < 0 ? QObject::tr("New Channel") : QObject::tr("Channel %1").arg(m_iChannelID));
149 }
150
151
152 // Engine name accessors.
153 QString& qsamplerChannel::engineName (void)
154 {
155 return m_sEngineName;
156 }
157
158 bool qsamplerChannel::loadEngine ( const QString& sEngineName )
159 {
160 if (client() == NULL || m_iChannelID < 0)
161 return false;
162 if (m_iInstrumentStatus == 100 && m_sEngineName == sEngineName)
163 return true;
164
165 if (::lscp_load_engine(client(), sEngineName.latin1(), m_iChannelID) != LSCP_OK) {
166 appendMessagesClient("lscp_load_engine");
167 return false;
168 }
169
170 m_sEngineName = sEngineName;
171 return true;
172 }
173
174
175 // Instrument filename accessor.
176 QString& qsamplerChannel::instrumentFile (void)
177 {
178 return m_sInstrumentFile;
179 }
180
181 // Instrument index accessor.
182 int qsamplerChannel::instrumentNr (void)
183 {
184 return m_iInstrumentNr;
185 }
186
187 // Instrument name accessor.
188 QString& qsamplerChannel::instrumentName (void)
189 {
190 return m_sInstrumentName;
191 }
192
193 // Instrument status accessor.
194 int qsamplerChannel::instrumentStatus (void)
195 {
196 return m_iInstrumentStatus;
197 }
198
199 // Instrument file loader.
200 bool qsamplerChannel::loadInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
201 {
202 if (client() == NULL || m_iChannelID < 0)
203 return false;
204 if (!isInstrumentFile(sInstrumentFile))
205 return false;
206 if (m_iInstrumentStatus == 100 && m_sInstrumentFile == sInstrumentFile && m_iInstrumentNr == iInstrumentNr)
207 return true;
208
209 if (::lscp_load_instrument_non_modal(client(), sInstrumentFile.latin1(), iInstrumentNr, m_iChannelID) != LSCP_OK) {
210 appendMessagesClient("lscp_load_instrument");
211 return false;
212 }
213
214 return setInstrument(sInstrumentFile, iInstrumentNr);
215 }
216
217
218 // Special instrument file/name/number settler.
219 bool qsamplerChannel::setInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
220 {
221 m_sInstrumentFile = sInstrumentFile;
222 m_iInstrumentNr = iInstrumentNr;
223 #ifdef CONFIG_INSTRUMENT_NAME
224 m_sInstrumentName = QString::null; // We'll get it, maybe later, on channel_info...
225 #else
226 m_sInstrumentName = getInstrumentName(sInstrumentFile, iInstrumentNr, true);
227 #endif
228 m_iInstrumentStatus = 0;
229
230 return true;
231 }
232
233
234 // MIDI driver type accessors (DEPRECATED).
235 QString& qsamplerChannel::midiDriver (void)
236 {
237 return m_sMidiDriver;
238 }
239
240 bool qsamplerChannel::setMidiDriver ( const QString& sMidiDriver )
241 {
242 if (client() == NULL || m_iChannelID < 0)
243 return false;
244 if (m_iInstrumentStatus == 100 && m_sMidiDriver == sMidiDriver)
245 return true;
246
247 if (::lscp_set_channel_midi_type(client(), m_iChannelID, sMidiDriver.latin1()) != LSCP_OK) {
248 appendMessagesClient("lscp_set_channel_midi_type");
249 return false;
250 }
251
252 m_sMidiDriver = sMidiDriver;
253 return true;
254 }
255
256
257 // MIDI device accessors.
258 int qsamplerChannel::midiDevice (void)
259 {
260 return m_iMidiDevice;
261 }
262
263 bool qsamplerChannel::setMidiDevice ( int iMidiDevice )
264 {
265 if (client() == NULL || m_iChannelID < 0)
266 return false;
267 if (m_iInstrumentStatus == 100 && m_iMidiDevice == iMidiDevice)
268 return true;
269
270 if (::lscp_set_channel_midi_device(client(), m_iChannelID, iMidiDevice) != LSCP_OK) {
271 appendMessagesClient("lscp_set_channel_midi_device");
272 return false;
273 }
274
275 m_iMidiDevice = iMidiDevice;
276 return true;
277 }
278
279
280 // MIDI port number accessor.
281 int qsamplerChannel::midiPort (void)
282 {
283 return m_iMidiPort;
284 }
285
286 bool qsamplerChannel::setMidiPort ( int iMidiPort )
287 {
288 if (client() == NULL || m_iChannelID < 0)
289 return false;
290 if (m_iInstrumentStatus == 100 && m_iMidiPort == iMidiPort)
291 return true;
292
293 if (::lscp_set_channel_midi_port(client(), m_iChannelID, iMidiPort) != LSCP_OK) {
294 appendMessagesClient("lscp_set_channel_midi_port");
295 return false;
296 }
297
298 m_iMidiPort = iMidiPort;
299 return true;
300 }
301
302
303 // MIDI channel accessor.
304 int qsamplerChannel::midiChannel (void)
305 {
306 return m_iMidiChannel;
307 }
308
309 bool qsamplerChannel::setMidiChannel ( int iMidiChannel )
310 {
311 if (client() == NULL || m_iChannelID < 0)
312 return false;
313 if (m_iInstrumentStatus == 100 && m_iMidiChannel == iMidiChannel)
314 return true;
315
316 if (::lscp_set_channel_midi_channel(client(), m_iChannelID, iMidiChannel) != LSCP_OK) {
317 appendMessagesClient("lscp_set_channel_midi_channel");
318 return false;
319 }
320
321 m_iMidiChannel = iMidiChannel;
322 return true;
323 }
324
325
326 // Audio device accessor.
327 int qsamplerChannel::audioDevice (void)
328 {
329 return m_iAudioDevice;
330 }
331
332 bool qsamplerChannel::setAudioDevice ( int iAudioDevice )
333 {
334 if (client() == NULL || m_iChannelID < 0)
335 return false;
336 if (m_iInstrumentStatus == 100 && m_iAudioDevice == iAudioDevice)
337 return true;
338
339 if (::lscp_set_channel_audio_device(client(), m_iChannelID, iAudioDevice) != LSCP_OK) {
340 appendMessagesClient("lscp_set_channel_audio_device");
341 return false;
342 }
343
344 m_iAudioDevice = iAudioDevice;
345 return true;
346 }
347
348
349 // Audio driver type accessors (DEPRECATED).
350 QString& qsamplerChannel::audioDriver (void)
351 {
352 return m_sAudioDriver;
353 }
354
355 bool qsamplerChannel::setAudioDriver ( const QString& sAudioDriver )
356 {
357 if (client() == NULL || m_iChannelID < 0)
358 return false;
359 if (m_iInstrumentStatus == 100 && m_sAudioDriver == sAudioDriver)
360 return true;
361
362 if (::lscp_set_channel_audio_type(client(), m_iChannelID, sAudioDriver.latin1()) != LSCP_OK) {
363 appendMessagesClient("lscp_set_channel_audio_type");
364 return false;
365 }
366
367 m_sAudioDriver = sAudioDriver;
368 return true;
369 }
370
371
372 // Channel volume accessors.
373 float qsamplerChannel::volume (void)
374 {
375 return m_fVolume;
376 }
377
378 bool qsamplerChannel::setVolume ( float fVolume )
379 {
380 if (client() == NULL || m_iChannelID < 0)
381 return false;
382 if (m_iInstrumentStatus == 100 && m_fVolume == fVolume)
383 return true;
384
385 if (::lscp_set_channel_volume(client(), m_iChannelID, fVolume) != LSCP_OK) {
386 appendMessagesClient("lscp_set_channel_volume");
387 return false;
388 }
389
390 m_fVolume = fVolume;
391 return true;
392 }
393
394
395 // Istrument name remapper.
396 void qsamplerChannel::updateInstrumentName (void)
397 {
398 #ifndef CONFIG_INSTRUMENT_NAME
399 m_sInstrumentName = getInstrumentName(m_sInstrumentFile,
400 m_iInstrumentNr, (options() && options()->bInstrumentNames));
401 #endif
402 }
403
404
405 // Update whole channel info state.
406 bool qsamplerChannel::updateChannelInfo (void)
407 {
408 if (client() == NULL || m_iChannelID < 0)
409 return false;
410
411 // Read channel information.
412 lscp_channel_info_t *pChannelInfo = ::lscp_get_channel_info(client(), m_iChannelID);
413 if (pChannelInfo == NULL) {
414 appendMessagesClient("lscp_get_channel_info");
415 appendMessagesError(QObject::tr("Could not get channel information.\n\nSorry."));
416 return false;
417 }
418
419 #ifdef CONFIG_INSTRUMENT_NAME
420 // We got all actual instrument datum...
421 m_sInstrumentFile = pChannelInfo->instrument_file;
422 m_iInstrumentNr = pChannelInfo->instrument_nr;
423 m_sInstrumentName = pChannelInfo->instrument_name;
424 #else
425 // First, check if intrument name has changed,
426 // taking care that instrument name lookup might be expensive,
427 // so we better make it only once and when really needed...
428 if ((m_sInstrumentFile != pChannelInfo->instrument_file) ||
429 (m_iInstrumentNr != pChannelInfo->instrument_nr)) {
430 m_sInstrumentFile = pChannelInfo->instrument_file;
431 m_iInstrumentNr = pChannelInfo->instrument_nr;
432 updateInstrumentName();
433 }
434 #endif
435 // Cache in other channel information.
436 m_sEngineName = pChannelInfo->engine_name;
437 m_iInstrumentStatus = pChannelInfo->instrument_status;
438 m_iMidiDevice = pChannelInfo->midi_device;
439 m_iMidiPort = pChannelInfo->midi_port;
440 m_iMidiChannel = pChannelInfo->midi_channel;
441 m_iAudioDevice = pChannelInfo->audio_device;
442 m_fVolume = pChannelInfo->volume;
443 // Some sanity checks.
444 if (m_sEngineName == "NONE")
445 m_sEngineName = QString::null;
446 if (m_sInstrumentFile == "NONE") {
447 m_sInstrumentFile = QString::null;
448 m_sInstrumentName = QString::null;
449 }
450
451 return true;
452 }
453
454
455 // Reset channel method.
456 bool qsamplerChannel::channelReset (void)
457 {
458 if (client() == NULL || m_iChannelID < 0)
459 return false;
460
461 if (::lscp_reset_channel(client(), m_iChannelID) != LSCP_OK) {
462 appendMessagesClient("lscp_reset_channel");
463 return false;
464 }
465
466 appendMessages(QObject::tr("Channel %1 reset.").arg(m_iChannelID));
467 return true;
468 }
469
470
471 // Channel setup dialog form.
472 bool qsamplerChannel::channelSetup ( QWidget *pParent )
473 {
474 bool bResult = false;
475
476 qsamplerChannelForm *pChannelForm = new qsamplerChannelForm(pParent);
477 if (pChannelForm) {
478 pChannelForm->setup(this);
479 bResult = pChannelForm->exec();
480 delete pChannelForm;
481 }
482
483 return bResult;
484 }
485
486
487 // Redirected messages output methods.
488 void qsamplerChannel::appendMessages( const QString& s )
489 {
490 if (m_pMainForm) m_pMainForm->appendMessages(s);
491 }
492
493 void qsamplerChannel::appendMessagesColor( const QString& s, const QString& c )
494 {
495 if (m_pMainForm) m_pMainForm->appendMessagesColor(s, c);
496 }
497
498 void qsamplerChannel::appendMessagesText( const QString& s )
499 {
500 if (m_pMainForm) m_pMainForm->appendMessagesText(s);
501 }
502
503 void qsamplerChannel::appendMessagesError( const QString& s )
504 {
505 if (m_pMainForm) m_pMainForm->appendMessagesError(s);
506 }
507
508 void qsamplerChannel::appendMessagesClient( const QString& s )
509 {
510 if (m_pMainForm) m_pMainForm->appendMessagesClient(s);
511 }
512
513
514 // Context menu event handler.
515 void qsamplerChannel::contextMenuEvent( QContextMenuEvent *pEvent )
516 {
517 if (m_pMainForm) m_pMainForm->contextMenuEvent(pEvent);
518 }
519
520
521 // FIXME: Check whether a given file is an instrument file.
522 bool qsamplerChannel::isInstrumentFile ( const QString& sInstrumentFile )
523 {
524 bool bResult = false;
525
526 QFile file(sInstrumentFile);
527 if (file.open(IO_ReadOnly)) {
528 char achHeader[4];
529 if (file.readBlock(achHeader, 4)) {
530 bResult = (achHeader[0] == 'R'
531 && achHeader[1] == 'I'
532 && achHeader[2] == 'F'
533 && achHeader[3] == 'F');
534 }
535 file.close();
536 }
537
538 return bResult;
539 }
540
541
542 // Retrieve the instrument list of a instrument file (.gig).
543 QStringList qsamplerChannel::getInstrumentList( const QString& sInstrumentFile,
544 bool bInstrumentNames )
545 {
546 QString sInstrumentName = QFileInfo(sInstrumentFile).fileName();
547 QStringList instlist;
548
549 if (isInstrumentFile(sInstrumentFile)) {
550 #ifdef CONFIG_LIBGIG
551 if (bInstrumentNames) {
552 RIFF::File *pRiff = new RIFF::File(sInstrumentFile);
553 gig::File *pGig = new gig::File(pRiff);
554 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
555 while (pInstrument) {
556 instlist.append((pInstrument->pInfo)->Name.c_str());
557 pInstrument = pGig->GetNextInstrument();
558 }
559 delete pGig;
560 delete pRiff;
561 }
562 else
563 #endif
564 for (int iInstrumentNr = 0; iInstrumentNr < QSAMPLER_INSTRUMENT_MAX; iInstrumentNr++)
565 instlist.append(sInstrumentName + " [" + QString::number(iInstrumentNr) + "]");
566 }
567 else instlist.append(noInstrumentName());
568
569 return instlist;
570 }
571
572
573 // Retrieve the spacific instrument name of a instrument file (.gig), given its index.
574 QString qsamplerChannel::getInstrumentName( const QString& sInstrumentFile,
575 int iInstrumentNr, bool bInstrumentNames )
576 {
577 QString sInstrumentName;
578
579 if (isInstrumentFile(sInstrumentFile)) {
580 sInstrumentName = QFileInfo(sInstrumentFile).fileName();
581 #ifdef CONFIG_LIBGIG
582 if (bInstrumentNames) {
583 RIFF::File *pRiff = new RIFF::File(sInstrumentFile);
584 gig::File *pGig = new gig::File(pRiff);
585 int iIndex = 0;
586 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
587 while (pInstrument) {
588 if (iIndex == iInstrumentNr) {
589 sInstrumentName = (pInstrument->pInfo)->Name.c_str();
590 break;
591 }
592 iIndex++;
593 pInstrument = pGig->GetNextInstrument();
594 }
595 delete pGig;
596 delete pRiff;
597 }
598 else
599 #endif
600 sInstrumentName += " [" + QString::number(iInstrumentNr) + "]";
601 }
602 else sInstrumentName = noInstrumentName();
603
604 return sInstrumentName;
605 }
606
607
608 // Common invalid name-helpers.
609 QString qsamplerChannel::noEngineName (void)
610 {
611 return QObject::tr("(No engine)");
612 }
613
614 QString qsamplerChannel::noInstrumentName (void)
615 {
616 return QObject::tr("(No instrument)");
617 }
618
619
620 // end of qsamplerChannel.cpp

  ViewVC Help
Powered by ViewVC