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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 414 - (show annotations) (download)
Tue Mar 1 10:31:09 2005 UTC (15 years, 1 month ago) by capela
File size: 17885 byte(s)
* Fixed device driver type channel information gathering,
  which was severely flawed, dropping all channel session
  configurations to the default audio driver type (which
  is ALSA) unexpectedly.

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

  ViewVC Help
Powered by ViewVC