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

Legend:
Removed from v.426  
changed lines
  Added in v.1486

  ViewVC Help
Powered by ViewVC