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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 759 - (show annotations) (download)
Sun Aug 28 11:44:10 2005 UTC (18 years, 7 months ago) by capela
File size: 28976 byte(s)
Usability changes on the new sampler channel audio routing functionality.

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

  ViewVC Help
Powered by ViewVC