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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC