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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 463 - (show annotations) (download)
Tue Mar 15 15:32:29 2005 UTC (19 years, 1 month ago) by capela
File size: 18592 byte(s)
* Device port/channel configuration is now complete (EXPERIMENTAL).

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->multiplicity;
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 ( lscp_client_t *pClient,
108 qsamplerDeviceType deviceType, int iDeviceID )
109 {
110 m_ports.setAutoDelete(true);
111
112 setDevice(pClient, deviceType, iDeviceID);
113 }
114
115 // Default destructor.
116 qsamplerDevice::~qsamplerDevice (void)
117 {
118 }
119
120
121 // Initializer.
122 void qsamplerDevice::setDevice ( lscp_client_t *pClient,
123 qsamplerDeviceType deviceType, int iDeviceID )
124 {
125 // Device id and type should be always set.
126 m_iDeviceID = iDeviceID;
127 m_deviceType = deviceType;
128
129 // Reset device parameters and ports anyway.
130 m_params.clear();
131 m_ports.clear();
132
133 // Retrieve device info, if any.
134 lscp_device_info_t *pDeviceInfo = NULL;
135 switch (deviceType) {
136 case qsamplerDevice::Audio:
137 m_sDeviceType = QObject::tr("Audio");
138 pDeviceInfo = ::lscp_get_audio_device_info(pClient, iDeviceID);
139 break;
140 case qsamplerDevice::Midi:
141 m_sDeviceType = QObject::tr("MIDI");
142 pDeviceInfo = ::lscp_get_midi_device_info(pClient, iDeviceID);
143 break;
144 case qsamplerDevice::None:
145 m_sDeviceType = QString::null;
146 break;
147 }
148
149 // If we're bogus, bail out...
150 if (pDeviceInfo == NULL) {
151 m_sDriverName = QString::null;
152 m_sDeviceName = QObject::tr("New %1 device").arg(m_sDeviceType);
153 return;
154 }
155
156 // Other device properties...
157 m_sDriverName = pDeviceInfo->driver;
158 m_sDeviceName = m_sDriverName + ' '
159 + QObject::tr("Device %1").arg(m_iDeviceID);
160
161 // Grab device parameters...
162 for (int i = 0; pDeviceInfo->params && pDeviceInfo->params[i].key; i++) {
163 const QString sParam = pDeviceInfo->params[i].key;
164 lscp_param_info_t *pParamInfo = NULL;
165 switch (deviceType) {
166 case qsamplerDevice::Audio:
167 pParamInfo = ::lscp_get_audio_driver_param_info(pClient,
168 m_sDriverName.latin1(), sParam.latin1(), NULL);
169 break;
170 case qsamplerDevice::Midi:
171 pParamInfo = ::lscp_get_midi_driver_param_info(pClient,
172 m_sDriverName.latin1(), sParam.latin1(), NULL);
173 break;
174 case qsamplerDevice::None:
175 break;
176 }
177 if (pParamInfo) {
178 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
179 pDeviceInfo->params[i].value);
180 }
181 }
182
183 // Grab port/channel list...
184 refresh(pClient);
185 }
186
187
188 // Driver name initializer/settler.
189 void qsamplerDevice::setDriver ( lscp_client_t *pClient,
190 const QString& sDriverName )
191 {
192 // Valid only for scratch devices.
193 if (m_sDriverName == sDriverName)
194 return;
195
196 // Reset device parameters and ports anyway.
197 m_params.clear();
198 m_ports.clear();
199
200 // Retrieve driver info, if any.
201 lscp_driver_info_t *pDriverInfo = NULL;
202 switch (m_deviceType) {
203 case qsamplerDevice::Audio:
204 pDriverInfo = ::lscp_get_audio_driver_info(pClient,
205 sDriverName.latin1());
206 break;
207 case qsamplerDevice::Midi:
208 pDriverInfo = ::lscp_get_midi_driver_info(pClient,
209 sDriverName.latin1());
210 break;
211 case qsamplerDevice::None:
212 break;
213 }
214
215 // If we're bogus, bail out...
216 if (pDriverInfo == NULL)
217 return;
218
219 // Remember device parameters...
220 m_sDriverName = sDriverName;
221
222 // Grab driver parameters...
223 for (int i = 0; pDriverInfo->parameters && pDriverInfo->parameters[i]; i++) {
224 const QString sParam = pDriverInfo->parameters[i];
225 lscp_param_info_t *pParamInfo = NULL;
226 switch (m_deviceType) {
227 case qsamplerDevice::Audio:
228 pParamInfo = ::lscp_get_audio_driver_param_info(pClient,
229 sDriverName.latin1(), sParam.latin1(), NULL);
230 break;
231 case qsamplerDevice::Midi:
232 pParamInfo = ::lscp_get_midi_driver_param_info(pClient,
233 sDriverName.latin1(), sParam.latin1(), NULL);
234 break;
235 case qsamplerDevice::None:
236 break;
237 }
238 if (pParamInfo) {
239 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
240 pParamInfo->defaultv);
241 }
242 }
243 }
244
245
246 // Device property accessors.
247 int qsamplerDevice::deviceID (void) const
248 {
249 return m_iDeviceID;
250 }
251
252 qsamplerDevice::qsamplerDeviceType qsamplerDevice::deviceType (void) const
253 {
254 return m_deviceType;
255 }
256
257 const QString& qsamplerDevice::deviceTypeName (void) const
258 {
259 return m_sDeviceType;
260 }
261
262 const QString& qsamplerDevice::driverName (void) const
263 {
264 return m_sDriverName;
265 }
266
267 const QString& qsamplerDevice::deviceName (void) const
268 {
269 return m_sDeviceName;
270 }
271
272
273 // Set the proper device parameter value.
274 void qsamplerDevice::setParam ( const QString& sParam,
275 const QString& sValue )
276 {
277 m_params[sParam.upper()].value = sValue;
278 }
279
280
281 // Device parameter accessor.
282 const qsamplerDeviceParamMap& qsamplerDevice::params (void) const
283 {
284 return m_params;
285 }
286
287
288 // Device port/channel list accessor.
289 qsamplerDevicePortList& qsamplerDevice::ports (void)
290 {
291 return m_ports;
292 }
293
294
295 // Device port/channel list refreshner.
296 void qsamplerDevice::refresh ( lscp_client_t *pClient )
297 {
298 // Port/channel count determination...
299 int iPorts = 0;
300 switch (m_deviceType) {
301 case qsamplerDevice::Audio:
302 iPorts = m_params["CHANNELS"].value.toInt();
303 break;
304 case qsamplerDevice::Midi:
305 iPorts = m_params["PORTS"].value.toInt();
306 break;
307 case qsamplerDevice::None:
308 break;
309 }
310
311 // Retrieve port/channel information...
312 m_ports.clear();
313 for (int iPort = 0; iPort < iPorts; iPort++)
314 m_ports.append(new qsamplerDevicePort(pClient, *this, iPort));
315 }
316
317
318 // Device ids enumerator.
319 int *qsamplerDevice::getDevices ( lscp_client_t *pClient,
320 qsamplerDeviceType deviceType )
321 {
322 int *piDeviceIDs = NULL;
323 switch (deviceType) {
324 case qsamplerDevice::Audio:
325 piDeviceIDs = ::lscp_list_audio_devices(pClient);
326 break;
327 case qsamplerDevice::Midi:
328 piDeviceIDs = ::lscp_list_midi_devices(pClient);
329 break;
330 case qsamplerDevice::None:
331 break;
332 }
333 return piDeviceIDs;
334 }
335
336
337 // Driver names enumerator.
338 QStringList qsamplerDevice::getDrivers ( lscp_client_t *pClient,
339 qsamplerDeviceType deviceType )
340 {
341 QStringList drivers;
342
343 const char **ppszDrivers = NULL;
344 switch (deviceType) {
345 case qsamplerDevice::Audio:
346 ppszDrivers = ::lscp_get_available_audio_drivers(pClient);
347 break;
348 case qsamplerDevice::Midi:
349 ppszDrivers = ::lscp_get_available_midi_drivers(pClient);
350 break;
351 case qsamplerDevice::None:
352 break;
353 }
354
355 for (int iDriver = 0; ppszDrivers[iDriver]; iDriver++)
356 drivers.append(ppszDrivers[iDriver]);
357
358 return drivers;
359 }
360
361
362 //-------------------------------------------------------------------------
363 // qsamplerDevicePort - MIDI/Audio Device port/channel structure.
364 //
365
366 // Constructor.
367 qsamplerDevicePort::qsamplerDevicePort ( lscp_client_t *pClient,
368 const qsamplerDevice& device, int iPortID )
369 {
370 setDevicePort(pClient, device, iPortID);
371 }
372
373 // Default destructor.
374 qsamplerDevicePort::~qsamplerDevicePort (void)
375 {
376 }
377
378
379 // Initializer.
380 void qsamplerDevicePort::setDevicePort ( lscp_client_t *pClient,
381 const qsamplerDevice& device, int iPortID )
382 {
383 // Device port id should be always set.
384 m_iPortID = iPortID;
385
386 // Reset port parameters anyway.
387 m_params.clear();
388
389 // Retrieve device port/channel info, if any.
390 QString sPrefix = device.driverName() + ' ';
391 lscp_device_port_info_t *pPortInfo = NULL;
392 switch (device.deviceType()) {
393 case qsamplerDevice::Audio:
394 sPrefix += QObject::tr("Channel");
395 pPortInfo = ::lscp_get_audio_channel_info(pClient, device.deviceID(), iPortID);
396 break;
397 case qsamplerDevice::Midi:
398 sPrefix += QObject::tr("Port");
399 pPortInfo = ::lscp_get_midi_port_info(pClient, device.deviceID(), iPortID);
400 break;
401 case qsamplerDevice::None:
402 break;
403 }
404
405 // If we're bogus, bail out...
406 if (pPortInfo == NULL) {
407 m_sPortName = QString::null;
408 return;
409 }
410
411 // Set device port/channel properties...
412 sPrefix += " %1:";
413 m_sPortName = sPrefix.arg(m_iPortID) + ' ' + pPortInfo->name;
414
415 // Grab device port/channel parameters...
416 m_params.clear();
417 for (int i = 0; pPortInfo->params && pPortInfo->params[i].key; i++) {
418 const QString sParam = pPortInfo->params[i].key;
419 lscp_param_info_t *pParamInfo = NULL;
420 switch (device.deviceType()) {
421 case qsamplerDevice::Audio:
422 pParamInfo = ::lscp_get_audio_channel_param_info(pClient,
423 device.deviceID(), iPortID, sParam.latin1());
424 break;
425 case qsamplerDevice::Midi:
426 pParamInfo = ::lscp_get_midi_port_param_info(pClient,
427 device.deviceID(), iPortID, sParam.latin1());
428 break;
429 case qsamplerDevice::None:
430 break;
431 }
432 if (pParamInfo) {
433 m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,
434 pPortInfo->params[i].value);
435 }
436 }
437 }
438
439
440 // Device port/channel property accessors.
441 int qsamplerDevicePort::portID (void) const
442 {
443 return m_iPortID;
444 }
445
446 const QString& qsamplerDevicePort::portName (void) const
447 {
448 return m_sPortName;
449 }
450
451 // Device port/channel parameter accessor.
452 const qsamplerDeviceParamMap& qsamplerDevicePort::params (void) const
453 {
454 return m_params;
455 }
456
457
458 // Set the proper device port/channel parameter value.
459 void qsamplerDevicePort::setParam ( const QString& sParam,
460 const QString& sValue )
461 {
462 m_params[sParam.upper()].value = sValue;
463 }
464
465
466 //-------------------------------------------------------------------------
467 // qsamplerDeviceItem - QListView device item.
468 //
469
470 // Constructors.
471 qsamplerDeviceItem::qsamplerDeviceItem ( QListView *pListView,
472 lscp_client_t *pClient, qsamplerDevice::qsamplerDeviceType deviceType )
473 : QListViewItem(pListView), m_device(pClient, deviceType)
474 {
475 switch(m_device.deviceType()) {
476 case qsamplerDevice::Audio:
477 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio1.png"));
478 QListViewItem::setText(0, QObject::tr("Audio devices"));
479 break;
480 case qsamplerDevice::Midi:
481 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi1.png"));
482 QListViewItem::setText(0, QObject::tr("MIDI devices"));
483 break;
484 case qsamplerDevice::None:
485 break;
486 }
487 }
488
489 qsamplerDeviceItem::qsamplerDeviceItem ( QListViewItem *pItem,
490 lscp_client_t *pClient, qsamplerDevice::qsamplerDeviceType deviceType,
491 int iDeviceID )
492 : QListViewItem(pItem), m_device(pClient, deviceType, iDeviceID)
493 {
494 switch(m_device.deviceType()) {
495 case qsamplerDevice::Audio:
496 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio2.png"));
497 break;
498 case qsamplerDevice::Midi:
499 QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi2.png"));
500 break;
501 case qsamplerDevice::None:
502 break;
503 }
504
505 QListViewItem::setText(0, m_device.deviceName());
506 }
507
508 // Default destructor.
509 qsamplerDeviceItem::~qsamplerDeviceItem (void)
510 {
511 }
512
513 // Instance accessors.
514 qsamplerDevice& qsamplerDeviceItem::device (void)
515 {
516 return m_device;
517 }
518
519 // To virtually distinguish between list view items.
520 int qsamplerDeviceItem::rtti() const
521 {
522 return QSAMPLER_DEVICE_ITEM;
523 }
524
525
526
527 //-------------------------------------------------------------------------
528 // qsamplerDeviceParamTable - Device parameter view table.
529 //
530
531 // Constructor.
532 qsamplerDeviceParamTable::qsamplerDeviceParamTable ( QWidget *pParent,
533 const char *pszName )
534 : QTable(pParent, pszName)
535 {
536 // Set fixed number of columns.
537 QTable::setNumCols(3);
538 QTable::setShowGrid(false);
539 QTable::setSorting(false);
540 QTable::setFocusStyle(QTable::FollowStyle);
541 QTable::setSelectionMode(QTable::NoSelection);
542 // No vertical header.
543 QTable::verticalHeader()->hide();
544 QTable::setLeftMargin(0);
545 // Initialize the fixed table column headings.
546 QHeader *pHeader = QTable::horizontalHeader();
547 pHeader->setLabel(0, tr("Parameter"));
548 pHeader->setLabel(1, tr("Description"));
549 pHeader->setLabel(2, tr("Value"));
550 // Set read-onlyness of each column
551 QTable::setColumnReadOnly(0, true);
552 QTable::setColumnReadOnly(1, true);
553 // QTable::setColumnReadOnly(2, true); -- of course not.
554 QTable::setColumnStretchable(1, true);
555 }
556
557 // Default destructor.
558 qsamplerDeviceParamTable::~qsamplerDeviceParamTable (void)
559 {
560 }
561
562
563 // Common parameter table renderer.
564 void qsamplerDeviceParamTable::refresh ( const qsamplerDeviceParamMap& params,
565 bool bEditable )
566 {
567 // Always (re)start it empty.
568 QTable::setUpdatesEnabled(false);
569 QTable::setNumRows(0);
570
571 // Fill the parameter table...
572 QTable::insertRows(0, params.count());
573 int iRow = 0;
574 qsamplerDeviceParamMap::ConstIterator iter;
575 for (iter = params.begin(); iter != params.end(); ++iter) {
576 const qsamplerDeviceParam& param = iter.data();
577 bool bEnabled = (bEditable || !param.fix);
578 QTable::setText(iRow, 0, iter.key());
579 QTable::setText(iRow, 1, param.description);
580 if (param.type == LSCP_TYPE_BOOL) {
581 QStringList opts;
582 opts.append(tr("false"));
583 opts.append(tr("true"));
584 QComboTableItem *pComboItem = new QComboTableItem(this, opts);
585 pComboItem->setCurrentItem(param.value.lower() == "true" ? 1 : 0);
586 pComboItem->setEnabled(bEnabled);
587 QTable::setItem(iRow, 2, pComboItem);
588 } else if (param.possibilities.count() > 0 && bEnabled) {
589 QComboTableItem *pComboItem = new QComboTableItem(this,
590 param.possibilities);
591 pComboItem->setCurrentItem(param.value);
592 pComboItem->setEnabled(bEnabled);
593 pComboItem->setEditable(bEnabled && param.multiplicity);
594 QTable::setItem(iRow, 2, pComboItem);
595 } else if (param.type == LSCP_TYPE_INT && bEnabled
596 && !param.range_min.isEmpty()
597 && !param.range_max.isEmpty()) {
598 qsamplerDeviceParamTableSpinBox *pSpinItem =
599 new qsamplerDeviceParamTableSpinBox(this,
600 bEnabled ? QTableItem::OnTyping : QTableItem::Never,
601 param.value);
602 pSpinItem->setMinValue(param.range_min.toInt());
603 pSpinItem->setMaxValue(param.range_max.toInt());
604 QTable::setItem(iRow, 2, pSpinItem);
605 } else {
606 qsamplerDeviceParamTableEditBox *pEditItem =
607 new qsamplerDeviceParamTableEditBox(this,
608 bEnabled ? QTableItem::OnTyping : QTableItem::Never,
609 param.value);
610 QTable::setItem(iRow, 2, pEditItem);
611 }
612 ++iRow;
613 }
614
615 // Adjust optimal column widths.
616 QTable::adjustColumn(0);
617 QTable::adjustColumn(2);
618
619 QTable::setUpdatesEnabled(true);
620 QTable::updateContents();
621 }
622
623
624 //-------------------------------------------------------------------------
625 // qsamplerDeviceParamTableSpinBox - Custom spin box for parameter table.
626 //
627
628 // Constructor.
629 qsamplerDeviceParamTableSpinBox::qsamplerDeviceParamTableSpinBox (
630 QTable *pTable, EditType editType, const QString& sText )
631 : QTableItem(pTable, editType, sText)
632 {
633 m_iValue = sText.toInt();
634 m_iMinValue = m_iMaxValue = 0;
635 }
636
637 // Public accessors.
638 void qsamplerDeviceParamTableSpinBox::setValue ( int iValue )
639 {
640 m_iValue = iValue;
641 QTableItem::setText(QString::number(m_iValue));
642 }
643
644 void qsamplerDeviceParamTableSpinBox::setMinValue ( int iMinValue )
645 {
646 m_iMinValue = iMinValue;
647 }
648
649 void qsamplerDeviceParamTableSpinBox::setMaxValue ( int iMaxValue )
650 {
651 m_iMaxValue = iMaxValue;
652 }
653
654 // Virtual implemetations.
655 QWidget *qsamplerDeviceParamTableSpinBox::createEditor (void) const
656 {
657 QSpinBox *pSpinBox = new QSpinBox(QTableItem::table()->viewport());
658 QObject::connect(pSpinBox, SIGNAL(valueChanged(int)),
659 QTableItem::table(), SLOT(doValueChanged()));
660 if (m_iValue >= m_iMinValue && m_iMaxValue >= m_iValue) {
661 pSpinBox->setMinValue(m_iMinValue);
662 pSpinBox->setMaxValue(m_iMaxValue);
663 }
664 pSpinBox->setValue(m_iValue);
665 return pSpinBox;
666 }
667
668 void qsamplerDeviceParamTableSpinBox::setContentFromEditor ( QWidget *pWidget )
669 {
670 if (pWidget->inherits("QSpinBox"))
671 QTableItem::setText(QString::number(((QSpinBox *) pWidget)->value()));
672 else
673 QTableItem::setContentFromEditor(pWidget);
674 }
675
676
677 //-------------------------------------------------------------------------
678 // qsamplerDeviceParamTableEditBox - Custom edit box for parameter table.
679 //
680
681 // Constructor.
682 qsamplerDeviceParamTableEditBox::qsamplerDeviceParamTableEditBox (
683 QTable *pTable, EditType editType, const QString& sText )
684 : QTableItem(pTable, editType, sText)
685 {
686 }
687
688 // Virtual implemetations.
689 QWidget *qsamplerDeviceParamTableEditBox::createEditor (void) const
690 {
691 QLineEdit *pEditBox = new QLineEdit(QTableItem::table()->viewport());
692 QObject::connect(pEditBox, SIGNAL(returnPressed()),
693 QTableItem::table(), SLOT(doValueChanged()));
694 pEditBox->setText(QTableItem::text());
695 return pEditBox;
696 }
697
698 void qsamplerDeviceParamTableEditBox::setContentFromEditor ( QWidget *pWidget )
699 {
700 if (pWidget->inherits("QLineEdit"))
701 QTableItem::setText(((QLineEdit *) pWidget)->text());
702 else
703 QTableItem::setContentFromEditor(pWidget);
704 }
705
706
707 // end of qsamplerDevice.cpp

  ViewVC Help
Powered by ViewVC