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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 492 - (show annotations) (download)
Sat Apr 2 12:23:18 2005 UTC (14 years, 9 months ago) by capela
File size: 28968 byte(s)
* Option "(none)" was added to device port/channel
  parameter settings which have multiplicity set on.

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

  ViewVC Help
Powered by ViewVC