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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 484 - (show annotations) (download)
Tue Mar 22 12:55:29 2005 UTC (13 years, 8 months ago) by capela
File size: 28823 byte(s)
* Device management classes rearrangement for local messages support.

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 appendMessages(QObject::tr("created."));
421 } else {
422 appendMessagesError(QObject::tr("Could not create device.\n\nSorry."));
423 }
424
425 // Return whether we're a valid device...
426 return (m_iDeviceID >= 0);
427 }
428
429
430 // Destroy existing device.
431 bool qsamplerDevice::deleteDevice (void)
432 {
433 // Now it depends on the device type...
434 lscp_status_t ret = LSCP_FAILED;
435 switch (m_deviceType) {
436 case qsamplerDevice::Audio:
437 if ((ret = ::lscp_destroy_audio_device(client(),
438 m_iDeviceID)) != LSCP_OK)
439 appendMessagesClient("lscp_destroy_audio_device");
440 break;
441 case qsamplerDevice::Midi:
442 if ((ret = ::lscp_destroy_midi_device(client(),
443 m_iDeviceID)) != LSCP_OK)
444 appendMessagesClient("lscp_destroy_midi_device");
445 break;
446 case qsamplerDevice::None:
447 break;
448 }
449
450 // Show result.
451 if (ret == LSCP_OK) {
452 appendMessages(QObject::tr("deleted."));
453 m_iDeviceID = -1;
454 } else {
455 appendMessagesError(QObject::tr("Could not delete device.\n\nSorry."));
456 }
457
458 // Return whether we've done it..
459 return (ret == LSCP_OK);
460 }
461
462
463 // Device parameter dependencies refreshner.
464 int qsamplerDevice::refreshParams (void)
465 {
466 // This should only make sense for scratch devices...
467 if (m_iDeviceID >= 0)
468 return 0;
469 // Refresh all parameters that have dependencies...
470 int iParams = 0;
471 qsamplerDeviceParamMap::ConstIterator iter;
472 for (iter = m_params.begin(); iter != m_params.end(); ++iter)
473 iParams += refreshParam(iter.key());
474 // Return how many parameters have been refreshed...
475 return iParams;
476 }
477
478
479 // Device port/channel list refreshner.
480 int qsamplerDevice::refreshPorts (void)
481 {
482 // This should only make sense for actual devices...
483 if (m_iDeviceID < 0)
484 return 0;
485 // Port/channel count determination...
486 int iPorts = 0;
487 switch (m_deviceType) {
488 case qsamplerDevice::Audio:
489 iPorts = m_params["CHANNELS"].value.toInt();
490 break;
491 case qsamplerDevice::Midi:
492 iPorts = m_params["PORTS"].value.toInt();
493 break;
494 case qsamplerDevice::None:
495 break;
496 }
497 // Retrieve port/channel information...
498 m_ports.clear();
499 for (int iPort = 0; iPort < iPorts; iPort++)
500 m_ports.append(new qsamplerDevicePort(*this, iPort));
501 // Return how many ports have been refreshed...
502 return iPorts;
503 }
504
505
506 // Refresh/set dependencies given that some parameter has changed.
507 int qsamplerDevice::refreshDepends ( const QString& sParam )
508 {
509 // This should only make sense for scratch devices...
510 if (m_iDeviceID >= 0)
511 return 0;
512 // Refresh all parameters that depend on this one...
513 int iDepends = 0;
514 qsamplerDeviceParamMap::ConstIterator iter;
515 for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
516 const QStringList& depends = iter.data().depends;
517 if (depends.find(sParam) != depends.end())
518 iDepends += refreshParam(iter.key());
519 }
520 // Return how many dependencies have been refreshed...
521 return iDepends;
522 }
523
524
525 // Refresh/set given parameter based on driver supplied dependencies.
526 int qsamplerDevice::refreshParam ( const QString& sParam )
527 {
528 // Check if we have dependencies...
529 qsamplerDeviceParam& param = m_params[sParam.upper()];
530 if (param.depends.isEmpty())
531 return 0;
532
533 int iRefresh = 0;
534
535 // Build dependency list...
536 lscp_param_t *pDepends = new lscp_param_t [param.depends.count() + 1];
537 int iDepend = 0;
538 QStringList::ConstIterator iter;
539 for (iter = param.depends.begin(); iter != param.depends.end(); ++iter) {
540 const QString& sDepend = *iter;
541 pDepends[iDepend].key = (char *) sDepend.latin1();
542 pDepends[iDepend].value = (char *) m_params[sDepend.upper()].value.latin1();
543 ++iDepend;
544 }
545 // Null terminated.
546 pDepends[iDepend].key = NULL;
547 pDepends[iDepend].value = NULL;
548
549 // FIXME: Some parameter dependencies (e.g.ALSA CARD)
550 // are blocking for no reason, causing potential timeout-crashes.
551 // hopefully this gets mitigated if this dependency hell is only
552 // carried out for scratch devices...
553
554 // Retrieve some modern parameters...
555 lscp_param_info_t *pParamInfo = NULL;
556 switch (m_deviceType) {
557 case qsamplerDevice::Audio:
558 if ((pParamInfo = ::lscp_get_audio_driver_param_info(client(),
559 m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)
560 appendMessagesClient("lscp_get_audio_driver_param_info");
561 break;
562 case qsamplerDevice::Midi:
563 if ((pParamInfo = ::lscp_get_midi_driver_param_info(client(),
564 m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)
565 appendMessagesClient("lscp_get_midi_driver_param_info");
566 break;
567 case qsamplerDevice::None:
568 break;
569 }
570 if (pParamInfo) {
571 param = qsamplerDeviceParam(pParamInfo, QString(param.value));
572 iRefresh++;
573 }
574
575 // Free used parameter array.
576 delete pDepends;
577
578 // Return whether the parameters has been changed...
579 return iRefresh;
580 }
581
582
583 // Redirected messages output methods.
584 void qsamplerDevice::appendMessages( const QString& s ) const
585 {
586 if (m_pMainForm)
587 m_pMainForm->appendMessages(deviceName() + ' ' + s);
588 }
589
590 void qsamplerDevice::appendMessagesColor( const QString& s,
591 const QString& c ) const
592 {
593 if (m_pMainForm)
594 m_pMainForm->appendMessagesColor(deviceName() + ' ' + s, c);
595 }
596
597 void qsamplerDevice::appendMessagesText( const QString& s ) const
598 {
599 if (m_pMainForm)
600 m_pMainForm->appendMessagesText(deviceName() + ' ' + s);
601 }
602
603 void qsamplerDevice::appendMessagesError( const QString& s ) const
604 {
605 if (m_pMainForm)
606 m_pMainForm->appendMessagesError(deviceName() + "\n\n" + s);
607 }
608
609 void qsamplerDevice::appendMessagesClient( const QString& s ) const
610 {
611 if (m_pMainForm)
612 m_pMainForm->appendMessagesClient(deviceName() + ' ' + s);
613 }
614
615
616 // Device ids enumerator.
617 int *qsamplerDevice::getDevices ( lscp_client_t *pClient,
618 qsamplerDeviceType deviceType )
619 {
620 int *piDeviceIDs = NULL;
621 switch (deviceType) {
622 case qsamplerDevice::Audio:
623 piDeviceIDs = ::lscp_list_audio_devices(pClient);
624 break;
625 case qsamplerDevice::Midi:
626 piDeviceIDs = ::lscp_list_midi_devices(pClient);
627 break;
628 case qsamplerDevice::None:
629 break;
630 }
631 return piDeviceIDs;
632 }
633
634
635 // Driver names enumerator.
636 QStringList qsamplerDevice::getDrivers ( lscp_client_t *pClient,
637 qsamplerDeviceType deviceType )
638 {
639 QStringList drivers;
640
641 const char **ppszDrivers = NULL;
642 switch (deviceType) {
643 case qsamplerDevice::Audio:
644 ppszDrivers = ::lscp_get_available_audio_drivers(pClient);
645 break;
646 case qsamplerDevice::Midi:
647 ppszDrivers = ::lscp_get_available_midi_drivers(pClient);
648 break;
649 case qsamplerDevice::None:
650 break;
651 }
652
653 for (int iDriver = 0; ppszDrivers[iDriver]; iDriver++)
654 drivers.append(ppszDrivers[iDriver]);
655
656 return drivers;
657 }
658
659
660 //-------------------------------------------------------------------------
661 // qsamplerDevicePort - MIDI/Audio Device port/channel structure.
662 //
663
664 // Constructor.
665 qsamplerDevicePort::qsamplerDevicePort ( qsamplerDevice& device,
666 int iPortID ) : m_device(device)
667 {
668 setDevicePort(iPortID);
669 }
670
671 // Default destructor.
672 qsamplerDevicePort::~qsamplerDevicePort (void)
673 {
674 }
675
676
677 // Initializer.
678 void qsamplerDevicePort::setDevicePort ( int iPortID )
679 {
680 // Device port id should be always set.
681 m_iPortID = iPortID;
682
683 // Reset port parameters anyway.
684 m_params.clear();
685
686 // Retrieve device port/channel info, if any.
687 lscp_device_port_info_t *pPortInfo = NULL;
688 switch (m_device.deviceType()) {
689 case qsamplerDevice::Audio:
690 if ((pPortInfo = ::lscp_get_audio_channel_info(m_device.client(),
691 m_device.deviceID(), m_iPortID)) == NULL)
692 m_device.appendMessagesClient("lscp_get_audio_channel_info");
693 break;
694 case qsamplerDevice::Midi:
695 if ((pPortInfo = ::lscp_get_midi_port_info(m_device.client(),
696 m_device.deviceID(), m_iPortID)) == NULL)
697 m_device.appendMessagesClient("lscp_get_midi_port_info");
698 break;
699 case qsamplerDevice::None:
700 break;
701 }
702
703 // If we're bogus, bail out...
704 if (pPortInfo == NULL) {
705 m_sPortName = QString::null;
706 return;
707 }
708
709 // Set device port/channel properties...
710 m_sPortName = pPortInfo->name;
711
712 // Grab device port/channel parameters...
713 m_params.clear();
714 for (int i = 0; pPortInfo->params && pPortInfo->params[i].key; i++) {
715 const QString sParam = pPortInfo->params[i].key;
716 lscp_param_info_t *pParamInfo = NULL;
717 switch (m_device.deviceType()) {
718 case qsamplerDevice::Audio:
719 if ((pParamInfo = ::lscp_get_audio_channel_param_info(
720 m_device.client(), m_device.deviceID(),
721 m_iPortID, sParam.latin1())) == NULL)
722 m_device.appendMessagesClient("lscp_get_audio_channel_param_info");
723 break;
724 case qsamplerDevice::Midi:
725 if ((pParamInfo = ::lscp_get_midi_port_param_info(
726 m_device.client(), m_device.deviceID(),
727 m_iPortID, sParam.latin1())) == NULL)
728 m_device.appendMessagesClient("lscp_get_midi_port_param_info");
729 break;
730 case qsamplerDevice::None:
731 break;
732 }
733 if (pParamInfo) {
734 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
735 pPortInfo->params[i].value);
736 }
737 }
738 }
739
740
741 // Device port/channel property accessors.
742 int qsamplerDevicePort::portID (void) const
743 {
744 return m_iPortID;
745 }
746
747 const QString& qsamplerDevicePort::portName (void) const
748 {
749 return m_sPortName;
750 }
751
752 // Device port/channel parameter accessor.
753 const qsamplerDeviceParamMap& qsamplerDevicePort::params (void) const
754 {
755 return m_params;
756 }
757
758
759 // Set the proper device port/channel parameter value.
760 bool qsamplerDevicePort::setParam ( const QString& sParam,
761 const QString& sValue )
762 {
763 // Set proper port/channel parameter.
764 m_params[sParam.upper()].value = sValue;
765
766 // If the device already exists, things get immediate...
767 int iRefresh = 0;
768 if (m_device.deviceID() >= 0 && m_iPortID >= 0) {
769 // Prepare parameter struct.
770 lscp_param_t param;
771 param.key = (char *) sParam.latin1();
772 param.value = (char *) sValue.latin1();
773 // Now it depends on the device type...
774 lscp_status_t ret = LSCP_FAILED;
775 switch (m_device.deviceType()) {
776 case qsamplerDevice::Audio:
777 if ((ret = ::lscp_set_audio_channel_param(m_device.client(),
778 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
779 m_device.appendMessagesClient("lscp_set_audio_channel_param");
780 break;
781 case qsamplerDevice::Midi:
782 if ((ret = ::lscp_set_midi_port_param(m_device.client(),
783 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
784 m_device.appendMessagesClient("lscp_set_midi_port_param");
785 break;
786 case qsamplerDevice::None:
787 break;
788 }
789 // Show result.
790 if (ret == LSCP_OK) {
791 m_device.appendMessages(m_sPortName
792 + ' ' + QString("%1: %2.").arg(sParam).arg(sValue));
793 iRefresh++;
794 } else {
795 m_device.appendMessagesError(
796 QObject::tr("Could not set %1 parameter value.\n\n"
797 "Sorry.").arg(m_sPortName));
798 }
799 }
800
801 // Return whether we're need a view refresh.
802 return (iRefresh > 0);
803 }
804
805
806 //-------------------------------------------------------------------------
807 // qsamplerDeviceItem - QListView device item.
808 //
809
810 // Constructors.
811 qsamplerDeviceItem::qsamplerDeviceItem ( QListView *pListView,
812 qsamplerMainForm *pMainForm, qsamplerDevice::qsamplerDeviceType deviceType )
813 : QListViewItem(pListView), m_device(pMainForm, deviceType)
814 {
815 switch(m_device.deviceType()) {
816 case qsamplerDevice::Audio:
817 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio1.png"));
818 QListViewItem::setText(0, QObject::tr("Audio Devices"));
819 break;
820 case qsamplerDevice::Midi:
821 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi1.png"));
822 QListViewItem::setText(0, QObject::tr("MIDI Devices"));
823 break;
824 case qsamplerDevice::None:
825 break;
826 }
827 }
828
829 qsamplerDeviceItem::qsamplerDeviceItem ( QListViewItem *pItem,
830 qsamplerMainForm *pMainForm, qsamplerDevice::qsamplerDeviceType deviceType,
831 int iDeviceID )
832 : QListViewItem(pItem), m_device(pMainForm, deviceType, iDeviceID)
833 {
834 switch(m_device.deviceType()) {
835 case qsamplerDevice::Audio:
836 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio2.png"));
837 break;
838 case qsamplerDevice::Midi:
839 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi2.png"));
840 break;
841 case qsamplerDevice::None:
842 break;
843 }
844
845 QListViewItem::setText(0, m_device.deviceName());
846 }
847
848 // Default destructor.
849 qsamplerDeviceItem::~qsamplerDeviceItem (void)
850 {
851 }
852
853 // Instance accessors.
854 qsamplerDevice& qsamplerDeviceItem::device (void)
855 {
856 return m_device;
857 }
858
859 // To virtually distinguish between list view items.
860 int qsamplerDeviceItem::rtti() const
861 {
862 return QSAMPLER_DEVICE_ITEM;
863 }
864
865
866
867 //-------------------------------------------------------------------------
868 // qsamplerDeviceParamTable - Device parameter view table.
869 //
870
871 // Constructor.
872 qsamplerDeviceParamTable::qsamplerDeviceParamTable ( QWidget *pParent,
873 const char *pszName )
874 : QTable(pParent, pszName)
875 {
876 // Set fixed number of columns.
877 QTable::setNumCols(3);
878 QTable::setShowGrid(false);
879 QTable::setSorting(false);
880 QTable::setFocusStyle(QTable::FollowStyle);
881 QTable::setSelectionMode(QTable::NoSelection);
882 // No vertical header.
883 QTable::verticalHeader()->hide();
884 QTable::setLeftMargin(0);
885 // Initialize the fixed table column headings.
886 QHeader *pHeader = QTable::horizontalHeader();
887 pHeader->setLabel(0, tr("Parameter"));
888 pHeader->setLabel(1, tr("Description"));
889 pHeader->setLabel(2, tr("Value"));
890 // Set read-onlyness of each column
891 QTable::setColumnReadOnly(0, true);
892 QTable::setColumnReadOnly(1, true);
893 // QTable::setColumnReadOnly(2, false); -- of course not.
894 QTable::setColumnStretchable(1, true);
895 }
896
897 // Default destructor.
898 qsamplerDeviceParamTable::~qsamplerDeviceParamTable (void)
899 {
900 }
901
902
903 // Common parameter table renderer.
904 void qsamplerDeviceParamTable::refresh ( const qsamplerDeviceParamMap& params,
905 bool bEditable )
906 {
907 // Always (re)start it empty.
908 QTable::setUpdatesEnabled(false);
909 QTable::setNumRows(0);
910
911 // Fill the parameter table...
912 QTable::insertRows(0, params.count());
913 int iRow = 0;
914 qsamplerDeviceParamMap::ConstIterator iter;
915 for (iter = params.begin(); iter != params.end(); ++iter) {
916 const qsamplerDeviceParam& param = iter.data();
917 bool bEnabled = (bEditable || !param.fix);
918 QTable::setText(iRow, 0, iter.key());
919 QTable::setText(iRow, 1, param.description);
920 if (param.type == LSCP_TYPE_BOOL) {
921 QStringList opts;
922 opts.append(tr("false"));
923 opts.append(tr("true"));
924 QComboTableItem *pComboItem = new QComboTableItem(this, opts);
925 pComboItem->setCurrentItem(param.value.lower() == "true" ? 1 : 0);
926 pComboItem->setEnabled(bEnabled);
927 QTable::setItem(iRow, 2, pComboItem);
928 } else if (param.possibilities.count() > 0 && bEnabled) {
929 QComboTableItem *pComboItem = new QComboTableItem(this,
930 param.possibilities);
931 pComboItem->setCurrentItem(param.value);
932 pComboItem->setEnabled(bEnabled);
933 // pComboItem->setEditable(bEnabled && param.multiplicity);
934 QTable::setItem(iRow, 2, pComboItem);
935 } else if (param.type == LSCP_TYPE_INT && bEnabled
936 && !param.range_min.isEmpty()
937 && !param.range_max.isEmpty()) {
938 qsamplerDeviceParamTableSpinBox *pSpinItem =
939 new qsamplerDeviceParamTableSpinBox(this,
940 bEnabled ? QTableItem::OnTyping : QTableItem::Never,
941 param.value);
942 pSpinItem->setMinValue(param.range_min.toInt());
943 pSpinItem->setMaxValue(param.range_max.toInt());
944 QTable::setItem(iRow, 2, pSpinItem);
945 } else {
946 qsamplerDeviceParamTableEditBox *pEditItem =
947 new qsamplerDeviceParamTableEditBox(this,
948 bEnabled ? QTableItem::OnTyping : QTableItem::Never,
949 param.value);
950 QTable::setItem(iRow, 2, pEditItem);
951 }
952 ++iRow;
953 }
954
955 // Adjust optimal column widths.
956 QTable::adjustColumn(0);
957 QTable::adjustColumn(2);
958
959 QTable::setUpdatesEnabled(true);
960 QTable::updateContents();
961 }
962
963
964 //-------------------------------------------------------------------------
965 // qsamplerDeviceParamTableSpinBox - Custom spin box for parameter table.
966 //
967
968 // Constructor.
969 qsamplerDeviceParamTableSpinBox::qsamplerDeviceParamTableSpinBox (
970 QTable *pTable, EditType editType, const QString& sText )
971 : QTableItem(pTable, editType, sText)
972 {
973 m_iValue = sText.toInt();
974 m_iMinValue = m_iMaxValue = 0;
975 }
976
977 // Public accessors.
978 void qsamplerDeviceParamTableSpinBox::setValue ( int iValue )
979 {
980 m_iValue = iValue;
981 QTableItem::setText(QString::number(m_iValue));
982 }
983
984 void qsamplerDeviceParamTableSpinBox::setMinValue ( int iMinValue )
985 {
986 m_iMinValue = iMinValue;
987 }
988
989 void qsamplerDeviceParamTableSpinBox::setMaxValue ( int iMaxValue )
990 {
991 m_iMaxValue = iMaxValue;
992 }
993
994 // Virtual implemetations.
995 QWidget *qsamplerDeviceParamTableSpinBox::createEditor (void) const
996 {
997 QSpinBox *pSpinBox = new QSpinBox(QTableItem::table()->viewport());
998 QObject::connect(pSpinBox, SIGNAL(valueChanged(int)),
999 QTableItem::table(), SLOT(doValueChanged()));
1000 if (m_iValue >= m_iMinValue && m_iMaxValue >= m_iValue) {
1001 pSpinBox->setMinValue(m_iMinValue);
1002 pSpinBox->setMaxValue(m_iMaxValue);
1003 }
1004 pSpinBox->setValue(m_iValue);
1005 return pSpinBox;
1006 }
1007
1008 void qsamplerDeviceParamTableSpinBox::setContentFromEditor ( QWidget *pWidget )
1009 {
1010 if (pWidget->inherits("QSpinBox"))
1011 QTableItem::setText(QString::number(((QSpinBox *) pWidget)->value()));
1012 else
1013 QTableItem::setContentFromEditor(pWidget);
1014 }
1015
1016
1017 //-------------------------------------------------------------------------
1018 // qsamplerDeviceParamTableEditBox - Custom edit box for parameter table.
1019 //
1020
1021 // Constructor.
1022 qsamplerDeviceParamTableEditBox::qsamplerDeviceParamTableEditBox (
1023 QTable *pTable, EditType editType, const QString& sText )
1024 : QTableItem(pTable, editType, sText)
1025 {
1026 }
1027
1028 // Virtual implemetations.
1029 QWidget *qsamplerDeviceParamTableEditBox::createEditor (void) const
1030 {
1031 QLineEdit *pEditBox = new QLineEdit(QTableItem::table()->viewport());
1032 QObject::connect(pEditBox, SIGNAL(returnPressed()),
1033 QTableItem::table(), SLOT(doValueChanged()));
1034 pEditBox->setText(QTableItem::text());
1035 return pEditBox;
1036 }
1037
1038 void qsamplerDeviceParamTableEditBox::setContentFromEditor ( QWidget *pWidget )
1039 {
1040 if (pWidget->inherits("QLineEdit"))
1041 QTableItem::setText(((QLineEdit *) pWidget)->text());
1042 else
1043 QTableItem::setContentFromEditor(pWidget);
1044 }
1045
1046
1047 // end of qsamplerDevice.cpp

  ViewVC Help
Powered by ViewVC