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

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

  ViewVC Help
Powered by ViewVC