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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3555 - (show annotations) (download)
Tue Aug 13 10:19:32 2019 UTC (8 days, 12 hours ago) by capela
File size: 29120 byte(s)
- In late compliance to C++11, all NULL constants replaced for nullptr.
1 // qsamplerChannel.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2007, 2008 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 "qsamplerChannel.h"
25 #include "qsamplerUtilities.h"
26
27 #include "qsamplerMainForm.h"
28 #include "qsamplerChannelForm.h"
29
30 #include <QFileInfo>
31 #include <QComboBox>
32
33 #ifdef CONFIG_LIBGIG
34 #include "gig.h"
35 #ifdef CONFIG_LIBGIG_SF2
36 #include "SF.h"
37 #endif
38 #endif
39
40 namespace QSampler {
41
42 #define QSAMPLER_INSTRUMENT_MAX 128
43
44 #define UNICODE_RIGHT_ARROW QChar(char(0x92), char(0x21))
45
46
47 //-------------------------------------------------------------------------
48 // QSampler::Channel - Sampler channel structure.
49 //
50
51 // Constructor.
52 Channel::Channel ( int iChannelID )
53 {
54 m_iChannelID = iChannelID;
55
56 // m_sEngineName = noEngineName();
57 // m_sInstrumentName = noInstrumentName();
58 // m_sInstrumentFile = m_sInstrumentName;
59 m_iInstrumentNr = -1;
60 m_iInstrumentStatus = -1;
61 m_sMidiDriver = "ALSA";
62 m_iMidiDevice = -1;
63 m_iMidiPort = -1;
64 m_iMidiChannel = -1;
65 m_iMidiMap = -1;
66 m_sAudioDriver = "ALSA";
67 m_iAudioDevice = -1;
68 m_fVolume = 0.0f;
69 m_bMute = false;
70 m_bSolo = false;
71 }
72
73 // Default destructor.
74 Channel::~Channel (void)
75 {
76 }
77
78
79 // Create a new sampler channel, if not already.
80 bool Channel::addChannel (void)
81 {
82 MainForm* pMainForm = MainForm::getInstance();
83 if (pMainForm == nullptr)
84 return false;
85 if (pMainForm->client() == nullptr)
86 return false;
87
88 // Are we a new channel?
89 if (m_iChannelID < 0) {
90 m_iChannelID = ::lscp_add_channel(pMainForm->client());
91 if (m_iChannelID < 0) {
92 appendMessagesClient("lscp_add_channel");
93 appendMessagesError(
94 QObject::tr("Could not add channel.\n\nSorry."));
95 } // Otherwise it's created...
96 else appendMessages(QObject::tr("added."));
97 }
98
99 // Return whether we're a valid channel...
100 return (m_iChannelID >= 0);
101 }
102
103
104 // Remove sampler channel.
105 bool Channel::removeChannel (void)
106 {
107 MainForm *pMainForm = MainForm::getInstance();
108 if (pMainForm == nullptr)
109 return false;
110 if (pMainForm->client() == nullptr)
111 return false;
112
113 // Are we an existing channel?
114 if (m_iChannelID >= 0) {
115 if (::lscp_remove_channel(pMainForm->client(), m_iChannelID) != LSCP_OK) {
116 appendMessagesClient("lscp_remove_channel");
117 appendMessagesError(QObject::tr("Could not remove channel.\n\nSorry."));
118 } else {
119 // Otherwise it's removed.
120 appendMessages(QObject::tr("removed."));
121 m_iChannelID = -1;
122 }
123 }
124
125 // Return whether we've removed the channel...
126 return (m_iChannelID < 0);
127 }
128
129
130 // Channel-ID (aka Sammpler-Channel) accessors.
131 int Channel::channelID (void) const
132 {
133 return m_iChannelID;
134 }
135
136 void Channel::setChannelID ( int iChannelID )
137 {
138 m_iChannelID = iChannelID;
139 }
140
141
142 // Readable channel name.
143 QString Channel::channelName (void) const
144 {
145 return (m_iChannelID < 0 ? QObject::tr("New Channel") : QObject::tr("Channel %1").arg(m_iChannelID));
146 }
147
148
149 // Engine name accessors.
150 const QString& Channel::engineName (void) const
151 {
152 return m_sEngineName;
153 }
154
155 bool Channel::loadEngine ( const QString& sEngineName )
156 {
157 MainForm *pMainForm = MainForm::getInstance();
158 if (pMainForm == nullptr)
159 return false;
160 if (pMainForm->client() == nullptr || m_iChannelID < 0)
161 return false;
162 if (m_iInstrumentStatus == 100 && m_sEngineName == sEngineName)
163 return true;
164
165 if (::lscp_load_engine(pMainForm->client(),
166 sEngineName.toUtf8().constData(), m_iChannelID) != LSCP_OK) {
167 appendMessagesClient("lscp_load_engine");
168 return false;
169 }
170
171 appendMessages(QObject::tr("Engine: %1.").arg(sEngineName));
172
173 m_sEngineName = sEngineName;
174 return true;
175 }
176
177
178 // Instrument filename accessor.
179 const QString& Channel::instrumentFile (void) const
180 {
181 return m_sInstrumentFile;
182 }
183
184 // Instrument index accessor.
185 int Channel::instrumentNr (void) const
186 {
187 return m_iInstrumentNr;
188 }
189
190 // Instrument name accessor.
191 const QString& Channel::instrumentName (void) const
192 {
193 return m_sInstrumentName;
194 }
195
196 // Instrument status accessor.
197 int Channel::instrumentStatus (void) const
198 {
199 return m_iInstrumentStatus;
200 }
201
202 // Instrument file loader.
203 bool Channel::loadInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
204 {
205 MainForm *pMainForm = MainForm::getInstance();
206 if (pMainForm == nullptr)
207 return false;
208 if (pMainForm->client() == nullptr || m_iChannelID < 0)
209 return false;
210 if (!QFileInfo(sInstrumentFile).exists())
211 return false;
212 if (m_iInstrumentStatus == 100
213 && m_sInstrumentFile == sInstrumentFile
214 && m_iInstrumentNr == iInstrumentNr)
215 return true;
216
217 if (::lscp_load_instrument_non_modal(
218 pMainForm->client(),
219 qsamplerUtilities::lscpEscapePath(
220 sInstrumentFile).toUtf8().constData(),
221 iInstrumentNr, m_iChannelID
222 ) != LSCP_OK) {
223 appendMessagesClient("lscp_load_instrument");
224 return false;
225 }
226
227 appendMessages(QObject::tr("Instrument: \"%1\" (%2).")
228 .arg(sInstrumentFile).arg(iInstrumentNr));
229
230 return setInstrument(sInstrumentFile, iInstrumentNr);
231 }
232
233
234 // Special instrument file/name/number settler.
235 bool Channel::setInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
236 {
237 m_sInstrumentFile = sInstrumentFile;
238 m_iInstrumentNr = iInstrumentNr;
239 #ifdef CONFIG_INSTRUMENT_NAME
240 m_sInstrumentName.clear(); // We'll get it, maybe later, on channel_info...
241 #else
242 m_sInstrumentName = getInstrumentName(sInstrumentFile, iInstrumentNr, true);
243 #endif
244 m_iInstrumentStatus = 0;
245
246 return true;
247 }
248
249
250 // MIDI driver type accessors (DEPRECATED).
251 const QString& Channel::midiDriver (void) const
252 {
253 return m_sMidiDriver;
254 }
255
256 bool Channel::setMidiDriver ( const QString& sMidiDriver )
257 {
258 MainForm *pMainForm = MainForm::getInstance();
259 if (pMainForm == nullptr)
260 return false;
261 if (pMainForm->client() == nullptr || m_iChannelID < 0)
262 return false;
263 if (m_iInstrumentStatus == 100 && m_sMidiDriver == sMidiDriver)
264 return true;
265
266 if (::lscp_set_channel_midi_type(pMainForm->client(),
267 m_iChannelID, sMidiDriver.toUtf8().constData()) != LSCP_OK) {
268 appendMessagesClient("lscp_set_channel_midi_type");
269 return false;
270 }
271
272 appendMessages(QObject::tr("MIDI driver: %1.").arg(sMidiDriver));
273
274 m_sMidiDriver = sMidiDriver;
275 return true;
276 }
277
278
279 // MIDI device accessors.
280 int Channel::midiDevice (void) const
281 {
282 return m_iMidiDevice;
283 }
284
285 bool Channel::setMidiDevice ( int iMidiDevice )
286 {
287 MainForm *pMainForm = MainForm::getInstance();
288 if (pMainForm == nullptr)
289 return false;
290 if (pMainForm->client() == nullptr || m_iChannelID < 0)
291 return false;
292 if (m_iInstrumentStatus == 100 && m_iMidiDevice == iMidiDevice)
293 return true;
294
295 if (::lscp_set_channel_midi_device(pMainForm->client(), m_iChannelID, iMidiDevice) != LSCP_OK) {
296 appendMessagesClient("lscp_set_channel_midi_device");
297 return false;
298 }
299
300 appendMessages(QObject::tr("MIDI device: %1.").arg(iMidiDevice));
301
302 m_iMidiDevice = iMidiDevice;
303 return true;
304 }
305
306
307 // MIDI port number accessor.
308 int Channel::midiPort (void) const
309 {
310 return m_iMidiPort;
311 }
312
313 bool Channel::setMidiPort ( int iMidiPort )
314 {
315 MainForm *pMainForm = MainForm::getInstance();
316 if (pMainForm == nullptr)
317 return false;
318 if (pMainForm->client() == nullptr || m_iChannelID < 0)
319 return false;
320 if (m_iInstrumentStatus == 100 && m_iMidiPort == iMidiPort)
321 return true;
322
323 if (::lscp_set_channel_midi_port(pMainForm->client(), m_iChannelID, iMidiPort) != LSCP_OK) {
324 appendMessagesClient("lscp_set_channel_midi_port");
325 return false;
326 }
327
328 appendMessages(QObject::tr("MIDI port: %1.").arg(iMidiPort));
329
330 m_iMidiPort = iMidiPort;
331 return true;
332 }
333
334
335 // MIDI channel accessor.
336 int Channel::midiChannel (void) const
337 {
338 return m_iMidiChannel;
339 }
340
341 bool Channel::setMidiChannel ( int iMidiChannel )
342 {
343 MainForm *pMainForm = MainForm::getInstance();
344 if (pMainForm == nullptr)
345 return false;
346 if (pMainForm->client() == nullptr || m_iChannelID < 0)
347 return false;
348 if (m_iInstrumentStatus == 100 && m_iMidiChannel == iMidiChannel)
349 return true;
350
351 if (::lscp_set_channel_midi_channel(pMainForm->client(), m_iChannelID, iMidiChannel) != LSCP_OK) {
352 appendMessagesClient("lscp_set_channel_midi_channel");
353 return false;
354 }
355
356 appendMessages(QObject::tr("MIDI channel: %1.").arg(iMidiChannel));
357
358 m_iMidiChannel = iMidiChannel;
359 return true;
360 }
361
362
363 // MIDI instrument map accessor.
364 int Channel::midiMap (void) const
365 {
366 return m_iMidiMap;
367 }
368
369 bool Channel::setMidiMap ( int iMidiMap )
370 {
371 MainForm *pMainForm = MainForm::getInstance();
372 if (pMainForm == nullptr)
373 return false;
374 if (pMainForm->client() == nullptr || m_iChannelID < 0)
375 return false;
376 if (m_iInstrumentStatus == 100 && m_iMidiMap == iMidiMap)
377 return true;
378 #ifdef CONFIG_MIDI_INSTRUMENT
379 if (::lscp_set_channel_midi_map(pMainForm->client(), m_iChannelID, iMidiMap) != LSCP_OK) {
380 appendMessagesClient("lscp_set_channel_midi_map");
381 return false;
382 }
383 #endif
384 appendMessages(QObject::tr("MIDI map: %1.").arg(iMidiMap));
385
386 m_iMidiMap = iMidiMap;
387 return true;
388 }
389
390
391 // Audio device accessor.
392 int Channel::audioDevice (void) const
393 {
394 return m_iAudioDevice;
395 }
396
397 bool Channel::setAudioDevice ( int iAudioDevice )
398 {
399 MainForm *pMainForm = MainForm::getInstance();
400 if (pMainForm == nullptr)
401 return false;
402 if (pMainForm->client() == nullptr || m_iChannelID < 0)
403 return false;
404 if (m_iInstrumentStatus == 100 && m_iAudioDevice == iAudioDevice)
405 return true;
406
407 if (::lscp_set_channel_audio_device(pMainForm->client(), m_iChannelID, iAudioDevice) != LSCP_OK) {
408 appendMessagesClient("lscp_set_channel_audio_device");
409 return false;
410 }
411
412 appendMessages(QObject::tr("Audio device: %1.").arg(iAudioDevice));
413
414 m_iAudioDevice = iAudioDevice;
415 return true;
416 }
417
418
419 // Audio driver type accessors (DEPRECATED).
420 const QString& Channel::audioDriver (void) const
421 {
422 return m_sAudioDriver;
423 }
424
425 bool Channel::setAudioDriver ( const QString& sAudioDriver )
426 {
427 MainForm *pMainForm = MainForm::getInstance();
428 if (pMainForm == nullptr)
429 return false;
430 if (pMainForm->client() == nullptr || m_iChannelID < 0)
431 return false;
432 if (m_iInstrumentStatus == 100 && m_sAudioDriver == sAudioDriver)
433 return true;
434
435 if (::lscp_set_channel_audio_type(pMainForm->client(),
436 m_iChannelID, sAudioDriver.toUtf8().constData()) != LSCP_OK) {
437 appendMessagesClient("lscp_set_channel_audio_type");
438 return false;
439 }
440
441 appendMessages(QObject::tr("Audio driver: %1.").arg(sAudioDriver));
442
443 m_sAudioDriver = sAudioDriver;
444 return true;
445 }
446
447
448 // Channel volume accessors.
449 float Channel::volume (void) const
450 {
451 return m_fVolume;
452 }
453
454 bool Channel::setVolume ( float fVolume )
455 {
456 MainForm *pMainForm = MainForm::getInstance();
457 if (pMainForm == nullptr)
458 return false;
459 if (pMainForm->client() == nullptr || m_iChannelID < 0)
460 return false;
461 if (m_iInstrumentStatus == 100 && m_fVolume == fVolume)
462 return true;
463
464 if (::lscp_set_channel_volume(pMainForm->client(), m_iChannelID, fVolume) != LSCP_OK) {
465 appendMessagesClient("lscp_set_channel_volume");
466 return false;
467 }
468
469 appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
470
471 m_fVolume = fVolume;
472 return true;
473 }
474
475
476 // Sampler channel mute state.
477 bool Channel::channelMute (void) const
478 {
479 return m_bMute;
480 }
481
482 bool Channel::setChannelMute ( bool bMute )
483 {
484 MainForm *pMainForm = MainForm::getInstance();
485 if (pMainForm == nullptr)
486 return false;
487 if (pMainForm->client() == nullptr || m_iChannelID < 0)
488 return false;
489 if (m_iInstrumentStatus == 100 && ((m_bMute && bMute) || (!m_bMute && !bMute)))
490 return true;
491
492 #ifdef CONFIG_MUTE_SOLO
493 if (::lscp_set_channel_mute(pMainForm->client(), m_iChannelID, bMute) != LSCP_OK) {
494 appendMessagesClient("lscp_set_channel_mute");
495 return false;
496 }
497 appendMessages(QObject::tr("Mute: %1.").arg((int) bMute));
498 m_bMute = bMute;
499 return true;
500 #else
501 return false;
502 #endif
503 }
504
505
506 // Sampler channel solo state.
507 bool Channel::channelSolo (void) const
508 {
509 return m_bSolo;
510 }
511
512 bool Channel::setChannelSolo ( bool bSolo )
513 {
514 MainForm *pMainForm = MainForm::getInstance();
515 if (pMainForm == nullptr)
516 return false;
517 if (pMainForm->client() == nullptr || m_iChannelID < 0)
518 return false;
519 if (m_iInstrumentStatus == 100 && ((m_bSolo && bSolo) || (!m_bSolo && !bSolo)))
520 return true;
521
522 #ifdef CONFIG_MUTE_SOLO
523 if (::lscp_set_channel_solo(pMainForm->client(), m_iChannelID, bSolo) != LSCP_OK) {
524 appendMessagesClient("lscp_set_channel_solo");
525 return false;
526 }
527 appendMessages(QObject::tr("Solo: %1.").arg((int) bSolo));
528 m_bSolo = bSolo;
529 return true;
530 #else
531 return false;
532 #endif
533 }
534
535
536 // Audio routing accessors.
537 int Channel::audioChannel ( int iAudioOut ) const
538 {
539 return m_audioRouting[iAudioOut];
540 }
541
542 bool Channel::setAudioChannel ( int iAudioOut, int iAudioIn )
543 {
544 MainForm *pMainForm = MainForm::getInstance();
545 if (pMainForm == nullptr)
546 return false;
547 if (pMainForm->client() == nullptr || m_iChannelID < 0)
548 return false;
549 if (m_iInstrumentStatus == 100 &&
550 m_audioRouting[iAudioOut] == iAudioIn)
551 return true;
552
553 if (::lscp_set_channel_audio_channel(pMainForm->client(),
554 m_iChannelID, iAudioOut, iAudioIn) != LSCP_OK) {
555 appendMessagesClient("lscp_set_channel_audio_channel");
556 return false;
557 }
558
559 appendMessages(QObject::tr("Audio Channel: %1 -> %2.")
560 .arg(iAudioOut).arg(iAudioIn));
561
562 m_audioRouting[iAudioOut] = iAudioIn;
563 return true;
564 }
565
566 // The audio routing map itself.
567 const ChannelRoutingMap& Channel::audioRouting (void) const
568 {
569 return m_audioRouting;
570 }
571
572
573 // Istrument name remapper.
574 void Channel::updateInstrumentName (void)
575 {
576 #ifndef CONFIG_INSTRUMENT_NAME
577 m_sInstrumentName = getInstrumentName(m_sInstrumentFile,
578 m_iInstrumentNr, (options() && options()->bInstrumentNames));
579 #endif
580 }
581
582
583 // Update whole channel info state.
584 bool Channel::updateChannelInfo (void)
585 {
586 MainForm *pMainForm = MainForm::getInstance();
587 if (pMainForm == nullptr)
588 return false;
589 if (pMainForm->client() == nullptr || m_iChannelID < 0)
590 return false;
591
592 // Read channel information.
593 lscp_channel_info_t *pChannelInfo = ::lscp_get_channel_info(pMainForm->client(), m_iChannelID);
594 if (pChannelInfo == nullptr) {
595 appendMessagesClient("lscp_get_channel_info");
596 appendMessagesError(QObject::tr("Could not get channel information.\n\nSorry."));
597 return false;
598 }
599
600 #ifdef CONFIG_INSTRUMENT_NAME
601 // We got all actual instrument datum...
602 m_sInstrumentFile =
603 qsamplerUtilities::lscpEscapedPathToPosix(pChannelInfo->instrument_file);
604 m_iInstrumentNr = pChannelInfo->instrument_nr;
605 m_sInstrumentName =
606 qsamplerUtilities::lscpEscapedTextToRaw(pChannelInfo->instrument_name);
607 #else
608 // First, check if intrument name has changed,
609 // taking care that instrument name lookup might be expensive,
610 // so we better make it only once and when really needed...
611 if ((m_sInstrumentFile != pChannelInfo->instrument_file) ||
612 (m_iInstrumentNr != pChannelInfo->instrument_nr)) {
613 m_sInstrumentFile = pChannelInfo->instrument_file;
614 m_iInstrumentNr = pChannelInfo->instrument_nr;
615 updateInstrumentName();
616 }
617 #endif
618 // Cache in other channel information.
619 m_sEngineName = pChannelInfo->engine_name;
620 m_iInstrumentStatus = pChannelInfo->instrument_status;
621 m_iMidiDevice = pChannelInfo->midi_device;
622 m_iMidiPort = pChannelInfo->midi_port;
623 m_iMidiChannel = pChannelInfo->midi_channel;
624 #ifdef CONFIG_MIDI_INSTRUMENT
625 m_iMidiMap = pChannelInfo->midi_map;
626 #endif
627 m_iAudioDevice = pChannelInfo->audio_device;
628 m_fVolume = pChannelInfo->volume;
629 #ifdef CONFIG_MUTE_SOLO
630 m_bMute = pChannelInfo->mute;
631 m_bSolo = pChannelInfo->solo;
632 #endif
633 // Some sanity checks.
634 if (m_sEngineName == "NONE" || m_sEngineName.isEmpty())
635 m_sEngineName.clear();
636 if (m_sInstrumentFile == "NONE" || m_sInstrumentFile.isEmpty()) {
637 m_sInstrumentFile.clear();
638 m_sInstrumentName.clear();
639 }
640
641 // Time for device info grabbing...
642 lscp_device_info_t *pDeviceInfo;
643 const QString sNone = QObject::tr("(none)");
644 // Audio device driver type.
645 pDeviceInfo = ::lscp_get_audio_device_info(pMainForm->client(), m_iAudioDevice);
646 if (pDeviceInfo == nullptr) {
647 appendMessagesClient("lscp_get_audio_device_info");
648 m_sAudioDriver = sNone;
649 } else {
650 m_sAudioDriver = pDeviceInfo->driver;
651 }
652 // MIDI device driver type.
653 pDeviceInfo = ::lscp_get_midi_device_info(pMainForm->client(), m_iMidiDevice);
654 if (pDeviceInfo == nullptr) {
655 appendMessagesClient("lscp_get_midi_device_info");
656 m_sMidiDriver = sNone;
657 } else {
658 m_sMidiDriver = pDeviceInfo->driver;
659 }
660
661 // Set the audio routing map.
662 m_audioRouting.clear();
663 #ifdef CONFIG_AUDIO_ROUTING
664 int *piAudioRouting = pChannelInfo->audio_routing;
665 for (int i = 0; piAudioRouting && piAudioRouting[i] >= 0; i++)
666 m_audioRouting[i] = piAudioRouting[i];
667 #else
668 char **ppszAudioRouting = pChannelInfo->audio_routing;
669 for (int i = 0; ppszAudioRouting && ppszAudioRouting[i]; i++)
670 m_audioRouting[i] = ::atoi(ppszAudioRouting[i]);
671 #endif
672
673 return true;
674 }
675
676
677 // Reset channel method.
678 bool Channel::channelReset (void)
679 {
680 MainForm *pMainForm = MainForm::getInstance();
681 if (pMainForm == nullptr)
682 return false;
683 if (pMainForm->client() == nullptr || m_iChannelID < 0)
684 return false;
685
686 if (::lscp_reset_channel(pMainForm->client(), m_iChannelID) != LSCP_OK) {
687 appendMessagesClient("lscp_reset_channel");
688 return false;
689 }
690
691 appendMessages(QObject::tr("reset."));
692
693 return true;
694 }
695
696
697 // Spawn instrument editor method.
698 bool Channel::editChannel (void)
699 {
700 #ifdef CONFIG_EDIT_INSTRUMENT
701
702 MainForm *pMainForm = MainForm::getInstance();
703 if (pMainForm == nullptr)
704 return false;
705 if (pMainForm->client() == nullptr || m_iChannelID < 0)
706 return false;
707
708 if (::lscp_edit_channel_instrument(pMainForm->client(), m_iChannelID)
709 != LSCP_OK) {
710 appendMessagesClient("lscp_edit_channel_instrument");
711 appendMessagesError(QObject::tr(
712 "Could not launch an appropriate instrument editor "
713 "for the given instrument!\n\n"
714 "Make sure you have an appropriate "
715 "instrument editor like 'gigedit' installed "
716 "and that it placed its mandatory DLL file "
717 "into the sampler's plugin directory.")
718 );
719 return false;
720 }
721
722 appendMessages(QObject::tr("edit instrument."));
723
724 return true;
725
726 #else
727
728 appendMessagesError(QObject::tr(
729 "Sorry, QSampler was compiled for a version of liblscp "
730 "which lacks this feature.\n\n"
731 "You may want to update liblscp and recompile QSampler afterwards.")
732 );
733
734 return false;
735
736 #endif
737 }
738
739
740 // Channel setup dialog form.
741 bool Channel::channelSetup ( QWidget *pParent )
742 {
743 MainForm *pMainForm = MainForm::getInstance();
744 if (pMainForm == nullptr)
745 return false;
746
747 bool bResult = false;
748
749 appendMessages(QObject::tr("setup..."));
750
751 ChannelForm *pChannelForm = new ChannelForm(pParent);
752 if (pChannelForm) {
753 pChannelForm->setup(this);
754 bResult = pChannelForm->exec();
755 delete pChannelForm;
756 }
757
758 return bResult;
759 }
760
761
762 // Redirected messages output methods.
763 void Channel::appendMessages ( const QString& sText ) const
764 {
765 MainForm *pMainForm = MainForm::getInstance();
766 if (pMainForm)
767 pMainForm->appendMessages(channelName() + ' ' + sText);
768 }
769
770 void Channel::appendMessagesColor (
771 const QString& sText, const QString& sColor ) const
772 {
773 MainForm *pMainForm = MainForm::getInstance();
774 if (pMainForm)
775 pMainForm->appendMessagesColor(channelName() + ' ' + sText, sColor);
776 }
777
778 void Channel::appendMessagesText ( const QString& sText ) const
779 {
780 MainForm *pMainForm = MainForm::getInstance();
781 if (pMainForm)
782 pMainForm->appendMessagesText(channelName() + ' ' + sText);
783 }
784
785 void Channel::appendMessagesError ( const QString& sText ) const
786 {
787 MainForm *pMainForm = MainForm::getInstance();
788 if (pMainForm)
789 pMainForm->appendMessagesError(channelName() + "\n\n" + sText);
790 }
791
792 void Channel::appendMessagesClient ( const QString& sText ) const
793 {
794 MainForm *pMainForm = MainForm::getInstance();
795 if (pMainForm)
796 pMainForm->appendMessagesClient(channelName() + ' ' + sText);
797 }
798
799
800 // Context menu event handler.
801 void Channel::contextMenuEvent ( QContextMenuEvent *pEvent )
802 {
803 MainForm *pMainForm = MainForm::getInstance();
804 if (pMainForm)
805 pMainForm->contextMenuEvent(pEvent);
806 }
807
808
809 // FIXME: Check whether a given file is an instrument file (DLS only).
810 bool Channel::isDlsInstrumentFile ( const QString& sInstrumentFile )
811 {
812 bool bResult = false;
813
814 QFile file(sInstrumentFile);
815 if (file.open(QIODevice::ReadOnly)) {
816 char achHeader[16];
817 if (file.read(achHeader, 16) > 0) {
818 bResult = (::memcmp(&achHeader[0], "RIFF", 4) == 0
819 && ::memcmp(&achHeader[8], "DLS LIST", 8) == 0);
820 }
821 file.close();
822 }
823
824 return bResult;
825 }
826
827
828 // FIXME: Check whether a given file is an instrument file (SF2 only).
829 bool Channel::isSf2InstrumentFile ( const QString& sInstrumentFile )
830 {
831 bool bResult = false;
832
833 QFile file(sInstrumentFile);
834 if (file.open(QIODevice::ReadOnly)) {
835 char achHeader[12];
836 if (file.read(achHeader, 12) > 0) {
837 bResult = (::memcmp(&achHeader[0], "RIFF", 4) == 0
838 && ::memcmp(&achHeader[8], "sfbk", 4) == 0);
839 }
840 file.close();
841 }
842
843 return bResult;
844 }
845
846
847 // Retrieve the instrument list of a instrument file (.gig).
848 QStringList Channel::getInstrumentList (
849 const QString& sInstrumentFile, bool bInstrumentNames )
850 {
851 QStringList instlist;
852
853 const QFileInfo fi(sInstrumentFile);
854 if (!fi.exists()) {
855 instlist.append(noInstrumentName());
856 return instlist;
857 }
858
859 #ifdef CONFIG_LIBGIG
860 if (bInstrumentNames) {
861 if (isDlsInstrumentFile(sInstrumentFile)) {
862 RIFF::File *pRiff
863 = new RIFF::File(sInstrumentFile.toUtf8().constData());
864 gig::File *pGig = new gig::File(pRiff);
865 #ifdef CONFIG_LIBGIG_SETAUTOLOAD
866 // prevent sleepy response time on large .gig files
867 pGig->SetAutoLoad(false);
868 #endif
869 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
870 while (pInstrument) {
871 instlist.append((pInstrument->pInfo)->Name.c_str());
872 pInstrument = pGig->GetNextInstrument();
873 }
874 delete pGig;
875 delete pRiff;
876 }
877 #ifdef CONFIG_LIBGIG_SF2
878 else
879 if (isSf2InstrumentFile(sInstrumentFile)) {
880 RIFF::File *pRiff
881 = new RIFF::File(sInstrumentFile.toUtf8().constData());
882 sf2::File *pSf2 = new sf2::File(pRiff);
883 const int iPresetCount = pSf2->GetPresetCount();
884 for (int iIndex = 0; iIndex < iPresetCount; ++iIndex) {
885 sf2::Preset *pPreset = pSf2->GetPreset(iIndex);
886 if (pPreset) {
887 instlist.append(pPreset->Name.c_str());
888 } else {
889 instlist.append(fi.fileName()
890 + " [" + QString::number(iIndex) + "]");
891 }
892 }
893 delete pSf2;
894 delete pRiff;
895 }
896 #endif
897 }
898 #endif
899
900 if (instlist.isEmpty()) {
901 for (int iIndex = 0; iIndex < QSAMPLER_INSTRUMENT_MAX; ++iIndex) {
902 instlist.append(fi.fileName()
903 + " [" + QString::number(iIndex) + "]");
904 }
905 }
906
907 return instlist;
908 }
909
910
911 // Retrieve the spacific instrument name of a instrument file (.gig), given its index.
912 QString Channel::getInstrumentName (
913 const QString& sInstrumentFile, int iInstrumentNr, bool bInstrumentNames )
914 {
915 const QFileInfo fi(sInstrumentFile);
916 if (!fi.exists())
917 return noInstrumentName();
918
919 QString sInstrumentName;
920
921 #ifdef CONFIG_LIBGIG
922 if (bInstrumentNames) {
923 if (isDlsInstrumentFile(sInstrumentFile)) {
924 RIFF::File *pRiff
925 = new RIFF::File(sInstrumentFile.toUtf8().constData());
926 gig::File *pGig = new gig::File(pRiff);
927 #ifdef CONFIG_LIBGIG_SETAUTOLOAD
928 // prevent sleepy response time on large .gig files
929 pGig->SetAutoLoad(false);
930 #endif
931 int iIndex = 0;
932 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
933 while (pInstrument) {
934 if (iIndex == iInstrumentNr) {
935 sInstrumentName = (pInstrument->pInfo)->Name.c_str();
936 break;
937 }
938 iIndex++;
939 pInstrument = pGig->GetNextInstrument();
940 }
941 delete pGig;
942 delete pRiff;
943 }
944 #ifdef CONFIG_LIBGIG_SF2
945 else
946 if (isSf2InstrumentFile(sInstrumentFile)) {
947 RIFF::File *pRiff
948 = new RIFF::File(sInstrumentFile.toUtf8().constData());
949 sf2::File *pSf2 = new sf2::File(pRiff);
950 sf2::Preset *pPreset = pSf2->GetPreset(iInstrumentNr);
951 if (pPreset)
952 sInstrumentName = pPreset->Name.c_str();
953 delete pSf2;
954 delete pRiff;
955 }
956 #endif
957 }
958 #endif
959
960 if (sInstrumentName.isEmpty()) {
961 sInstrumentName = fi.fileName();
962 sInstrumentName += " [" + QString::number(iInstrumentNr) + "]";
963 }
964
965 return sInstrumentName;
966 }
967
968
969 // Common invalid name-helpers.
970 QString Channel::noEngineName (void)
971 {
972 return QObject::tr("(No engine)");
973 }
974
975 QString Channel::noInstrumentName (void)
976 {
977 return QObject::tr("(No instrument)");
978 }
979
980 QString Channel::loadingInstrument (void) {
981 return QObject::tr("(Loading instrument...)");
982 }
983
984
985 //-------------------------------------------------------------------------
986 // QSampler::ChannelRoutingModel - data model for audio routing
987 // (used for QTableView)
988
989 ChannelRoutingModel::ChannelRoutingModel ( QObject *pParent )
990 : QAbstractTableModel(pParent), m_pDevice(nullptr)
991 {
992 }
993
994
995 int ChannelRoutingModel::rowCount ( const QModelIndex& /*parent*/) const
996 {
997 return (m_pDevice) ? m_routing.size() : 0;
998 }
999
1000
1001 int ChannelRoutingModel::columnCount ( const QModelIndex& /*parent*/) const
1002 {
1003 return 1;
1004 }
1005
1006
1007 Qt::ItemFlags ChannelRoutingModel::flags ( const QModelIndex& /*index*/) const
1008 {
1009 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
1010 }
1011
1012
1013 bool ChannelRoutingModel::setData ( const QModelIndex& index,
1014 const QVariant& value, int /*role*/)
1015 {
1016 if (!index.isValid())
1017 return false;
1018
1019 m_routing[index.row()] = value.toInt();
1020
1021 emit dataChanged(index, index);
1022 return true;
1023 }
1024
1025
1026 QVariant ChannelRoutingModel::data ( const QModelIndex &index, int role ) const
1027 {
1028 if (!index.isValid())
1029 return QVariant();
1030 if (role != Qt::DisplayRole)
1031 return QVariant();
1032 if (index.column() != 0)
1033 return QVariant();
1034
1035 ChannelRoutingItem item;
1036
1037 // The common device port item list.
1038 DevicePortList& ports = m_pDevice->ports();
1039 QListIterator<DevicePort *> iter(ports);
1040 while (iter.hasNext()) {
1041 DevicePort *pPort = iter.next();
1042 item.options.append(
1043 m_pDevice->deviceTypeName()
1044 + ' ' + m_pDevice->driverName()
1045 + ' ' + pPort->portName()
1046 );
1047 }
1048
1049 item.selection = m_routing[index.row()];
1050
1051 return QVariant::fromValue(item);
1052 }
1053
1054
1055 QVariant ChannelRoutingModel::headerData ( int section,
1056 Qt::Orientation orientation, int role) const
1057 {
1058 if (role != Qt::DisplayRole)
1059 return QVariant();
1060
1061 switch (orientation) {
1062 case Qt::Horizontal:
1063 return UNICODE_RIGHT_ARROW + QObject::tr(" Device Channel");
1064 case Qt::Vertical:
1065 return QObject::tr("Audio Channel ") +
1066 QString::number(section) + " " + UNICODE_RIGHT_ARROW;
1067 default:
1068 return QVariant();
1069 }
1070 }
1071
1072
1073 void ChannelRoutingModel::refresh ( Device *pDevice,
1074 const ChannelRoutingMap& routing )
1075 {
1076 m_pDevice = pDevice;
1077 m_routing = routing;
1078 // inform the outer world (QTableView) that our data changed
1079 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1080 QAbstractTableModel::reset();
1081 #else
1082 QAbstractTableModel::beginResetModel();
1083 QAbstractTableModel::endResetModel();
1084 #endif
1085 }
1086
1087
1088 //-------------------------------------------------------------------------
1089 // QSampler::ChannelRoutingDelegate - table cell renderer for audio routing
1090 //
1091
1092 ChannelRoutingDelegate::ChannelRoutingDelegate ( QObject *pParent )
1093 : QItemDelegate(pParent)
1094 {
1095 }
1096
1097
1098 QWidget* ChannelRoutingDelegate::createEditor ( QWidget *pParent,
1099 const QStyleOptionViewItem & option, const QModelIndex& index ) const
1100 {
1101 if (!index.isValid())
1102 return nullptr;
1103
1104 if (index.column() != 0)
1105 return nullptr;
1106
1107 ChannelRoutingItem item = index.model()->data(index, Qt::DisplayRole).value<ChannelRoutingItem>();
1108
1109 QComboBox* pComboBox = new QComboBox(pParent);
1110 pComboBox->addItems(item.options);
1111 pComboBox->setCurrentIndex(item.selection);
1112 pComboBox->setEnabled(true);
1113 pComboBox->setEditable(true);
1114 pComboBox->setGeometry(option.rect);
1115 return pComboBox;
1116 }
1117
1118
1119 void ChannelRoutingDelegate::setEditorData ( QWidget *pEditor,
1120 const QModelIndex &index) const
1121 {
1122 ChannelRoutingItem item = index.model()->data(index,
1123 Qt::DisplayRole).value<ChannelRoutingItem> ();
1124 QComboBox* pComboBox = static_cast<QComboBox*> (pEditor);
1125 pComboBox->setCurrentIndex(item.selection);
1126 }
1127
1128
1129 void ChannelRoutingDelegate::setModelData ( QWidget* pEditor,
1130 QAbstractItemModel *pModel, const QModelIndex& index ) const
1131 {
1132 QComboBox *pComboBox = static_cast<QComboBox*> (pEditor);
1133 pModel->setData(index, pComboBox->currentIndex());
1134 }
1135
1136
1137 void ChannelRoutingDelegate::updateEditorGeometry ( QWidget *pEditor,
1138 const QStyleOptionViewItem& option, const QModelIndex &/* index */) const
1139 {
1140 pEditor->setGeometry(option.rect);
1141 }
1142
1143 } // namespace QSampler
1144
1145
1146 // end of qsamplerChannel.cpp

  ViewVC Help
Powered by ViewVC