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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.428  
changed lines
  Added in v.1499

  ViewVC Help
Powered by ViewVC