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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 824 - (show annotations) (download)
Fri Dec 23 01:40:56 2005 UTC (18 years, 3 months ago) by capela
File size: 23990 byte(s)
* Whenever the listing of actual instrument names is not an
  option (e.g. due to lack of libgig support), the whole
  number of selectable Instrument items is now being graciously
  increased from just the bare 8 (eight) right up through 100
  (one hundred), on the sampler channel setup dialog.

* The selection buttons, on the right of the Instrument, Audio
  and MIDI devices combo-boxes, on the sampler channel dialog,
  are now expected to be a little better looking than it was
  before, at least for those Mac OS X eyes.

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 "qsamplerAbout.h"
23 #include "qsamplerChannel.h"
24
25 #include "qsamplerMainForm.h"
26 #include "qsamplerChannelForm.h"
27
28 #include <qfileinfo.h>
29 #include <qcombobox.h>
30
31 #ifdef CONFIG_LIBGIG
32 #include "gig.h"
33 #endif
34
35 #define QSAMPLER_INSTRUMENT_MAX 100
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 m_bMute = false;
61 m_bSolo = false;
62 }
63
64 // Default destructor.
65 qsamplerChannel::~qsamplerChannel (void)
66 {
67 }
68
69
70 // Main application form accessor.
71 qsamplerMainForm *qsamplerChannel::mainForm(void) const
72 {
73 return m_pMainForm;
74 }
75
76
77 // The global options settings delegated property.
78 qsamplerOptions *qsamplerChannel::options (void) const
79 {
80 if (m_pMainForm == NULL)
81 return NULL;
82
83 return m_pMainForm->options();
84 }
85
86
87 // The client descriptor delegated property.
88 lscp_client_t *qsamplerChannel::client (void) const
89 {
90 if (m_pMainForm == NULL)
91 return NULL;
92
93 return m_pMainForm->client();
94 }
95
96
97 // Create a new sampler channel, if not already.
98 bool qsamplerChannel::addChannel (void)
99 {
100 if (client() == NULL)
101 return false;
102
103 // Are we a new channel?
104 if (m_iChannelID < 0) {
105 m_iChannelID = ::lscp_add_channel(client());
106 if (m_iChannelID < 0) {
107 appendMessagesClient("lscp_add_channel");
108 appendMessagesError(QObject::tr("Could not add channel.\n\nSorry."));
109 } // Otherwise it's created...
110 else appendMessages(QObject::tr("added."));
111 }
112
113 // Return whether we're a valid channel...
114 return (m_iChannelID >= 0);
115 }
116
117
118 // Remove sampler channel.
119 bool qsamplerChannel::removeChannel (void)
120 {
121 if (client() == NULL)
122 return false;
123
124 // Are we an existing channel?
125 if (m_iChannelID >= 0) {
126 if (::lscp_remove_channel(client(), m_iChannelID) != LSCP_OK) {
127 appendMessagesClient("lscp_remove_channel");
128 appendMessagesError(QObject::tr("Could not remove channel.\n\nSorry."));
129 } else {
130 // Otherwise it's removed.
131 appendMessages(QObject::tr("removed."));
132 m_iChannelID = -1;
133 }
134 }
135
136 // Return whether we've removed the channel...
137 return (m_iChannelID < 0);
138 }
139
140
141 // Channel-ID (aka Sammpler-Channel) accessors.
142 int qsamplerChannel::channelID (void) const
143 {
144 return m_iChannelID;
145 }
146
147 void qsamplerChannel::setChannelID ( int iChannelID )
148 {
149 m_iChannelID = iChannelID;
150 }
151
152
153 // Readable channel name.
154 QString qsamplerChannel::channelName (void) const
155 {
156 return (m_iChannelID < 0 ? QObject::tr("New Channel") : QObject::tr("Channel %1").arg(m_iChannelID));
157 }
158
159
160 // Engine name accessors.
161 const QString& qsamplerChannel::engineName (void) const
162 {
163 return m_sEngineName;
164 }
165
166 bool qsamplerChannel::loadEngine ( const QString& sEngineName )
167 {
168 if (client() == NULL || m_iChannelID < 0)
169 return false;
170 if (m_iInstrumentStatus == 100 && m_sEngineName == sEngineName)
171 return true;
172
173 if (::lscp_load_engine(client(), sEngineName.latin1(), m_iChannelID) != LSCP_OK) {
174 appendMessagesClient("lscp_load_engine");
175 return false;
176 }
177 appendMessages(QObject::tr("Engine: %1.").arg(sEngineName));
178
179 m_sEngineName = sEngineName;
180 return true;
181 }
182
183
184 // Instrument filename accessor.
185 const QString& qsamplerChannel::instrumentFile (void) const
186 {
187 return m_sInstrumentFile;
188 }
189
190 // Instrument index accessor.
191 int qsamplerChannel::instrumentNr (void) const
192 {
193 return m_iInstrumentNr;
194 }
195
196 // Instrument name accessor.
197 const QString& qsamplerChannel::instrumentName (void) const
198 {
199 return m_sInstrumentName;
200 }
201
202 // Instrument status accessor.
203 int qsamplerChannel::instrumentStatus (void) const
204 {
205 return m_iInstrumentStatus;
206 }
207
208 // Instrument file loader.
209 bool qsamplerChannel::loadInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
210 {
211 if (client() == NULL || m_iChannelID < 0)
212 return false;
213 if (!isInstrumentFile(sInstrumentFile))
214 return false;
215 if (m_iInstrumentStatus == 100 && m_sInstrumentFile == sInstrumentFile && m_iInstrumentNr == iInstrumentNr)
216 return true;
217
218 if (::lscp_load_instrument_non_modal(client(), sInstrumentFile.latin1(), iInstrumentNr, m_iChannelID) != LSCP_OK) {
219 appendMessagesClient("lscp_load_instrument");
220 return false;
221 }
222
223 appendMessages(QObject::tr("Instrument: \"%1\" (%2).")
224 .arg(sInstrumentFile).arg(iInstrumentNr));
225
226 return setInstrument(sInstrumentFile, iInstrumentNr);
227 }
228
229
230 // Special instrument file/name/number settler.
231 bool qsamplerChannel::setInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
232 {
233 m_sInstrumentFile = sInstrumentFile;
234 m_iInstrumentNr = iInstrumentNr;
235 #ifdef CONFIG_INSTRUMENT_NAME
236 m_sInstrumentName = QString::null; // We'll get it, maybe later, on channel_info...
237 #else
238 m_sInstrumentName = getInstrumentName(sInstrumentFile, iInstrumentNr, true);
239 #endif
240 m_iInstrumentStatus = 0;
241
242 return true;
243 }
244
245
246 // MIDI driver type accessors (DEPRECATED).
247 const QString& qsamplerChannel::midiDriver (void) const
248 {
249 return m_sMidiDriver;
250 }
251
252 bool qsamplerChannel::setMidiDriver ( const QString& sMidiDriver )
253 {
254 if (client() == NULL || m_iChannelID < 0)
255 return false;
256 if (m_iInstrumentStatus == 100 && m_sMidiDriver == sMidiDriver)
257 return true;
258
259 if (::lscp_set_channel_midi_type(client(), m_iChannelID, sMidiDriver.latin1()) != LSCP_OK) {
260 appendMessagesClient("lscp_set_channel_midi_type");
261 return false;
262 }
263
264 appendMessages(QObject::tr("MIDI driver: %1.").arg(sMidiDriver));
265
266 m_sMidiDriver = sMidiDriver;
267 return true;
268 }
269
270
271 // MIDI device accessors.
272 int qsamplerChannel::midiDevice (void) const
273 {
274 return m_iMidiDevice;
275 }
276
277 bool qsamplerChannel::setMidiDevice ( int iMidiDevice )
278 {
279 if (client() == NULL || m_iChannelID < 0)
280 return false;
281 if (m_iInstrumentStatus == 100 && m_iMidiDevice == iMidiDevice)
282 return true;
283
284 if (::lscp_set_channel_midi_device(client(), m_iChannelID, iMidiDevice) != LSCP_OK) {
285 appendMessagesClient("lscp_set_channel_midi_device");
286 return false;
287 }
288
289 appendMessages(QObject::tr("MIDI device: %1.").arg(iMidiDevice));
290
291 m_iMidiDevice = iMidiDevice;
292 return true;
293 }
294
295
296 // MIDI port number accessor.
297 int qsamplerChannel::midiPort (void) const
298 {
299 return m_iMidiPort;
300 }
301
302 bool qsamplerChannel::setMidiPort ( int iMidiPort )
303 {
304 if (client() == NULL || m_iChannelID < 0)
305 return false;
306 if (m_iInstrumentStatus == 100 && m_iMidiPort == iMidiPort)
307 return true;
308
309 if (::lscp_set_channel_midi_port(client(), m_iChannelID, iMidiPort) != LSCP_OK) {
310 appendMessagesClient("lscp_set_channel_midi_port");
311 return false;
312 }
313
314 appendMessages(QObject::tr("MIDI port: %1.").arg(iMidiPort));
315
316 m_iMidiPort = iMidiPort;
317 return true;
318 }
319
320
321 // MIDI channel accessor.
322 int qsamplerChannel::midiChannel (void) const
323 {
324 return m_iMidiChannel;
325 }
326
327 bool qsamplerChannel::setMidiChannel ( int iMidiChannel )
328 {
329 if (client() == NULL || m_iChannelID < 0)
330 return false;
331 if (m_iInstrumentStatus == 100 && m_iMidiChannel == iMidiChannel)
332 return true;
333
334 if (::lscp_set_channel_midi_channel(client(), m_iChannelID, iMidiChannel) != LSCP_OK) {
335 appendMessagesClient("lscp_set_channel_midi_channel");
336 return false;
337 }
338
339 appendMessages(QObject::tr("MIDI channel: %1.").arg(iMidiChannel));
340
341 m_iMidiChannel = iMidiChannel;
342 return true;
343 }
344
345
346 // Audio device accessor.
347 int qsamplerChannel::audioDevice (void) const
348 {
349 return m_iAudioDevice;
350 }
351
352 bool qsamplerChannel::setAudioDevice ( int iAudioDevice )
353 {
354 if (client() == NULL || m_iChannelID < 0)
355 return false;
356 if (m_iInstrumentStatus == 100 && m_iAudioDevice == iAudioDevice)
357 return true;
358
359 if (::lscp_set_channel_audio_device(client(), m_iChannelID, iAudioDevice) != LSCP_OK) {
360 appendMessagesClient("lscp_set_channel_audio_device");
361 return false;
362 }
363
364 appendMessages(QObject::tr("Audio device: %1.").arg(iAudioDevice));
365
366 m_iAudioDevice = iAudioDevice;
367 return true;
368 }
369
370
371 // Audio driver type accessors (DEPRECATED).
372 const QString& qsamplerChannel::audioDriver (void) const
373 {
374 return m_sAudioDriver;
375 }
376
377 bool qsamplerChannel::setAudioDriver ( const QString& sAudioDriver )
378 {
379 if (client() == NULL || m_iChannelID < 0)
380 return false;
381 if (m_iInstrumentStatus == 100 && m_sAudioDriver == sAudioDriver)
382 return true;
383
384 if (::lscp_set_channel_audio_type(client(), m_iChannelID, sAudioDriver.latin1()) != LSCP_OK) {
385 appendMessagesClient("lscp_set_channel_audio_type");
386 return false;
387 }
388
389 appendMessages(QObject::tr("Audio driver: %1.").arg(sAudioDriver));
390
391 m_sAudioDriver = sAudioDriver;
392 return true;
393 }
394
395
396 // Channel volume accessors.
397 float qsamplerChannel::volume (void) const
398 {
399 return m_fVolume;
400 }
401
402 bool qsamplerChannel::setVolume ( float fVolume )
403 {
404 if (client() == NULL || m_iChannelID < 0)
405 return false;
406 if (m_iInstrumentStatus == 100 && m_fVolume == fVolume)
407 return true;
408
409 if (::lscp_set_channel_volume(client(), m_iChannelID, fVolume) != LSCP_OK) {
410 appendMessagesClient("lscp_set_channel_volume");
411 return false;
412 }
413
414 appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
415
416 m_fVolume = fVolume;
417 return true;
418 }
419
420
421 // Sampler channel mute state.
422 bool qsamplerChannel::channelMute (void) const
423 {
424 return m_bMute;
425 }
426
427 bool qsamplerChannel::setChannelMute ( bool bMute )
428 {
429 if (client() == NULL || m_iChannelID < 0)
430 return false;
431 if (m_iInstrumentStatus == 100 && ((m_bMute && bMute) || (!m_bMute && !bMute)))
432 return true;
433
434 #ifdef CONFIG_MUTE_SOLO
435 if (::lscp_set_channel_mute(client(), m_iChannelID, bMute) != LSCP_OK) {
436 appendMessagesClient("lscp_set_channel_mute");
437 return false;
438 }
439 appendMessages(QObject::tr("Mute: %1.").arg((int) bMute));
440 m_bMute = bMute;
441 return true;
442 #else
443 return false;
444 #endif
445 }
446
447
448 // Sampler channel solo state.
449 bool qsamplerChannel::channelSolo (void) const
450 {
451 return m_bSolo;
452 }
453
454 bool qsamplerChannel::setChannelSolo ( bool bSolo )
455 {
456 if (client() == NULL || m_iChannelID < 0)
457 return false;
458 if (m_iInstrumentStatus == 100 && ((m_bSolo && bSolo) || (!m_bSolo && !bSolo)))
459 return true;
460
461 #ifdef CONFIG_MUTE_SOLO
462 if (::lscp_set_channel_solo(client(), m_iChannelID, bSolo) != LSCP_OK) {
463 appendMessagesClient("lscp_set_channel_solo");
464 return false;
465 }
466 appendMessages(QObject::tr("Solo: %1.").arg((int) bSolo));
467 m_bSolo = bSolo;
468 return true;
469 #else
470 return false;
471 #endif
472 }
473
474
475 // Audio routing accessors.
476 int qsamplerChannel::audioChannel ( int iAudioOut ) const
477 {
478 return m_audioRouting[iAudioOut];
479 }
480
481 bool qsamplerChannel::setAudioChannel ( int iAudioOut, int iAudioIn )
482 {
483 if (client() == NULL || m_iChannelID < 0)
484 return false;
485 if (m_iInstrumentStatus == 100 &&
486 m_audioRouting[iAudioOut] == iAudioIn)
487 return true;
488
489 if (::lscp_set_channel_audio_channel(client(),
490 m_iChannelID, iAudioOut, iAudioIn) != LSCP_OK) {
491 appendMessagesClient("lscp_set_channel_audio_channel");
492 return false;
493 }
494
495 appendMessages(QObject::tr("Audio Channel: %1 -> %2.")
496 .arg(iAudioOut).arg(iAudioIn));
497
498 m_audioRouting[iAudioOut] = iAudioIn;
499 return true;
500 }
501
502 // The audio routing map itself.
503 const qsamplerChannelRoutingMap& qsamplerChannel::audioRouting (void) const
504 {
505 return m_audioRouting;
506 }
507
508
509 // Istrument name remapper.
510 void qsamplerChannel::updateInstrumentName (void)
511 {
512 #ifndef CONFIG_INSTRUMENT_NAME
513 m_sInstrumentName = getInstrumentName(m_sInstrumentFile,
514 m_iInstrumentNr, (options() && options()->bInstrumentNames));
515 #endif
516 }
517
518
519 // Update whole channel info state.
520 bool qsamplerChannel::updateChannelInfo (void)
521 {
522 if (client() == NULL || m_iChannelID < 0)
523 return false;
524
525 // Read channel information.
526 lscp_channel_info_t *pChannelInfo = ::lscp_get_channel_info(client(), m_iChannelID);
527 if (pChannelInfo == NULL) {
528 appendMessagesClient("lscp_get_channel_info");
529 appendMessagesError(QObject::tr("Could not get channel information.\n\nSorry."));
530 return false;
531 }
532
533 #ifdef CONFIG_INSTRUMENT_NAME
534 // We got all actual instrument datum...
535 m_sInstrumentFile = pChannelInfo->instrument_file;
536 m_iInstrumentNr = pChannelInfo->instrument_nr;
537 m_sInstrumentName = pChannelInfo->instrument_name;
538 #else
539 // First, check if intrument name has changed,
540 // taking care that instrument name lookup might be expensive,
541 // so we better make it only once and when really needed...
542 if ((m_sInstrumentFile != pChannelInfo->instrument_file) ||
543 (m_iInstrumentNr != pChannelInfo->instrument_nr)) {
544 m_sInstrumentFile = pChannelInfo->instrument_file;
545 m_iInstrumentNr = pChannelInfo->instrument_nr;
546 updateInstrumentName();
547 }
548 #endif
549 // Cache in other channel information.
550 m_sEngineName = pChannelInfo->engine_name;
551 m_iInstrumentStatus = pChannelInfo->instrument_status;
552 m_iMidiDevice = pChannelInfo->midi_device;
553 m_iMidiPort = pChannelInfo->midi_port;
554 m_iMidiChannel = pChannelInfo->midi_channel;
555 m_iAudioDevice = pChannelInfo->audio_device;
556 m_fVolume = pChannelInfo->volume;
557 #ifdef CONFIG_MUTE_SOLO
558 m_bMute = pChannelInfo->mute;
559 m_bSolo = pChannelInfo->solo;
560 #endif
561 // Some sanity checks.
562 if (m_sEngineName == "NONE" || m_sEngineName.isEmpty())
563 m_sEngineName = QString::null;
564 if (m_sInstrumentFile == "NONE" || m_sInstrumentFile.isEmpty()) {
565 m_sInstrumentFile = QString::null;
566 m_sInstrumentName = QString::null;
567 }
568
569 // Time for device info grabbing...
570 lscp_device_info_t *pDeviceInfo;
571 const QString sNone = QObject::tr("(none)");
572 // Audio device driver type.
573 pDeviceInfo = ::lscp_get_audio_device_info(client(), m_iAudioDevice);
574 if (pDeviceInfo == NULL) {
575 appendMessagesClient("lscp_get_audio_device_info");
576 m_sAudioDriver = sNone;
577 } else {
578 m_sAudioDriver = pDeviceInfo->driver;
579 }
580 // MIDI device driver type.
581 pDeviceInfo = ::lscp_get_midi_device_info(client(), m_iMidiDevice);
582 if (pDeviceInfo == NULL) {
583 appendMessagesClient("lscp_get_midi_device_info");
584 m_sMidiDriver = sNone;
585 } else {
586 m_sMidiDriver = pDeviceInfo->driver;
587 }
588
589 // Set the audio routing map.
590 m_audioRouting.clear();
591 char **ppszRouting = pChannelInfo->audio_routing;
592 for (int i = 0; ppszRouting && ppszRouting[i]; i++) {
593 m_audioRouting[i] = ::atoi(ppszRouting[i]);
594 }
595
596 return true;
597 }
598
599
600 // Reset channel method.
601 bool qsamplerChannel::channelReset (void)
602 {
603 if (client() == NULL || m_iChannelID < 0)
604 return false;
605
606 if (::lscp_reset_channel(client(), m_iChannelID) != LSCP_OK) {
607 appendMessagesClient("lscp_reset_channel");
608 return false;
609 }
610
611 appendMessages(QObject::tr("reset."));
612
613 return true;
614 }
615
616
617 // Channel setup dialog form.
618 bool qsamplerChannel::channelSetup ( QWidget *pParent )
619 {
620 bool bResult = false;
621
622 appendMessages(QObject::tr("setup..."));
623
624 qsamplerChannelForm *pChannelForm = new qsamplerChannelForm(pParent);
625 if (pChannelForm) {
626 pChannelForm->setup(this);
627 bResult = pChannelForm->exec();
628 delete pChannelForm;
629 }
630
631 return bResult;
632 }
633
634
635 // Redirected messages output methods.
636 void qsamplerChannel::appendMessages( const QString& s ) const
637 {
638 if (m_pMainForm)
639 m_pMainForm->appendMessages(channelName() + ' ' + s);
640 }
641
642 void qsamplerChannel::appendMessagesColor( const QString& s,
643 const QString& c ) const
644 {
645 if (m_pMainForm)
646 m_pMainForm->appendMessagesColor(channelName() + ' ' + s, c);
647 }
648
649 void qsamplerChannel::appendMessagesText( const QString& s ) const
650 {
651 if (m_pMainForm)
652 m_pMainForm->appendMessagesText(channelName() + ' ' + s);
653 }
654
655 void qsamplerChannel::appendMessagesError( const QString& s ) const
656 {
657 if (m_pMainForm)
658 m_pMainForm->appendMessagesError(channelName() + "\n\n" + s);
659 }
660
661 void qsamplerChannel::appendMessagesClient( const QString& s ) const
662 {
663 if (m_pMainForm)
664 m_pMainForm->appendMessagesClient(channelName() + ' ' + s);
665 }
666
667
668 // Context menu event handler.
669 void qsamplerChannel::contextMenuEvent( QContextMenuEvent *pEvent )
670 {
671 if (m_pMainForm)
672 m_pMainForm->contextMenuEvent(pEvent);
673 }
674
675
676 // FIXME: Check whether a given file is an instrument file.
677 bool qsamplerChannel::isInstrumentFile ( const QString& sInstrumentFile )
678 {
679 bool bResult = false;
680
681 QFile file(sInstrumentFile);
682 if (file.open(IO_ReadOnly)) {
683 char achHeader[16];
684 if (file.readBlock(achHeader, 16)) {
685 bResult = (::memcmp(&achHeader[0], "RIFF", 4) == 0
686 && ::memcmp(&achHeader[8], "DLS LIST", 8) == 0);
687 }
688 file.close();
689 }
690
691 return bResult;
692 }
693
694
695 // Retrieve the instrument list of a instrument file (.gig).
696 QStringList qsamplerChannel::getInstrumentList( const QString& sInstrumentFile,
697 bool bInstrumentNames )
698 {
699 QString sInstrumentName = QFileInfo(sInstrumentFile).fileName();
700 QStringList instlist;
701
702 if (isInstrumentFile(sInstrumentFile)) {
703 #ifdef CONFIG_LIBGIG
704 if (bInstrumentNames) {
705 RIFF::File *pRiff = new RIFF::File(sInstrumentFile.latin1());
706 gig::File *pGig = new gig::File(pRiff);
707 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
708 while (pInstrument) {
709 instlist.append((pInstrument->pInfo)->Name.c_str());
710 pInstrument = pGig->GetNextInstrument();
711 }
712 delete pGig;
713 delete pRiff;
714 }
715 else
716 #endif
717 for (int iInstrumentNr = 0; iInstrumentNr < QSAMPLER_INSTRUMENT_MAX; iInstrumentNr++)
718 instlist.append(sInstrumentName + " [" + QString::number(iInstrumentNr) + "]");
719 }
720 else instlist.append(noInstrumentName());
721
722 return instlist;
723 }
724
725
726 // Retrieve the spacific instrument name of a instrument file (.gig), given its index.
727 QString qsamplerChannel::getInstrumentName( const QString& sInstrumentFile,
728 int iInstrumentNr, bool bInstrumentNames )
729 {
730 QString sInstrumentName;
731
732 if (isInstrumentFile(sInstrumentFile)) {
733 sInstrumentName = QFileInfo(sInstrumentFile).fileName();
734 #ifdef CONFIG_LIBGIG
735 if (bInstrumentNames) {
736 RIFF::File *pRiff = new RIFF::File(sInstrumentFile.latin1());
737 gig::File *pGig = new gig::File(pRiff);
738 int iIndex = 0;
739 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
740 while (pInstrument) {
741 if (iIndex == iInstrumentNr) {
742 sInstrumentName = (pInstrument->pInfo)->Name.c_str();
743 break;
744 }
745 iIndex++;
746 pInstrument = pGig->GetNextInstrument();
747 }
748 delete pGig;
749 delete pRiff;
750 }
751 else
752 #endif
753 sInstrumentName += " [" + QString::number(iInstrumentNr) + "]";
754 }
755 else sInstrumentName = noInstrumentName();
756
757 return sInstrumentName;
758 }
759
760
761 // Common invalid name-helpers.
762 QString qsamplerChannel::noEngineName (void)
763 {
764 return QObject::tr("(No engine)");
765 }
766
767 QString qsamplerChannel::noInstrumentName (void)
768 {
769 return QObject::tr("(No instrument)");
770 }
771
772 QString qsamplerChannel::loadingInstrument (void) {
773 return QObject::tr("(Loading instrument...)");
774 }
775
776
777
778 //-------------------------------------------------------------------------
779 // qsamplerChannelRoutingTable - Channel routing table.
780 //
781
782 // Constructor.
783 qsamplerChannelRoutingTable::qsamplerChannelRoutingTable (
784 QWidget *pParent, const char *pszName )
785 : QTable(pParent, pszName)
786 {
787 // Set fixed number of columns.
788 QTable::setNumCols(2);
789 QTable::setShowGrid(false);
790 QTable::setSorting(false);
791 QTable::setFocusStyle(QTable::FollowStyle);
792 QTable::setSelectionMode(QTable::NoSelection);
793 // No vertical header.
794 QTable::verticalHeader()->hide();
795 QTable::setLeftMargin(0);
796 // Initialize the fixed table column headings.
797 QHeader *pHeader = QTable::horizontalHeader();
798 pHeader->setLabel(0, tr("Sampler Channel"));
799 pHeader->setLabel(1, tr("Device Channel"));
800 // Set read-onlyness of each column
801 QTable::setColumnReadOnly(0, true);
802 // QTable::setColumnReadOnly(1, false); -- of course not.
803 QTable::setColumnStretchable(1, true);
804 }
805
806 // Default destructor.
807 qsamplerChannelRoutingTable::~qsamplerChannelRoutingTable (void)
808 {
809 }
810
811
812 // Routing map table renderer.
813 void qsamplerChannelRoutingTable::refresh ( qsamplerDevice *pDevice,
814 const qsamplerChannelRoutingMap& routing )
815 {
816 if (pDevice == NULL)
817 return;
818
819 // Always (re)start it empty.
820 QTable::setUpdatesEnabled(false);
821 QTable::setNumRows(0);
822
823 // The common device port item list.
824 QStringList opts;
825 qsamplerDevicePortList& ports = pDevice->ports();
826 qsamplerDevicePort *pPort;
827 for (pPort = ports.first(); pPort; pPort = ports.next()) {
828 opts.append(pDevice->deviceTypeName()
829 + ' ' + pDevice->driverName()
830 + ' ' + pPort->portName());
831 }
832
833 // Those items shall have a proper pixmap...
834 QPixmap pmChannel = QPixmap::fromMimeSource("qsamplerChannel.png");
835 QPixmap pmDevice;
836 switch (pDevice->deviceType()) {
837 case qsamplerDevice::Audio:
838 pmDevice = QPixmap::fromMimeSource("audio2.png");
839 break;
840 case qsamplerDevice::Midi:
841 pmDevice = QPixmap::fromMimeSource("midi2.png");
842 break;
843 case qsamplerDevice::None:
844 break;
845 }
846
847 // Fill the routing table...
848 QTable::insertRows(0, routing.count());
849 int iRow = 0;
850 qsamplerChannelRoutingMap::ConstIterator iter;
851 for (iter = routing.begin(); iter != routing.end(); ++iter) {
852 QTable::setPixmap(iRow, 0, pmChannel);
853 QTable::setText(iRow, 0, pDevice->deviceTypeName()
854 + ' ' + QString::number(iter.key()));
855 qsamplerChannelRoutingComboBox *pComboItem =
856 new qsamplerChannelRoutingComboBox(this, opts, pmDevice);
857 pComboItem->setCurrentItem(iter.data());
858 QTable::setItem(iRow, 1, pComboItem);
859 ++iRow;
860 }
861
862 // Adjust optimal column widths.
863 QTable::adjustColumn(0);
864 QTable::adjustColumn(1);
865
866 QTable::setUpdatesEnabled(true);
867 QTable::updateContents();
868 }
869
870
871 // Commit any pending editing.
872 void qsamplerChannelRoutingTable::flush (void)
873 {
874 if (QTable::isEditing())
875 QTable::endEdit(QTable::currEditRow(), QTable::currEditCol(), true, true);
876 }
877
878
879 //-------------------------------------------------------------------------
880 // qsamplerChannelRoutingComboBox - Custom combo box for routing table.
881 //
882
883 // Constructor.
884 qsamplerChannelRoutingComboBox::qsamplerChannelRoutingComboBox (
885 QTable *pTable, const QStringList& list, const QPixmap& pixmap )
886 : QTableItem(pTable, QTableItem::WhenCurrent, QString::null, pixmap),
887 m_list(list)
888 {
889 m_iCurrentItem = 0;
890 }
891
892 // Public accessors.
893 void qsamplerChannelRoutingComboBox::setCurrentItem ( int iCurrentItem )
894 {
895 m_iCurrentItem = iCurrentItem;
896
897 QTableItem::setText(m_list[iCurrentItem]);
898 }
899
900 int qsamplerChannelRoutingComboBox::currentItem (void) const
901 {
902 return m_iCurrentItem;
903 }
904
905 // Virtual implemetations.
906 QWidget *qsamplerChannelRoutingComboBox::createEditor (void) const
907 {
908 QComboBox *pComboBox = new QComboBox(QTableItem::table()->viewport());
909 QObject::connect(pComboBox, SIGNAL(activated(int)),
910 QTableItem::table(), SLOT(doValueChanged()));
911 for (QStringList::ConstIterator iter = m_list.begin();
912 iter != m_list.end(); iter++) {
913 pComboBox->insertItem(QTableItem::pixmap(), *iter);
914 }
915 pComboBox->setCurrentItem(m_iCurrentItem);
916 return pComboBox;
917 }
918
919 void qsamplerChannelRoutingComboBox::setContentFromEditor ( QWidget *pWidget )
920 {
921 if (pWidget->inherits("QComboBox")) {
922 QComboBox *pComboBox = (QComboBox *) pWidget;
923 m_iCurrentItem = pComboBox->currentItem();
924 QTableItem::setText(pComboBox->currentText());
925 }
926 else QTableItem::setContentFromEditor(pWidget);
927 }
928
929
930 // end of qsamplerChannel.cpp

  ViewVC Help
Powered by ViewVC