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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 767 - (show annotations) (download)
Tue Aug 30 09:52:46 2005 UTC (18 years, 7 months ago) by capela
File size: 23988 byte(s)
* Sampler channel audio routing changes are now being
  properly flushed upon immediate dialog acceptance,

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 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 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