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

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

  ViewVC Help
Powered by ViewVC