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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1477 - (show annotations) (download)
Mon Nov 12 01:33:13 2007 UTC (16 years, 4 months ago) by schoenebeck
File size: 34124 byte(s)
* again just a minor step for Qt4 port: couple fixes in device management
  list view

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

  ViewVC Help
Powered by ViewVC