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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 519 - (show annotations) (download)
Sun May 8 17:04:10 2005 UTC (14 years, 10 months ago) by schoenebeck
File size: 17190 byte(s)
* Show appropriate message in channel strip while loading an instrument.
* Show libgig version in About box (in case libgig is used).

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

  ViewVC Help
Powered by ViewVC