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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1499 - (show annotations) (download)
Tue Nov 20 16:48:04 2007 UTC (16 years, 5 months ago) by capela
File size: 32626 byte(s)
* Qt4 migration: one first step forward to kiss Qt3Support goodbye.

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

  ViewVC Help
Powered by ViewVC