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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1486 - (show annotations) (download)
Sat Nov 17 02:02:28 2007 UTC (16 years, 5 months ago) by schoenebeck
File size: 32169 byte(s)
* Qt4 migration: finished / fixed device management dialog.
* Fixed creation of devices (don't try to set device parameters which the
  user did not touch in the device creation dialog, this bug already
  existed in the Qt3 version of QSampler).

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 && sValue != QString::null) {
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 if (iter.data().value == QString::null) continue;
400 pParams[iParam].key = (char *) iter.key().latin1();
401 pParams[iParam].value = (char *) iter.data().value.latin1();
402 ++iParam;
403 }
404 // Null terminated.
405 pParams[iParam].key = NULL;
406 pParams[iParam].value = NULL;
407
408 // Now it depends on the device type...
409 switch (m_deviceType) {
410 case qsamplerDevice::Audio:
411 if ((m_iDeviceID = ::lscp_create_audio_device(pMainForm->client(),
412 m_sDriverName.latin1(), pParams)) < 0)
413 appendMessagesClient("lscp_create_audio_device");
414 break;
415 case qsamplerDevice::Midi:
416 if ((m_iDeviceID = ::lscp_create_midi_device(pMainForm->client(),
417 m_sDriverName.latin1(), pParams)) < 0)
418 appendMessagesClient("lscp_create_midi_device");
419 break;
420 case qsamplerDevice::None:
421 break;
422 }
423
424 // Free used parameter array.
425 delete pParams;
426
427 // Show result.
428 if (m_iDeviceID >= 0) {
429 // Refresh our own stuff...
430 setDevice(m_deviceType, m_iDeviceID);
431 appendMessages(QObject::tr("created."));
432 } else {
433 appendMessagesError(QObject::tr("Could not create device.\n\nSorry."));
434 }
435
436 // Return whether we're a valid device...
437 return (m_iDeviceID >= 0);
438 }
439
440
441 // Destroy existing device.
442 bool qsamplerDevice::deleteDevice (void)
443 {
444 MainForm *pMainForm = MainForm::getInstance();
445 if (pMainForm == NULL)
446 return false;
447 if (pMainForm->client() == NULL)
448 return false;
449
450 // Now it depends on the device type...
451 lscp_status_t ret = LSCP_FAILED;
452 switch (m_deviceType) {
453 case qsamplerDevice::Audio:
454 if ((ret = ::lscp_destroy_audio_device(pMainForm->client(),
455 m_iDeviceID)) != LSCP_OK)
456 appendMessagesClient("lscp_destroy_audio_device");
457 break;
458 case qsamplerDevice::Midi:
459 if ((ret = ::lscp_destroy_midi_device(pMainForm->client(),
460 m_iDeviceID)) != LSCP_OK)
461 appendMessagesClient("lscp_destroy_midi_device");
462 break;
463 case qsamplerDevice::None:
464 break;
465 }
466
467 // Show result.
468 if (ret == LSCP_OK) {
469 appendMessages(QObject::tr("deleted."));
470 m_iDeviceID = -1;
471 } else {
472 appendMessagesError(QObject::tr("Could not delete device.\n\nSorry."));
473 }
474
475 // Return whether we've done it..
476 return (ret == LSCP_OK);
477 }
478
479
480 // Device parameter dependencies refreshner.
481 int qsamplerDevice::refreshParams (void)
482 {
483 // This should only make sense for scratch devices...
484 if (m_iDeviceID >= 0)
485 return 0;
486 // Refresh all parameters that have dependencies...
487 int iParams = 0;
488 qsamplerDeviceParamMap::ConstIterator iter;
489 for (iter = m_params.begin(); iter != m_params.end(); ++iter)
490 iParams += refreshParam(iter.key());
491 // Return how many parameters have been refreshed...
492 return iParams;
493 }
494
495
496 // Device port/channel list refreshner.
497 int qsamplerDevice::refreshPorts (void)
498 {
499 // This should only make sense for actual devices...
500 if (m_iDeviceID < 0)
501 return 0;
502 // Port/channel count determination...
503 int iPorts = 0;
504 switch (m_deviceType) {
505 case qsamplerDevice::Audio:
506 iPorts = m_params["CHANNELS"].value.toInt();
507 break;
508 case qsamplerDevice::Midi:
509 iPorts = m_params["PORTS"].value.toInt();
510 break;
511 case qsamplerDevice::None:
512 break;
513 }
514 // Retrieve port/channel information...
515 m_ports.clear();
516 for (int iPort = 0; iPort < iPorts; iPort++)
517 m_ports.append(new qsamplerDevicePort(*this, iPort));
518 // Return how many ports have been refreshed...
519 return iPorts;
520 }
521
522
523 // Refresh/set dependencies given that some parameter has changed.
524 int qsamplerDevice::refreshDepends ( const QString& sParam )
525 {
526 // This should only make sense for scratch devices...
527 if (m_iDeviceID >= 0)
528 return 0;
529 // Refresh all parameters that depend on this one...
530 int iDepends = 0;
531 qsamplerDeviceParamMap::ConstIterator iter;
532 for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
533 const QStringList& depends = iter.data().depends;
534 if (depends.find(sParam) != depends.end())
535 iDepends += refreshParam(iter.key());
536 }
537 // Return how many dependencies have been refreshed...
538 return iDepends;
539 }
540
541
542 // Refresh/set given parameter based on driver supplied dependencies.
543 int qsamplerDevice::refreshParam ( const QString& sParam )
544 {
545 MainForm *pMainForm = MainForm::getInstance();
546 if (pMainForm == NULL)
547 return 0;
548 if (pMainForm->client() == NULL)
549 return 0;
550
551 // Check if we have dependencies...
552 qsamplerDeviceParam& param = m_params[sParam.upper()];
553 if (param.depends.isEmpty())
554 return 0;
555
556 int iRefresh = 0;
557
558 // Build dependency list...
559 lscp_param_t *pDepends = new lscp_param_t [param.depends.count() + 1];
560 int iDepend = 0;
561 QStringList::ConstIterator iter;
562 for (iter = param.depends.begin(); iter != param.depends.end(); ++iter) {
563 const QString& sDepend = *iter;
564 pDepends[iDepend].key = (char *) sDepend.latin1();
565 pDepends[iDepend].value = (char *) m_params[sDepend.upper()].value.latin1();
566 ++iDepend;
567 }
568 // Null terminated.
569 pDepends[iDepend].key = NULL;
570 pDepends[iDepend].value = NULL;
571
572 // FIXME: Some parameter dependencies (e.g.ALSA CARD)
573 // are blocking for no reason, causing potential timeout-crashes.
574 // hopefully this gets mitigated if this dependency hell is only
575 // carried out for scratch devices...
576
577 // Retrieve some modern parameters...
578 lscp_param_info_t *pParamInfo = NULL;
579 switch (m_deviceType) {
580 case qsamplerDevice::Audio:
581 if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),
582 m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)
583 appendMessagesClient("lscp_get_audio_driver_param_info");
584 break;
585 case qsamplerDevice::Midi:
586 if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),
587 m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)
588 appendMessagesClient("lscp_get_midi_driver_param_info");
589 break;
590 case qsamplerDevice::None:
591 break;
592 }
593 if (pParamInfo) {
594 if (param.value != QString::null)
595 param = qsamplerDeviceParam(pParamInfo, param.value);
596 else
597 param = qsamplerDeviceParam(pParamInfo, NULL);
598 iRefresh++;
599 }
600
601 // Free used parameter array.
602 delete pDepends;
603
604 // Return whether the parameters has been changed...
605 return iRefresh;
606 }
607
608
609 // Redirected messages output methods.
610 void qsamplerDevice::appendMessages( const QString& s ) const
611 {
612 MainForm *pMainForm = MainForm::getInstance();
613 if (pMainForm)
614 pMainForm->appendMessages(deviceName() + ' ' + s);
615 }
616
617 void qsamplerDevice::appendMessagesColor( const QString& s,
618 const QString& c ) const
619 {
620 MainForm *pMainForm = MainForm::getInstance();
621 if (pMainForm)
622 pMainForm->appendMessagesColor(deviceName() + ' ' + s, c);
623 }
624
625 void qsamplerDevice::appendMessagesText( const QString& s ) const
626 {
627 MainForm *pMainForm = MainForm::getInstance();
628 if (pMainForm)
629 pMainForm->appendMessagesText(deviceName() + ' ' + s);
630 }
631
632 void qsamplerDevice::appendMessagesError( const QString& s ) const
633 {
634 MainForm *pMainForm = MainForm::getInstance();
635 if (pMainForm)
636 pMainForm->appendMessagesError(deviceName() + "\n\n" + s);
637 }
638
639 void qsamplerDevice::appendMessagesClient( const QString& s ) const
640 {
641 MainForm *pMainForm = MainForm::getInstance();
642 if (pMainForm)
643 pMainForm->appendMessagesClient(deviceName() + ' ' + s);
644 }
645
646
647 // Device ids enumerator.
648 int *qsamplerDevice::getDevices ( lscp_client_t *pClient,
649 qsamplerDeviceType deviceType )
650 {
651 int *piDeviceIDs = NULL;
652 switch (deviceType) {
653 case qsamplerDevice::Audio:
654 piDeviceIDs = ::lscp_list_audio_devices(pClient);
655 break;
656 case qsamplerDevice::Midi:
657 piDeviceIDs = ::lscp_list_midi_devices(pClient);
658 break;
659 case qsamplerDevice::None:
660 break;
661 }
662 return piDeviceIDs;
663 }
664
665
666 // Driver names enumerator.
667 QStringList qsamplerDevice::getDrivers ( lscp_client_t *pClient,
668 qsamplerDeviceType deviceType )
669 {
670 QStringList drivers;
671
672 const char **ppszDrivers = NULL;
673 switch (deviceType) {
674 case qsamplerDevice::Audio:
675 ppszDrivers = ::lscp_list_available_audio_drivers(pClient);
676 break;
677 case qsamplerDevice::Midi:
678 ppszDrivers = ::lscp_list_available_midi_drivers(pClient);
679 break;
680 case qsamplerDevice::None:
681 break;
682 }
683
684 for (int iDriver = 0; ppszDrivers && ppszDrivers[iDriver]; iDriver++)
685 drivers.append(ppszDrivers[iDriver]);
686
687 return drivers;
688 }
689
690
691 //-------------------------------------------------------------------------
692 // qsamplerDevicePort - MIDI/Audio Device port/channel structure.
693 //
694
695 // Constructor.
696 qsamplerDevicePort::qsamplerDevicePort ( qsamplerDevice& device,
697 int iPortID ) : m_device(device)
698 {
699 setDevicePort(iPortID);
700 }
701
702 // Default destructor.
703 qsamplerDevicePort::~qsamplerDevicePort (void)
704 {
705 }
706
707
708 // Initializer.
709 void qsamplerDevicePort::setDevicePort ( int iPortID )
710 {
711 MainForm *pMainForm = MainForm::getInstance();
712 if (pMainForm == NULL)
713 return;
714 if (pMainForm->client() == NULL)
715 return;
716
717 // Device port id should be always set.
718 m_iPortID = iPortID;
719
720 // Reset port parameters anyway.
721 m_params.clear();
722
723 // Retrieve device port/channel info, if any.
724 lscp_device_port_info_t *pPortInfo = NULL;
725 switch (m_device.deviceType()) {
726 case qsamplerDevice::Audio:
727 if ((pPortInfo = ::lscp_get_audio_channel_info(pMainForm->client(),
728 m_device.deviceID(), m_iPortID)) == NULL)
729 m_device.appendMessagesClient("lscp_get_audio_channel_info");
730 break;
731 case qsamplerDevice::Midi:
732 if ((pPortInfo = ::lscp_get_midi_port_info(pMainForm->client(),
733 m_device.deviceID(), m_iPortID)) == NULL)
734 m_device.appendMessagesClient("lscp_get_midi_port_info");
735 break;
736 case qsamplerDevice::None:
737 break;
738 }
739
740 // If we're bogus, bail out...
741 if (pPortInfo == NULL) {
742 m_sPortName = QString::null;
743 return;
744 }
745
746 // Set device port/channel properties...
747 m_sPortName = pPortInfo->name;
748
749 // Grab device port/channel parameters...
750 m_params.clear();
751 for (int i = 0; pPortInfo->params && pPortInfo->params[i].key; i++) {
752 const QString sParam = pPortInfo->params[i].key;
753 lscp_param_info_t *pParamInfo = NULL;
754 switch (m_device.deviceType()) {
755 case qsamplerDevice::Audio:
756 if ((pParamInfo = ::lscp_get_audio_channel_param_info(
757 pMainForm->client(), m_device.deviceID(),
758 m_iPortID, sParam.latin1())) == NULL)
759 m_device.appendMessagesClient("lscp_get_audio_channel_param_info");
760 break;
761 case qsamplerDevice::Midi:
762 if ((pParamInfo = ::lscp_get_midi_port_param_info(
763 pMainForm->client(), m_device.deviceID(),
764 m_iPortID, sParam.latin1())) == NULL)
765 m_device.appendMessagesClient("lscp_get_midi_port_param_info");
766 break;
767 case qsamplerDevice::None:
768 break;
769 }
770 if (pParamInfo) {
771 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
772 pPortInfo->params[i].value);
773 }
774 }
775 }
776
777
778 // Device port/channel property accessors.
779 int qsamplerDevicePort::portID (void) const
780 {
781 return m_iPortID;
782 }
783
784 const QString& qsamplerDevicePort::portName (void) const
785 {
786 return m_sPortName;
787 }
788
789 // Device port/channel parameter accessor.
790 const qsamplerDeviceParamMap& qsamplerDevicePort::params (void) const
791 {
792 return m_params;
793 }
794
795
796 // Set the proper device port/channel parameter value.
797 bool qsamplerDevicePort::setParam ( const QString& sParam,
798 const QString& sValue )
799 {
800 MainForm *pMainForm = MainForm::getInstance();
801 if (pMainForm == NULL)
802 return false;
803 if (pMainForm->client() == NULL)
804 return false;
805
806 // Set proper port/channel parameter.
807 m_params[sParam.upper()].value = sValue;
808
809 // If the device already exists, things get immediate...
810 int iRefresh = 0;
811 if (m_device.deviceID() >= 0 && m_iPortID >= 0) {
812 // Prepare parameter struct.
813 lscp_param_t param;
814 param.key = (char *) sParam.latin1();
815 param.value = (char *) sValue.latin1();
816 // Now it depends on the device type...
817 lscp_status_t ret = LSCP_FAILED;
818 switch (m_device.deviceType()) {
819 case qsamplerDevice::Audio:
820 if ((ret = ::lscp_set_audio_channel_param(pMainForm->client(),
821 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
822 m_device.appendMessagesClient("lscp_set_audio_channel_param");
823 break;
824 case qsamplerDevice::Midi:
825 if ((ret = ::lscp_set_midi_port_param(pMainForm->client(),
826 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
827 m_device.appendMessagesClient("lscp_set_midi_port_param");
828 break;
829 case qsamplerDevice::None:
830 break;
831 }
832 // Show result.
833 if (ret == LSCP_OK) {
834 m_device.appendMessages(m_sPortName
835 + ' ' + QString("%1: %2.").arg(sParam).arg(sValue));
836 iRefresh++;
837 } else {
838 m_device.appendMessagesError(
839 QObject::tr("Could not set %1 parameter value.\n\n"
840 "Sorry.").arg(m_sPortName));
841 }
842 }
843
844 // Return whether we're need a view refresh.
845 return (iRefresh > 0);
846 }
847
848
849 //-------------------------------------------------------------------------
850 // qsamplerDeviceItem - QTreeWidget device item.
851 //
852
853 // Constructors.
854 qsamplerDeviceItem::qsamplerDeviceItem ( QTreeWidget* pTreeWidget,
855 qsamplerDevice::qsamplerDeviceType deviceType )
856 : QTreeWidgetItem(pTreeWidget, QSAMPLER_DEVICE_ITEM),
857 m_device(deviceType)
858 {
859 switch(m_device.deviceType()) {
860 case qsamplerDevice::Audio:
861 setIcon(0, QPixmap(":/icons/audio1.png"));
862 setText(0, QObject::tr("Audio Devices"));
863 break;
864 case qsamplerDevice::Midi:
865 setIcon(0, QPixmap(":/icons/midi1.png"));
866 setText(0, QObject::tr("MIDI Devices"));
867 break;
868 case qsamplerDevice::None:
869 break;
870 }
871 }
872
873 qsamplerDeviceItem::qsamplerDeviceItem ( QTreeWidgetItem* pItem,
874 qsamplerDevice::qsamplerDeviceType deviceType,
875 int iDeviceID )
876 : QTreeWidgetItem(pItem, QSAMPLER_DEVICE_ITEM),
877 m_device(deviceType, iDeviceID)
878 {
879 switch(m_device.deviceType()) {
880 case qsamplerDevice::Audio:
881 setIcon(0, QPixmap(":/icons/audio2.png"));
882 break;
883 case qsamplerDevice::Midi:
884 setIcon(0, QPixmap(":/icons/midi2.png"));
885 break;
886 case qsamplerDevice::None:
887 break;
888 }
889
890 setText(0, m_device.deviceName());
891 }
892
893 // Default destructor.
894 qsamplerDeviceItem::~qsamplerDeviceItem ()
895 {
896 }
897
898 // Instance accessors.
899 qsamplerDevice& qsamplerDeviceItem::device ()
900 {
901 return m_device;
902 }
903
904
905 //-------------------------------------------------------------------------
906 // AbstractDeviceParamModel - data model base class for device parameters
907 //
908
909 AbstractDeviceParamModel::AbstractDeviceParamModel(QObject* parent) : QAbstractTableModel(parent), bEditable(false) {
910 params = NULL;
911 }
912
913 int AbstractDeviceParamModel::rowCount(const QModelIndex& /*parent*/) const {
914 //std::cout << "model size=" << params.size() << "\n" << std::flush;
915 return (params) ? params->size() : 0;
916 }
917
918 int AbstractDeviceParamModel::columnCount(const QModelIndex& /*parent*/) const {
919 return 3;
920 }
921
922 Qt::ItemFlags AbstractDeviceParamModel::flags(const QModelIndex& /*index*/) const {
923 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
924 }
925
926 QVariant AbstractDeviceParamModel::data(const QModelIndex &index, int role) const {
927 if (!index.isValid()) {
928 //std::cout << "inavlid device model index\n" << std::flush;
929 return QVariant();
930 }
931 if (role != Qt::DisplayRole) {
932 //std::cout << "inavlid display role\n" << std::flush;
933 return QVariant();
934 }
935
936 DeviceParameterRow item;
937 item.name = params->keys()[index.row()];
938 item.param = (*params)[item.name];
939
940 //std::cout << "item["<<index.row()<<"]=[" << item.name.toLatin1().data() << "]\n" << std::flush;
941
942 return QVariant::fromValue(item);
943 }
944
945 QVariant AbstractDeviceParamModel::headerData(int section, Qt::Orientation orientation, int role) const {
946 if (role != Qt::DisplayRole) return QVariant();
947
948 if (orientation == Qt::Horizontal) {
949 switch (section) {
950 case 0: return tr("Parameter");
951 case 1: return tr("Value");
952 case 2: return tr("Description");
953 default: return QVariant();
954 }
955 }
956
957 return QVariant();
958 }
959
960 void AbstractDeviceParamModel::refresh(const qsamplerDeviceParamMap* params, bool bEditable) {
961 this->params = params;
962 this->bEditable = bEditable;
963 // inform the outer world (QTableView) that our data changed
964 QAbstractTableModel::reset();
965 }
966
967 void AbstractDeviceParamModel::clear() {
968 params = NULL;
969 // inform the outer world (QTableView) that our data changed
970 QAbstractTableModel::reset();
971 }
972
973
974 //-------------------------------------------------------------------------
975 // DeviceParamModel - data model for device parameters (used for QTableView)
976 //
977
978 DeviceParamModel::DeviceParamModel(QObject* parent) : AbstractDeviceParamModel(parent) {
979 device = NULL;
980 }
981
982 bool DeviceParamModel::setData(const QModelIndex& index, const QVariant& value, int /*role*/) {
983 if (!index.isValid()) {
984 return false;
985 }
986 QString key = params->keys()[index.row()];
987 //params[key].value = value.toString();
988 device->setParam(key, value.toString());
989 emit dataChanged(index, index);
990 return true;
991 }
992
993 void DeviceParamModel::refresh(qsamplerDevice* pDevice, bool bEditable) {
994 device = pDevice;
995 AbstractDeviceParamModel::refresh(&pDevice->params(), bEditable);
996 }
997
998 void DeviceParamModel::clear() {
999 AbstractDeviceParamModel::clear();
1000 device = NULL;
1001 }
1002
1003
1004 //-------------------------------------------------------------------------
1005 // PortParamModel - data model for port parameters (used for QTableView)
1006 //
1007
1008 PortParamModel::PortParamModel(QObject* parent) : AbstractDeviceParamModel(parent) {
1009 port = NULL;
1010 }
1011
1012 bool PortParamModel::setData(const QModelIndex& index, const QVariant& value, int /*role*/) {
1013 if (!index.isValid()) {
1014 return false;
1015 }
1016 QString key = params->keys()[index.row()];
1017 //params[key].value = value.toString();
1018 port->setParam(key, value.toString());
1019 emit dataChanged(index, index);
1020 return true;
1021 }
1022
1023 void PortParamModel::refresh(qsamplerDevicePort* pPort, bool bEditable) {
1024 port = pPort;
1025 AbstractDeviceParamModel::refresh(&pPort->params(), bEditable);
1026 }
1027
1028 void PortParamModel::clear() {
1029 AbstractDeviceParamModel::clear();
1030 port = NULL;
1031 }
1032
1033
1034 //-------------------------------------------------------------------------
1035 // DeviceParamDelegate - table cell renderer for device/port parameters
1036 //
1037
1038 DeviceParamDelegate::DeviceParamDelegate(QObject *parent) : QItemDelegate(parent) {
1039 }
1040
1041 QWidget* DeviceParamDelegate::createEditor(QWidget *parent,
1042 const QStyleOptionViewItem &/* option */,
1043 const QModelIndex& index) const
1044 {
1045 if (!index.isValid()) {
1046 return NULL;
1047 }
1048
1049 DeviceParameterRow r = index.model()->data(index, Qt::DisplayRole).value<DeviceParameterRow>();
1050
1051 const bool bEnabled = (/*index.model()->bEditable ||*/ !r.param.fix);
1052
1053 switch (index.column()) {
1054 case 0:
1055 return new QLabel(r.name, parent);
1056 case 1: {
1057 if (r.param.type == LSCP_TYPE_BOOL) {
1058 QCheckBox* pCheckBox = new QCheckBox(parent);
1059 pCheckBox->setChecked(r.param.value.lower() == "true");
1060 pCheckBox->setEnabled(bEnabled);
1061 return pCheckBox;
1062 } else if (r.param.possibilities.count() > 0) {
1063 QStringList opts = r.param.possibilities;
1064 if (r.param.multiplicity)
1065 opts.prepend(tr("(none)"));
1066 QComboBox* pComboBox = new QComboBox(parent);
1067 pComboBox->addItems(opts);
1068 if (r.param.value.isEmpty())
1069 pComboBox->setCurrentIndex(0);
1070 else
1071 pComboBox->setCurrentIndex(pComboBox->findText(r.param.value));
1072 pComboBox->setEnabled(bEnabled);
1073 return pComboBox;
1074 } else if (r.param.type == LSCP_TYPE_INT
1075 && !r.param.range_min.isEmpty()
1076 && !r.param.range_max.isEmpty()) {
1077 QSpinBox* pSpinBox = new QSpinBox(parent);
1078 pSpinBox->setValue(r.param.value.toInt());
1079 pSpinBox->setMinimum(r.param.range_min.toInt());
1080 pSpinBox->setMaximum(r.param.range_max.toInt());
1081 pSpinBox->setEnabled(bEnabled);
1082 return pSpinBox;
1083 } else {
1084 QLineEdit* pLineEdit = new QLineEdit(r.param.value, parent);
1085 pLineEdit->setEnabled(bEnabled);
1086 return pLineEdit;
1087 }
1088 }
1089 case 2:
1090 return new QLabel(r.param.description, parent);
1091 default:
1092 return NULL;
1093 }
1094 }
1095
1096 void DeviceParamDelegate::setEditorData(QWidget* /*editor*/, const QModelIndex& /*index*/) const {
1097 // unused, since we set the editor data already in createEditor()
1098 }
1099
1100 void DeviceParamDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
1101 if (index.column() == 1) {
1102 DeviceParameterRow r = index.model()->data(index, Qt::DisplayRole).value<DeviceParameterRow>();
1103 if (r.param.type == LSCP_TYPE_BOOL) {
1104 QCheckBox* pCheckBox = static_cast<QCheckBox*>(editor);
1105 model->setData(index, QVariant(pCheckBox->checkState() == Qt::Checked));
1106 } else if (r.param.possibilities.count() > 0) {
1107 QComboBox* pComboBox = static_cast<QComboBox*>(editor);
1108 model->setData(index, pComboBox->currentText());
1109 } else if (r.param.type == LSCP_TYPE_INT) {
1110 QSpinBox* pSpinBox = static_cast<QSpinBox*>(editor);
1111 model->setData(index, pSpinBox->value());
1112 } else {
1113 QLineEdit* pLineEdit = static_cast<QLineEdit*>(editor);
1114 model->setData(index, pLineEdit->text());
1115 }
1116 }
1117 }
1118
1119 void DeviceParamDelegate::updateEditorGeometry(QWidget* editor,
1120 const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
1121 {
1122 if (editor) editor->setGeometry(option.rect);
1123 }
1124
1125 // end of qsamplerDevice.cpp

  ViewVC Help
Powered by ViewVC