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

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

  ViewVC Help
Powered by ViewVC