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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 980 - (show annotations) (download)
Sun Dec 17 22:29:29 2006 UTC (17 years, 4 months ago) by capela
File size: 30294 byte(s)
* Revised and extended MIDI instrument mapping feature; this time
  two (2) MIDI maps are being implicitly created, ones designated
  as 'Chromatic' (0) and another as 'Drum Kits' (1), which can be
  assigned to each sampler channel. (ATTN: this commit elevates the
  requirements for liblscp >= 0.5.0, also on todays CVS and pending
  proper release very soon).

1 // qsamplerDevice.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2006, 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 along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 *****************************************************************************/
21
22 #include "qsamplerAbout.h"
23 #include "qsamplerDevice.h"
24
25 #include "qsamplerMainForm.h"
26 #include "qsamplerDeviceForm.h"
27
28 #include <qspinbox.h>
29 #include <qlineedit.h>
30
31
32 //-------------------------------------------------------------------------
33 // qsamplerDeviceParam - MIDI/Audio Device parameter structure.
34 //
35
36 // Constructors.
37 qsamplerDeviceParam::qsamplerDeviceParam ( lscp_param_info_t *pParamInfo,
38 const char *pszValue )
39 {
40 setParam(pParamInfo, pszValue);
41 }
42
43
44 // Default destructor.
45 qsamplerDeviceParam::~qsamplerDeviceParam (void)
46 {
47 }
48
49
50 // Initializer.
51 void qsamplerDeviceParam::setParam ( lscp_param_info_t *pParamInfo,
52 const char *pszValue )
53 {
54 if (pParamInfo == NULL)
55 return;
56
57 // Info structure field members.
58
59 type = pParamInfo->type;
60
61 if (pParamInfo->description)
62 description = pParamInfo->description;
63 else
64 description = QString::null;
65
66 mandatory = (bool) pParamInfo->mandatory;
67 fix = (bool) pParamInfo->fix;
68 multiplicity = (bool) pParamInfo->multiplicity;
69
70 depends.clear();
71 for (int i = 0; pParamInfo->depends && pParamInfo->depends[i]; i++)
72 depends.append(pParamInfo->depends[i]);
73
74 if (pParamInfo->defaultv)
75 defaultv = pParamInfo->defaultv;
76 else
77 defaultv = QString::null;
78
79 if (pParamInfo->range_min)
80 range_min = pParamInfo->range_min;
81 else
82 range_min = QString::null;
83
84 if (pParamInfo->range_max)
85 range_max = pParamInfo->range_max;
86 else
87 range_max = QString::null;
88
89 possibilities.clear();
90 for (int i = 0; pParamInfo->possibilities && pParamInfo->possibilities[i]; i++)
91 possibilities.append(pParamInfo->possibilities[i]);
92
93 // The current parameter value.
94 if (pszValue)
95 value = pszValue;
96 else
97 value = QString::null;
98 }
99
100
101 //-------------------------------------------------------------------------
102 // qsamplerDevice - MIDI/Audio Device structure.
103 //
104
105 // Constructor.
106 qsamplerDevice::qsamplerDevice ( qsamplerDeviceType deviceType, int iDeviceID )
107 {
108 m_ports.setAutoDelete(true);
109
110 setDevice(deviceType, iDeviceID);
111 }
112
113 // Default destructor.
114 qsamplerDevice::~qsamplerDevice (void)
115 {
116 }
117
118 // Copy constructor.
119 qsamplerDevice::qsamplerDevice ( const qsamplerDevice& device )
120 : m_params(device.m_params), m_ports(m_ports)
121 {
122 m_iDeviceID = device.m_iDeviceID;
123 m_deviceType = device.m_deviceType;
124 m_sDeviceType = device.m_sDeviceType;
125 m_sDriverName = device.m_sDriverName;
126 m_sDeviceName = device.m_sDeviceName;
127 }
128
129
130 // Initializer.
131 void qsamplerDevice::setDevice ( qsamplerDeviceType deviceType, int iDeviceID )
132 {
133 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
134 if (pMainForm == NULL)
135 return;
136 if (pMainForm->client() == NULL)
137 return;
138
139 // Device id and type should be always set.
140 m_iDeviceID = iDeviceID;
141 m_deviceType = deviceType;
142
143 // Reset device parameters and ports anyway.
144 m_params.clear();
145 m_ports.clear();
146
147 // Retrieve device info, if any.
148 lscp_device_info_t *pDeviceInfo = NULL;
149 switch (deviceType) {
150 case qsamplerDevice::Audio:
151 m_sDeviceType = QObject::tr("Audio");
152 if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_audio_device_info(
153 pMainForm->client(), m_iDeviceID)) == NULL)
154 appendMessagesClient("lscp_get_audio_device_info");
155 break;
156 case qsamplerDevice::Midi:
157 m_sDeviceType = QObject::tr("MIDI");
158 if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_midi_device_info(
159 pMainForm->client(), m_iDeviceID)) == NULL)
160 appendMessagesClient("lscp_get_midi_device_info");
161 break;
162 case qsamplerDevice::None:
163 m_sDeviceType = QString::null;
164 break;
165 }
166 // If we're bogus, bail out...
167 if (pDeviceInfo == NULL) {
168 m_sDriverName = QString::null;
169 m_sDeviceName = QObject::tr("New %1 device").arg(m_sDeviceType);
170 return;
171 }
172
173 // Other device properties...
174 m_sDriverName = pDeviceInfo->driver;
175 m_sDeviceName = m_sDriverName + ' '
176 + QObject::tr("Device %1").arg(m_iDeviceID);
177
178 // Grab device parameters...
179 for (int i = 0; pDeviceInfo->params && pDeviceInfo->params[i].key; i++) {
180 const QString sParam = pDeviceInfo->params[i].key;
181 lscp_param_info_t *pParamInfo = NULL;
182 switch (deviceType) {
183 case qsamplerDevice::Audio:
184 if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),
185 m_sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)
186 appendMessagesClient("lscp_get_audio_driver_param_info");
187 break;
188 case qsamplerDevice::Midi:
189 if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),
190 m_sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)
191 appendMessagesClient("lscp_get_midi_driver_param_info");
192 break;
193 case qsamplerDevice::None:
194 break;
195 }
196 if (pParamInfo) {
197 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
198 pDeviceInfo->params[i].value);
199 }
200 }
201
202 // Refresh parameter dependencies...
203 refreshParams();
204 // Set port/channel list...
205 refreshPorts();
206 }
207
208
209 // Driver name initializer/settler.
210 void qsamplerDevice::setDriver ( const QString& sDriverName )
211 {
212 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
213 if (pMainForm == NULL)
214 return;
215 if (pMainForm->client() == NULL)
216 return;
217
218 // Valid only for scratch devices.
219 if (m_sDriverName == sDriverName)
220 return;
221
222 // Reset device parameters and ports anyway.
223 m_params.clear();
224 m_ports.clear();
225
226 // Retrieve driver info, if any.
227 lscp_driver_info_t *pDriverInfo = NULL;
228 switch (m_deviceType) {
229 case qsamplerDevice::Audio:
230 if ((pDriverInfo = ::lscp_get_audio_driver_info(pMainForm->client(),
231 sDriverName.latin1())) == NULL)
232 appendMessagesClient("lscp_get_audio_driver_info");
233 break;
234 case qsamplerDevice::Midi:
235 if ((pDriverInfo = ::lscp_get_midi_driver_info(pMainForm->client(),
236 sDriverName.latin1())) == NULL)
237 appendMessagesClient("lscp_get_midi_driver_info");
238 break;
239 case qsamplerDevice::None:
240 break;
241 }
242
243 // If we're bogus, bail out...
244 if (pDriverInfo == NULL)
245 return;
246
247 // Remember device parameters...
248 m_sDriverName = sDriverName;
249
250 // Grab driver parameters...
251 for (int i = 0; pDriverInfo->parameters && pDriverInfo->parameters[i]; i++) {
252 const QString sParam = pDriverInfo->parameters[i];
253 lscp_param_info_t *pParamInfo = NULL;
254 switch (m_deviceType) {
255 case qsamplerDevice::Audio:
256 if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),
257 sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)
258 appendMessagesClient("lscp_get_audio_driver_param_info");
259 break;
260 case qsamplerDevice::Midi:
261 if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),
262 sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)
263 appendMessagesClient("lscp_get_midi_driver_param_info");
264 break;
265 case qsamplerDevice::None:
266 break;
267 }
268 if (pParamInfo) {
269 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
270 pParamInfo->defaultv);
271 }
272 }
273
274 // Refresh parameter dependencies...
275 refreshParams();
276 // Set port/channel list...
277 refreshPorts();
278 }
279
280
281 // Device property accessors.
282 int qsamplerDevice::deviceID (void) const
283 {
284 return m_iDeviceID;
285 }
286
287 qsamplerDevice::qsamplerDeviceType qsamplerDevice::deviceType (void) const
288 {
289 return m_deviceType;
290 }
291
292 const QString& qsamplerDevice::deviceTypeName (void) const
293 {
294 return m_sDeviceType;
295 }
296
297 const QString& qsamplerDevice::driverName (void) const
298 {
299 return m_sDriverName;
300 }
301
302 // Special device name formatter.
303 QString qsamplerDevice::deviceName (void) const
304 {
305 QString sPrefix;
306 if (m_iDeviceID >= 0)
307 sPrefix += m_sDeviceType + ' ';
308 return sPrefix + m_sDeviceName;
309 }
310
311
312 // Set the proper device parameter value.
313 bool qsamplerDevice::setParam ( const QString& sParam,
314 const QString& sValue )
315 {
316 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
317 if (pMainForm == NULL)
318 return false;
319 if (pMainForm->client() == NULL)
320 return false;
321
322 // Set proper device parameter.
323 m_params[sParam.upper()].value = sValue;
324
325 // If the device already exists, things get immediate...
326 int iRefresh = 0;
327 if (m_iDeviceID >= 0) {
328 // Prepare parameter struct.
329 lscp_param_t param;
330 param.key = (char *) sParam.latin1();
331 param.value = (char *) sValue.latin1();
332 // Now it depends on the device type...
333 lscp_status_t ret = LSCP_FAILED;
334 switch (m_deviceType) {
335 case qsamplerDevice::Audio:
336 if (sParam == "CHANNELS") iRefresh++;
337 if ((ret = ::lscp_set_audio_device_param(pMainForm->client(),
338 m_iDeviceID, &param)) != LSCP_OK)
339 appendMessagesClient("lscp_set_audio_device_param");
340 break;
341 case qsamplerDevice::Midi:
342 if (sParam == "PORTS") iRefresh++;
343 if ((ret = ::lscp_set_midi_device_param(pMainForm->client(),
344 m_iDeviceID, &param)) != LSCP_OK)
345 appendMessagesClient("lscp_set_midi_device_param");
346 break;
347 case qsamplerDevice::None:
348 break;
349 }
350 // Show result.
351 if (ret == LSCP_OK) {
352 appendMessages(QString("%1: %2.").arg(sParam).arg(sValue));
353 // Special care for specific parameter changes...
354 if (iRefresh > 0)
355 iRefresh += refreshPorts();
356 iRefresh += refreshDepends(sParam);
357 } else {
358 // Oops...
359 appendMessagesError(
360 QObject::tr("Could not set device parameter value.\n\nSorry."));
361 }
362 }
363
364 // Return whether we're need a view refresh.
365 return (iRefresh > 0);
366 }
367
368
369 // Device parameter accessor.
370 const qsamplerDeviceParamMap& qsamplerDevice::params (void) const
371 {
372 return m_params;
373 }
374
375
376 // Device port/channel list accessor.
377 qsamplerDevicePortList& qsamplerDevice::ports (void)
378 {
379 return m_ports;
380 }
381
382
383 // Create a new device, as a copy of this current one.
384 bool qsamplerDevice::createDevice (void)
385 {
386 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
387 if (pMainForm == NULL)
388 return false;
389 if (pMainForm->client() == NULL)
390 return false;
391
392 // Build the parameter list...
393 lscp_param_t *pParams = new lscp_param_t [m_params.count() + 1];
394 int iParam = 0;
395 qsamplerDeviceParamMap::ConstIterator iter;
396 for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
397 pParams[iParam].key = (char *) iter.key().latin1();
398 pParams[iParam].value = (char *) iter.data().value.latin1();
399 ++iParam;
400 }
401 // Null terminated.
402 pParams[iParam].key = NULL;
403 pParams[iParam].value = NULL;
404
405 // Now it depends on the device type...
406 switch (m_deviceType) {
407 case qsamplerDevice::Audio:
408 if ((m_iDeviceID = ::lscp_create_audio_device(pMainForm->client(),
409 m_sDriverName.latin1(), pParams)) < 0)
410 appendMessagesClient("lscp_create_audio_device");
411 break;
412 case qsamplerDevice::Midi:
413 if ((m_iDeviceID = ::lscp_create_midi_device(pMainForm->client(),
414 m_sDriverName.latin1(), pParams)) < 0)
415 appendMessagesClient("lscp_create_midi_device");
416 break;
417 case qsamplerDevice::None:
418 break;
419 }
420
421 // Free used parameter array.
422 delete pParams;
423
424 // Show result.
425 if (m_iDeviceID >= 0) {
426 // Refresh our own stuff...
427 setDevice(m_deviceType, m_iDeviceID);
428 appendMessages(QObject::tr("created."));
429 } else {
430 appendMessagesError(QObject::tr("Could not create device.\n\nSorry."));
431 }
432
433 // Return whether we're a valid device...
434 return (m_iDeviceID >= 0);
435 }
436
437
438 // Destroy existing device.
439 bool qsamplerDevice::deleteDevice (void)
440 {
441 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
442 if (pMainForm == NULL)
443 return false;
444 if (pMainForm->client() == NULL)
445 return false;
446
447 // Now it depends on the device type...
448 lscp_status_t ret = LSCP_FAILED;
449 switch (m_deviceType) {
450 case qsamplerDevice::Audio:
451 if ((ret = ::lscp_destroy_audio_device(pMainForm->client(),
452 m_iDeviceID)) != LSCP_OK)
453 appendMessagesClient("lscp_destroy_audio_device");
454 break;
455 case qsamplerDevice::Midi:
456 if ((ret = ::lscp_destroy_midi_device(pMainForm->client(),
457 m_iDeviceID)) != LSCP_OK)
458 appendMessagesClient("lscp_destroy_midi_device");
459 break;
460 case qsamplerDevice::None:
461 break;
462 }
463
464 // Show result.
465 if (ret == LSCP_OK) {
466 appendMessages(QObject::tr("deleted."));
467 m_iDeviceID = -1;
468 } else {
469 appendMessagesError(QObject::tr("Could not delete device.\n\nSorry."));
470 }
471
472 // Return whether we've done it..
473 return (ret == LSCP_OK);
474 }
475
476
477 // Device parameter dependencies refreshner.
478 int qsamplerDevice::refreshParams (void)
479 {
480 // This should only make sense for scratch devices...
481 if (m_iDeviceID >= 0)
482 return 0;
483 // Refresh all parameters that have dependencies...
484 int iParams = 0;
485 qsamplerDeviceParamMap::ConstIterator iter;
486 for (iter = m_params.begin(); iter != m_params.end(); ++iter)
487 iParams += refreshParam(iter.key());
488 // Return how many parameters have been refreshed...
489 return iParams;
490 }
491
492
493 // Device port/channel list refreshner.
494 int qsamplerDevice::refreshPorts (void)
495 {
496 // This should only make sense for actual devices...
497 if (m_iDeviceID < 0)
498 return 0;
499 // Port/channel count determination...
500 int iPorts = 0;
501 switch (m_deviceType) {
502 case qsamplerDevice::Audio:
503 iPorts = m_params["CHANNELS"].value.toInt();
504 break;
505 case qsamplerDevice::Midi:
506 iPorts = m_params["PORTS"].value.toInt();
507 break;
508 case qsamplerDevice::None:
509 break;
510 }
511 // Retrieve port/channel information...
512 m_ports.clear();
513 for (int iPort = 0; iPort < iPorts; iPort++)
514 m_ports.append(new qsamplerDevicePort(*this, iPort));
515 // Return how many ports have been refreshed...
516 return iPorts;
517 }
518
519
520 // Refresh/set dependencies given that some parameter has changed.
521 int qsamplerDevice::refreshDepends ( const QString& sParam )
522 {
523 // This should only make sense for scratch devices...
524 if (m_iDeviceID >= 0)
525 return 0;
526 // Refresh all parameters that depend on this one...
527 int iDepends = 0;
528 qsamplerDeviceParamMap::ConstIterator iter;
529 for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
530 const QStringList& depends = iter.data().depends;
531 if (depends.find(sParam) != depends.end())
532 iDepends += refreshParam(iter.key());
533 }
534 // Return how many dependencies have been refreshed...
535 return iDepends;
536 }
537
538
539 // Refresh/set given parameter based on driver supplied dependencies.
540 int qsamplerDevice::refreshParam ( const QString& sParam )
541 {
542 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
543 if (pMainForm == NULL)
544 return 0;
545 if (pMainForm->client() == NULL)
546 return 0;
547
548 // Check if we have dependencies...
549 qsamplerDeviceParam& param = m_params[sParam.upper()];
550 if (param.depends.isEmpty())
551 return 0;
552
553 int iRefresh = 0;
554
555 // Build dependency list...
556 lscp_param_t *pDepends = new lscp_param_t [param.depends.count() + 1];
557 int iDepend = 0;
558 QStringList::ConstIterator iter;
559 for (iter = param.depends.begin(); iter != param.depends.end(); ++iter) {
560 const QString& sDepend = *iter;
561 pDepends[iDepend].key = (char *) sDepend.latin1();
562 pDepends[iDepend].value = (char *) m_params[sDepend.upper()].value.latin1();
563 ++iDepend;
564 }
565 // Null terminated.
566 pDepends[iDepend].key = NULL;
567 pDepends[iDepend].value = NULL;
568
569 // FIXME: Some parameter dependencies (e.g.ALSA CARD)
570 // are blocking for no reason, causing potential timeout-crashes.
571 // hopefully this gets mitigated if this dependency hell is only
572 // carried out for scratch devices...
573
574 // Retrieve some modern parameters...
575 lscp_param_info_t *pParamInfo = NULL;
576 switch (m_deviceType) {
577 case qsamplerDevice::Audio:
578 if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),
579 m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)
580 appendMessagesClient("lscp_get_audio_driver_param_info");
581 break;
582 case qsamplerDevice::Midi:
583 if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),
584 m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)
585 appendMessagesClient("lscp_get_midi_driver_param_info");
586 break;
587 case qsamplerDevice::None:
588 break;
589 }
590 if (pParamInfo) {
591 param = qsamplerDeviceParam(pParamInfo, QString(param.value));
592 iRefresh++;
593 }
594
595 // Free used parameter array.
596 delete pDepends;
597
598 // Return whether the parameters has been changed...
599 return iRefresh;
600 }
601
602
603 // Redirected messages output methods.
604 void qsamplerDevice::appendMessages( const QString& s ) const
605 {
606 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
607 if (pMainForm)
608 pMainForm->appendMessages(deviceName() + ' ' + s);
609 }
610
611 void qsamplerDevice::appendMessagesColor( const QString& s,
612 const QString& c ) const
613 {
614 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
615 if (pMainForm)
616 pMainForm->appendMessagesColor(deviceName() + ' ' + s, c);
617 }
618
619 void qsamplerDevice::appendMessagesText( const QString& s ) const
620 {
621 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
622 if (pMainForm)
623 pMainForm->appendMessagesText(deviceName() + ' ' + s);
624 }
625
626 void qsamplerDevice::appendMessagesError( const QString& s ) const
627 {
628 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
629 if (pMainForm)
630 pMainForm->appendMessagesError(deviceName() + "\n\n" + s);
631 }
632
633 void qsamplerDevice::appendMessagesClient( const QString& s ) const
634 {
635 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
636 if (pMainForm)
637 pMainForm->appendMessagesClient(deviceName() + ' ' + s);
638 }
639
640
641 // Device ids enumerator.
642 int *qsamplerDevice::getDevices ( lscp_client_t *pClient,
643 qsamplerDeviceType deviceType )
644 {
645 int *piDeviceIDs = NULL;
646 switch (deviceType) {
647 case qsamplerDevice::Audio:
648 piDeviceIDs = ::lscp_list_audio_devices(pClient);
649 break;
650 case qsamplerDevice::Midi:
651 piDeviceIDs = ::lscp_list_midi_devices(pClient);
652 break;
653 case qsamplerDevice::None:
654 break;
655 }
656 return piDeviceIDs;
657 }
658
659
660 // Driver names enumerator.
661 QStringList qsamplerDevice::getDrivers ( lscp_client_t *pClient,
662 qsamplerDeviceType deviceType )
663 {
664 QStringList drivers;
665
666 const char **ppszDrivers = NULL;
667 switch (deviceType) {
668 case qsamplerDevice::Audio:
669 ppszDrivers = ::lscp_list_available_audio_drivers(pClient);
670 break;
671 case qsamplerDevice::Midi:
672 ppszDrivers = ::lscp_list_available_midi_drivers(pClient);
673 break;
674 case qsamplerDevice::None:
675 break;
676 }
677
678 for (int iDriver = 0; ppszDrivers && ppszDrivers[iDriver]; iDriver++)
679 drivers.append(ppszDrivers[iDriver]);
680
681 return drivers;
682 }
683
684
685 //-------------------------------------------------------------------------
686 // qsamplerDevicePort - MIDI/Audio Device port/channel structure.
687 //
688
689 // Constructor.
690 qsamplerDevicePort::qsamplerDevicePort ( qsamplerDevice& device,
691 int iPortID ) : m_device(device)
692 {
693 setDevicePort(iPortID);
694 }
695
696 // Default destructor.
697 qsamplerDevicePort::~qsamplerDevicePort (void)
698 {
699 }
700
701
702 // Initializer.
703 void qsamplerDevicePort::setDevicePort ( int iPortID )
704 {
705 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
706 if (pMainForm == NULL)
707 return;
708 if (pMainForm->client() == NULL)
709 return;
710
711 // Device port id should be always set.
712 m_iPortID = iPortID;
713
714 // Reset port parameters anyway.
715 m_params.clear();
716
717 // Retrieve device port/channel info, if any.
718 lscp_device_port_info_t *pPortInfo = NULL;
719 switch (m_device.deviceType()) {
720 case qsamplerDevice::Audio:
721 if ((pPortInfo = ::lscp_get_audio_channel_info(pMainForm->client(),
722 m_device.deviceID(), m_iPortID)) == NULL)
723 m_device.appendMessagesClient("lscp_get_audio_channel_info");
724 break;
725 case qsamplerDevice::Midi:
726 if ((pPortInfo = ::lscp_get_midi_port_info(pMainForm->client(),
727 m_device.deviceID(), m_iPortID)) == NULL)
728 m_device.appendMessagesClient("lscp_get_midi_port_info");
729 break;
730 case qsamplerDevice::None:
731 break;
732 }
733
734 // If we're bogus, bail out...
735 if (pPortInfo == NULL) {
736 m_sPortName = QString::null;
737 return;
738 }
739
740 // Set device port/channel properties...
741 m_sPortName = pPortInfo->name;
742
743 // Grab device port/channel parameters...
744 m_params.clear();
745 for (int i = 0; pPortInfo->params && pPortInfo->params[i].key; i++) {
746 const QString sParam = pPortInfo->params[i].key;
747 lscp_param_info_t *pParamInfo = NULL;
748 switch (m_device.deviceType()) {
749 case qsamplerDevice::Audio:
750 if ((pParamInfo = ::lscp_get_audio_channel_param_info(
751 pMainForm->client(), m_device.deviceID(),
752 m_iPortID, sParam.latin1())) == NULL)
753 m_device.appendMessagesClient("lscp_get_audio_channel_param_info");
754 break;
755 case qsamplerDevice::Midi:
756 if ((pParamInfo = ::lscp_get_midi_port_param_info(
757 pMainForm->client(), m_device.deviceID(),
758 m_iPortID, sParam.latin1())) == NULL)
759 m_device.appendMessagesClient("lscp_get_midi_port_param_info");
760 break;
761 case qsamplerDevice::None:
762 break;
763 }
764 if (pParamInfo) {
765 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
766 pPortInfo->params[i].value);
767 }
768 }
769 }
770
771
772 // Device port/channel property accessors.
773 int qsamplerDevicePort::portID (void) const
774 {
775 return m_iPortID;
776 }
777
778 const QString& qsamplerDevicePort::portName (void) const
779 {
780 return m_sPortName;
781 }
782
783 // Device port/channel parameter accessor.
784 const qsamplerDeviceParamMap& qsamplerDevicePort::params (void) const
785 {
786 return m_params;
787 }
788
789
790 // Set the proper device port/channel parameter value.
791 bool qsamplerDevicePort::setParam ( const QString& sParam,
792 const QString& sValue )
793 {
794 qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
795 if (pMainForm == NULL)
796 return false;
797 if (pMainForm->client() == NULL)
798 return false;
799
800 // Set proper port/channel parameter.
801 m_params[sParam.upper()].value = sValue;
802
803 // If the device already exists, things get immediate...
804 int iRefresh = 0;
805 if (m_device.deviceID() >= 0 && m_iPortID >= 0) {
806 // Prepare parameter struct.
807 lscp_param_t param;
808 param.key = (char *) sParam.latin1();
809 param.value = (char *) sValue.latin1();
810 // Now it depends on the device type...
811 lscp_status_t ret = LSCP_FAILED;
812 switch (m_device.deviceType()) {
813 case qsamplerDevice::Audio:
814 if ((ret = ::lscp_set_audio_channel_param(pMainForm->client(),
815 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
816 m_device.appendMessagesClient("lscp_set_audio_channel_param");
817 break;
818 case qsamplerDevice::Midi:
819 if ((ret = ::lscp_set_midi_port_param(pMainForm->client(),
820 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
821 m_device.appendMessagesClient("lscp_set_midi_port_param");
822 break;
823 case qsamplerDevice::None:
824 break;
825 }
826 // Show result.
827 if (ret == LSCP_OK) {
828 m_device.appendMessages(m_sPortName
829 + ' ' + QString("%1: %2.").arg(sParam).arg(sValue));
830 iRefresh++;
831 } else {
832 m_device.appendMessagesError(
833 QObject::tr("Could not set %1 parameter value.\n\n"
834 "Sorry.").arg(m_sPortName));
835 }
836 }
837
838 // Return whether we're need a view refresh.
839 return (iRefresh > 0);
840 }
841
842
843 //-------------------------------------------------------------------------
844 // qsamplerDeviceItem - QListView device item.
845 //
846
847 // Constructors.
848 qsamplerDeviceItem::qsamplerDeviceItem ( QListView *pListView,
849 qsamplerDevice::qsamplerDeviceType deviceType )
850 : QListViewItem(pListView), m_device(deviceType)
851 {
852 switch(m_device.deviceType()) {
853 case qsamplerDevice::Audio:
854 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio1.png"));
855 QListViewItem::setText(0, QObject::tr("Audio Devices"));
856 break;
857 case qsamplerDevice::Midi:
858 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi1.png"));
859 QListViewItem::setText(0, QObject::tr("MIDI Devices"));
860 break;
861 case qsamplerDevice::None:
862 break;
863 }
864 }
865
866 qsamplerDeviceItem::qsamplerDeviceItem ( QListViewItem *pItem,
867 qsamplerDevice::qsamplerDeviceType deviceType,
868 int iDeviceID )
869 : QListViewItem(pItem), m_device(deviceType, iDeviceID)
870 {
871 switch(m_device.deviceType()) {
872 case qsamplerDevice::Audio:
873 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio2.png"));
874 break;
875 case qsamplerDevice::Midi:
876 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi2.png"));
877 break;
878 case qsamplerDevice::None:
879 break;
880 }
881
882 QListViewItem::setText(0, m_device.deviceName());
883 }
884
885 // Default destructor.
886 qsamplerDeviceItem::~qsamplerDeviceItem (void)
887 {
888 }
889
890 // Instance accessors.
891 qsamplerDevice& qsamplerDeviceItem::device (void)
892 {
893 return m_device;
894 }
895
896 // To virtually distinguish between list view items.
897 int qsamplerDeviceItem::rtti() const
898 {
899 return QSAMPLER_DEVICE_ITEM;
900 }
901
902
903
904 //-------------------------------------------------------------------------
905 // qsamplerDeviceParamTable - Device parameter view table.
906 //
907
908 // Constructor.
909 qsamplerDeviceParamTable::qsamplerDeviceParamTable ( QWidget *pParent,
910 const char *pszName )
911 : QTable(pParent, pszName)
912 {
913 // Set fixed number of columns.
914 QTable::setNumCols(3);
915 QTable::setShowGrid(false);
916 QTable::setSorting(false);
917 QTable::setFocusStyle(QTable::FollowStyle);
918 QTable::setSelectionMode(QTable::NoSelection);
919 // No vertical header.
920 QTable::verticalHeader()->hide();
921 QTable::setLeftMargin(0);
922 // Initialize the fixed table column headings.
923 QHeader *pHeader = QTable::horizontalHeader();
924 pHeader->setLabel(0, tr("Parameter"));
925 pHeader->setLabel(1, tr("Description"));
926 pHeader->setLabel(2, tr("Value"));
927 // Set read-onlyness of each column
928 QTable::setColumnReadOnly(0, true);
929 QTable::setColumnReadOnly(1, true);
930 // QTable::setColumnReadOnly(2, false); -- of course not.
931 QTable::setColumnStretchable(1, true);
932 }
933
934 // Default destructor.
935 qsamplerDeviceParamTable::~qsamplerDeviceParamTable (void)
936 {
937 }
938
939
940 // Common parameter table renderer.
941 void qsamplerDeviceParamTable::refresh ( const qsamplerDeviceParamMap& params,
942 bool bEditable )
943 {
944 // Always (re)start it empty.
945 QTable::setUpdatesEnabled(false);
946 QTable::setNumRows(0);
947
948 // Fill the parameter table...
949 QTable::insertRows(0, params.count());
950 int iRow = 0;
951 qsamplerDeviceParamMap::ConstIterator iter;
952 for (iter = params.begin(); iter != params.end(); ++iter) {
953 const qsamplerDeviceParam& param = iter.data();
954 bool bEnabled = (bEditable || !param.fix);
955 QTable::setText(iRow, 0, iter.key());
956 QTable::setText(iRow, 1, param.description);
957 if (param.type == LSCP_TYPE_BOOL) {
958 QStringList opts;
959 opts.append(tr("false"));
960 opts.append(tr("true"));
961 QComboTableItem *pComboItem = new QComboTableItem(this, opts);
962 pComboItem->setCurrentItem(param.value.lower() == "true" ? 1 : 0);
963 pComboItem->setEnabled(bEnabled);
964 QTable::setItem(iRow, 2, pComboItem);
965 } else if (param.possibilities.count() > 0 && bEnabled) {
966 QStringList opts = param.possibilities;
967 if (param.multiplicity)
968 opts.prepend(tr("(none)"));
969 QComboTableItem *pComboItem = new QComboTableItem(this, opts);
970 if (param.value.isEmpty())
971 pComboItem->setCurrentItem(0);
972 else
973 pComboItem->setCurrentItem(param.value);
974 pComboItem->setEnabled(bEnabled);
975 QTable::setItem(iRow, 2, pComboItem);
976 } else if (param.type == LSCP_TYPE_INT && bEnabled
977 && !param.range_min.isEmpty()
978 && !param.range_max.isEmpty()) {
979 qsamplerDeviceParamTableSpinBox *pSpinItem =
980 new qsamplerDeviceParamTableSpinBox(this,
981 bEnabled ? QTableItem::OnTyping : QTableItem::Never,
982 param.value);
983 pSpinItem->setMinValue(param.range_min.toInt());
984 pSpinItem->setMaxValue(param.range_max.toInt());
985 QTable::setItem(iRow, 2, pSpinItem);
986 } else {
987 qsamplerDeviceParamTableEditBox *pEditItem =
988 new qsamplerDeviceParamTableEditBox(this,
989 bEnabled ? QTableItem::OnTyping : QTableItem::Never,
990 param.value);
991 QTable::setItem(iRow, 2, pEditItem);
992 }
993 ++iRow;
994 }
995
996 // Adjust optimal column widths.
997 QTable::adjustColumn(0);
998 QTable::adjustColumn(2);
999
1000 QTable::setUpdatesEnabled(true);
1001 QTable::updateContents();
1002 }
1003
1004
1005 //-------------------------------------------------------------------------
1006 // qsamplerDeviceParamTableSpinBox - Custom spin box for parameter table.
1007 //
1008
1009 // Constructor.
1010 qsamplerDeviceParamTableSpinBox::qsamplerDeviceParamTableSpinBox (
1011 QTable *pTable, EditType editType, const QString& sText )
1012 : QTableItem(pTable, editType, sText)
1013 {
1014 m_iValue = sText.toInt();
1015 m_iMinValue = m_iMaxValue = 0;
1016 }
1017
1018 // Public accessors.
1019 void qsamplerDeviceParamTableSpinBox::setValue ( int iValue )
1020 {
1021 m_iValue = iValue;
1022 QTableItem::setText(QString::number(m_iValue));
1023 }
1024
1025 void qsamplerDeviceParamTableSpinBox::setMinValue ( int iMinValue )
1026 {
1027 m_iMinValue = iMinValue;
1028 }
1029
1030 void qsamplerDeviceParamTableSpinBox::setMaxValue ( int iMaxValue )
1031 {
1032 m_iMaxValue = iMaxValue;
1033 }
1034
1035 // Virtual implemetations.
1036 QWidget *qsamplerDeviceParamTableSpinBox::createEditor (void) const
1037 {
1038 QSpinBox *pSpinBox = new QSpinBox(QTableItem::table()->viewport());
1039 QObject::connect(pSpinBox, SIGNAL(valueChanged(int)),
1040 QTableItem::table(), SLOT(doValueChanged()));
1041 if (m_iValue >= m_iMinValue && m_iMaxValue >= m_iValue) {
1042 pSpinBox->setMinValue(m_iMinValue);
1043 pSpinBox->setMaxValue(m_iMaxValue);
1044 }
1045 pSpinBox->setValue(m_iValue);
1046 return pSpinBox;
1047 }
1048
1049 void qsamplerDeviceParamTableSpinBox::setContentFromEditor ( QWidget *pWidget )
1050 {
1051 if (pWidget->inherits("QSpinBox"))
1052 QTableItem::setText(QString::number(((QSpinBox *) pWidget)->value()));
1053 else
1054 QTableItem::setContentFromEditor(pWidget);
1055 }
1056
1057
1058 //-------------------------------------------------------------------------
1059 // qsamplerDeviceParamTableEditBox - Custom edit box for parameter table.
1060 //
1061
1062 // Constructor.
1063 qsamplerDeviceParamTableEditBox::qsamplerDeviceParamTableEditBox (
1064 QTable *pTable, EditType editType, const QString& sText )
1065 : QTableItem(pTable, editType, sText)
1066 {
1067 }
1068
1069 // Virtual implemetations.
1070 QWidget *qsamplerDeviceParamTableEditBox::createEditor (void) const
1071 {
1072 QLineEdit *pEditBox = new QLineEdit(QTableItem::table()->viewport());
1073 QObject::connect(pEditBox, SIGNAL(returnPressed()),
1074 QTableItem::table(), SLOT(doValueChanged()));
1075 pEditBox->setText(QTableItem::text());
1076 return pEditBox;
1077 }
1078
1079 void qsamplerDeviceParamTableEditBox::setContentFromEditor ( QWidget *pWidget )
1080 {
1081 if (pWidget->inherits("QLineEdit"))
1082 QTableItem::setText(((QLineEdit *) pWidget)->text());
1083 else
1084 QTableItem::setContentFromEditor(pWidget);
1085 }
1086
1087
1088 // end of qsamplerDevice.cpp
1089

  ViewVC Help
Powered by ViewVC