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

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

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

revision 344 by capela, Tue Jan 18 13:53:04 2005 UTC revision 3855 by capela, Thu Feb 4 10:09:42 2021 UTC
# Line 1  Line 1 
1  // qsamplerChannel.cpp  // qsamplerChannel.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2003-2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2021, rncbc aka Rui Nuno Capela. All rights reserved.
5       Copyright (C) 2007, 2008 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 13  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
23    #include "qsamplerAbout.h"
24  #include "qsamplerChannel.h"  #include "qsamplerChannel.h"
25    #include "qsamplerUtilities.h"
26    
27  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
28  #include "qsamplerChannelForm.h"  #include "qsamplerChannelForm.h"
29    
30  #include "config.h"  #include <QFileInfo>
31    #include <QComboBox>
 #include <qfileinfo.h>  
32    
33  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
34    #if defined(Q_CC_GNU) || defined(Q_CC_MINGW)
35    #pragma GCC diagnostic push
36    #pragma GCC diagnostic ignored "-Wunused-parameter"
37    #endif
38  #include "gig.h"  #include "gig.h"
39    #ifdef CONFIG_LIBGIG_SF2
40    #pragma GCC diagnostic ignored "-Wunused-variable"
41    #include "SF.h"
42    #endif
43    #if defined(Q_CC_GNU) || defined(Q_CC_MINGW)
44    #pragma GCC diagnostic pop
45    #endif
46  #endif  #endif
47    
48  #define QSAMPLER_INSTRUMENT_MAX 8  namespace QSampler {
49    
50    #define QSAMPLER_INSTRUMENT_MAX 128
51    
52    #define UNICODE_RIGHT_ARROW     QChar(char(0x92), char(0x21))
53    
54    
55  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
56  // qsamplerChannel - Sampler channel structure.  // QSampler::Channel - Sampler channel structure.
57  //  //
58    
59  // Constructor.  // Constructor.
60  qsamplerChannel::qsamplerChannel ( qsamplerMainForm *pMainForm, int iChannelID )  Channel::Channel ( int iChannelID )
61  {  {
62      m_pMainForm  = pMainForm;          m_iChannelID = iChannelID;
     m_iChannelID = iChannelID;  
63    
64  //  m_sEngineName       = QObject::tr("(No engine)");  //  m_sEngineName       = noEngineName();
65  //  m_sInstrumentName   = QObject::tr("(No instrument)");  //  m_sInstrumentName   = noInstrumentName();
66  //  m_sInstrumentFile   = m_sInstrumentName;  //  m_sInstrumentFile   = m_sInstrumentName;
67      m_iInstrumentNr     = -1;          m_iInstrumentNr     = -1;
68      m_iInstrumentStatus = -1;          m_iInstrumentStatus = -1;
69      m_sMidiDriver       = "Alsa";   // DEPRECATED.          m_sMidiDriver       = "ALSA";
70      m_iMidiDevice       = -1;          m_iMidiDevice       = -1;
71      m_iMidiPort         = -1;          m_iMidiPort         = -1;
72      m_iMidiChannel      = -1;          m_iMidiChannel      = -1;
73      m_sAudioDriver      = "Alsa";   // DEPRECATED.          m_iMidiMap          = -1;
74      m_iAudioDevice      = -1;          m_sAudioDriver      = "ALSA";
75      m_fVolume           = 0.0;          m_iAudioDevice      = -1;
76            m_fVolume           = 0.0f;
77            m_bMute             = false;
78            m_bSolo             = false;
79  }  }
80    
81  // Default destructor.  // Default destructor.
82  qsamplerChannel::~qsamplerChannel (void)  Channel::~Channel (void)
83  {  {
84  }  }
85    
86    
 // The global options settings delegated property.  
 qsamplerOptions *qsamplerChannel::options (void)  
 {  
     if (m_pMainForm == NULL)  
         return NULL;  
   
     return m_pMainForm->options();  
 }  
   
   
 // The client descriptor delegated property.  
 lscp_client_t *qsamplerChannel::client (void)  
 {  
     if (m_pMainForm == NULL)  
         return NULL;  
   
     return m_pMainForm->client();  
 }  
   
   
87  // Create a new sampler channel, if not already.  // Create a new sampler channel, if not already.
88  bool qsamplerChannel::addChannel (void)  bool Channel::addChannel (void)
89  {  {
90      if (client() == NULL)          MainForm* pMainForm = MainForm::getInstance();
91          return false;          if (pMainForm == nullptr)
92                    return false;
93      // Are we a new channel?          if (pMainForm->client() == nullptr)
94      if (m_iChannelID < 0) {                  return false;
95          m_iChannelID = ::lscp_add_channel(client());  
96          if (m_iChannelID < 0) {          // Are we a new channel?
97              appendMessagesClient("lscp_add_channel");          if (m_iChannelID < 0) {
98              appendMessagesError(QObject::tr("Could not create the new channel.\n\nSorry."));                  m_iChannelID = ::lscp_add_channel(pMainForm->client());
99          }   // Otherwise it's created...                  if (m_iChannelID < 0) {
100          else appendMessages(QObject::tr("Channel %1 created.").arg(m_iChannelID));                          appendMessagesClient("lscp_add_channel");
101      }                          appendMessagesError(
102                                    QObject::tr("Could not add channel.\n\nSorry."));
103                    }   // Otherwise it's created...
104                    else appendMessages(QObject::tr("added."));
105            }
106    
107      // Return whether we're a valid channel...          // Return whether we're a valid channel...
108      return (m_iChannelID >= 0);          return (m_iChannelID >= 0);
109  }  }
110    
111    
112  // Remove sampler channel.  // Remove sampler channel.
113  bool qsamplerChannel::removeChannel (void)  bool Channel::removeChannel (void)
114  {  {
115      if (client() == NULL)          MainForm *pMainForm = MainForm::getInstance();
116          return false;          if (pMainForm == nullptr)
117                    return false;
118            if (pMainForm->client() == nullptr)
119                    return false;
120    
121            // Are we an existing channel?
122            if (m_iChannelID >= 0) {
123                    if (::lscp_remove_channel(pMainForm->client(), m_iChannelID) != LSCP_OK) {
124                            appendMessagesClient("lscp_remove_channel");
125                            appendMessagesError(QObject::tr("Could not remove channel.\n\nSorry."));
126                    } else {
127                            // Otherwise it's removed.
128                            appendMessages(QObject::tr("removed."));
129                            m_iChannelID = -1;
130                    }
131            }
132    
133      // Are we an existing channel?          // Return whether we've removed the channel...
134      if (m_iChannelID >= 0) {          return (m_iChannelID < 0);
         if (::lscp_remove_channel(client(), m_iChannelID) != LSCP_OK) {  
             appendMessagesClient("lscp_remove_channel");  
             appendMessagesError(QObject::tr("Could not remove channel.\n\nSorry."));  
         } else {  
             // Otherwise it's removed.  
             appendMessages(QObject::tr("Channel %1 removed.").arg(m_iChannelID));  
             m_iChannelID = -1;  
         }  
     }  
       
     // Return whether we've removed the channel...  
     return (m_iChannelID < 0);  
135  }  }
136    
137    
138  // Channel-ID (aka Sammpler-Channel) accessors.  // Channel-ID (aka Sammpler-Channel) accessors.
139  int qsamplerChannel::channelID (void)  int Channel::channelID (void) const
140  {  {
141      return m_iChannelID;          return m_iChannelID;
142  }  }
143    
144  void qsamplerChannel::setChannelID ( int iChannelID )  void Channel::setChannelID ( int iChannelID )
145  {  {
146      m_iChannelID = iChannelID;          m_iChannelID = iChannelID;
147  }  }
148    
149    
150  // Readable channel name.  // Readable channel name.
151  QString qsamplerChannel::channelName (void)  QString Channel::channelName (void) const
152  {  {
153      return (m_iChannelID < 0 ? QObject::tr("New Channel") : QObject::tr("Channel %1").arg(m_iChannelID));          return (m_iChannelID < 0 ? QObject::tr("New Channel") : QObject::tr("Channel %1").arg(m_iChannelID));
154  }  }
155    
156    
157  // Engine name accessors.  // Engine name accessors.
158  QString& qsamplerChannel::engineName (void)  const QString& Channel::engineName (void) const
159  {  {
160      return m_sEngineName;          return m_sEngineName;
161  }  }
162    
163  bool qsamplerChannel::loadEngine ( const QString& sEngineName )  bool Channel::loadEngine ( const QString& sEngineName )
164  {  {
165      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
166          return false;          if (pMainForm == nullptr)
167                    return false;
168            if (pMainForm->client() == nullptr || m_iChannelID < 0)
169                    return false;
170            if (m_iInstrumentStatus == 100 && m_sEngineName == sEngineName)
171                    return true;
172    
173            if (::lscp_load_engine(pMainForm->client(),
174                            sEngineName.toUtf8().constData(), m_iChannelID) != LSCP_OK) {
175                    appendMessagesClient("lscp_load_engine");
176                    return false;
177            }
178    
179      if (::lscp_load_engine(client(), sEngineName.latin1(), m_iChannelID) != LSCP_OK) {          appendMessages(QObject::tr("Engine: %1.").arg(sEngineName));
         appendMessagesClient("lscp_load_engine");  
         return false;  
     }  
180    
181      m_sEngineName = sEngineName;          m_sEngineName = sEngineName;
182      return true;          return true;
183  }  }
184    
185    
186  // Instrument name accessor.  // Instrument filename accessor.
187  QString& qsamplerChannel::instrumentName (void)  const QString& Channel::instrumentFile (void) const
188  {  {
189      return m_sInstrumentName;          return m_sInstrumentFile;
190  }  }
191    
192  // Instrument filename accessor.  // Instrument index accessor.
193  QString& qsamplerChannel::instrumentFile (void)  int Channel::instrumentNr (void) const
194  {  {
195      return m_sInstrumentFile;          return m_iInstrumentNr;
196  }  }
197    
198  // Instrument index accessor.  // Instrument name accessor.
199  int qsamplerChannel::instrumentNr (void)  const QString& Channel::instrumentName (void) const
200  {  {
201      return m_iInstrumentNr;          return m_sInstrumentName;
202  }  }
203    
204  // Instrument status accessor.  // Instrument status accessor.
205  int qsamplerChannel::instrumentStatus (void)  int Channel::instrumentStatus (void) const
206  {  {
207      return m_iInstrumentStatus;          return m_iInstrumentStatus;
208  }  }
209    
210  // Instrument file loader.  // Instrument file loader.
211  bool qsamplerChannel::loadInstrument ( const QString& sInstrumentFile, int iInstrumentNr )  bool Channel::loadInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
212  {  {
213      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
214          return false;          if (pMainForm == nullptr)
215                    return false;
216            if (pMainForm->client() == nullptr || m_iChannelID < 0)
217                    return false;
218            if (!QFileInfo(sInstrumentFile).exists())
219                    return false;
220            if (m_iInstrumentStatus == 100
221                    && m_sInstrumentFile == sInstrumentFile
222                    && m_iInstrumentNr == iInstrumentNr)
223                    return true;
224    
225            if (::lscp_load_instrument_non_modal(
226                            pMainForm->client(),
227                            qsamplerUtilities::lscpEscapePath(
228                                    sInstrumentFile).toUtf8().constData(),
229                            iInstrumentNr, m_iChannelID
230                    ) != LSCP_OK) {
231                    appendMessagesClient("lscp_load_instrument");
232                    return false;
233            }
234    
235            appendMessages(QObject::tr("Instrument: \"%1\" (%2).")
236                    .arg(sInstrumentFile).arg(iInstrumentNr));
237    
238            return setInstrument(sInstrumentFile, iInstrumentNr);
239    }
240    
     if (::lscp_load_instrument_non_modal(client(), sInstrumentFile.latin1(), iInstrumentNr, m_iChannelID) != LSCP_OK) {  
         appendMessagesClient("lscp_load_instrument");  
         return false;  
     }  
   
     m_sInstrumentName = getInstrumentName(sInstrumentFile, iInstrumentNr, true);  
     m_sInstrumentFile = sInstrumentFile;  
     m_iInstrumentNr = iInstrumentNr;  
     m_iInstrumentStatus = 0;  
241    
242      return true;  // Special instrument file/name/number settler.
243    bool Channel::setInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
244    {
245            m_sInstrumentFile = sInstrumentFile;
246            m_iInstrumentNr = iInstrumentNr;
247    #ifdef CONFIG_INSTRUMENT_NAME
248            m_sInstrumentName.clear();  // We'll get it, maybe later, on channel_info...
249    #else
250            m_sInstrumentName = getInstrumentName(sInstrumentFile, iInstrumentNr, true);
251    #endif
252            m_iInstrumentStatus = 0;
253    
254            return true;
255  }  }
256    
257    
258  // MIDI driver type accessors (DEPRECATED).  // MIDI driver type accessors (DEPRECATED).
259  QString& qsamplerChannel::midiDriver (void)  const QString& Channel::midiDriver (void) const
260  {  {
261      return m_sMidiDriver;          return m_sMidiDriver;
262  }  }
263    
264  bool qsamplerChannel::setMidiDriver ( const QString& sMidiDriver )  bool Channel::setMidiDriver ( const QString& sMidiDriver )
265  {  {
266      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
267          return false;          if (pMainForm == nullptr)
268                    return false;
269            if (pMainForm->client() == nullptr || m_iChannelID < 0)
270                    return false;
271            if (m_iInstrumentStatus == 100 && m_sMidiDriver == sMidiDriver)
272                    return true;
273    
274      if (::lscp_set_channel_midi_type(client(), m_iChannelID, sMidiDriver.latin1()) != LSCP_OK) {          if (::lscp_set_channel_midi_type(pMainForm->client(),
275          appendMessagesClient("lscp_set_channel_midi_type");                          m_iChannelID, sMidiDriver.toUtf8().constData()) != LSCP_OK) {
276          return false;                  appendMessagesClient("lscp_set_channel_midi_type");
277      }                  return false;
278            }
279    
280      m_sMidiDriver = sMidiDriver;          appendMessages(QObject::tr("MIDI driver: %1.").arg(sMidiDriver));
281      return true;  
282            m_sMidiDriver = sMidiDriver;
283            return true;
284  }  }
285    
286    
287  // MIDI device accessors.  // MIDI device accessors.
288  int qsamplerChannel::midiDevice (void)  int Channel::midiDevice (void) const
289  {  {
290      return m_iMidiDevice;          return m_iMidiDevice;
291  }  }
292    
293  bool qsamplerChannel::setMidiDevice ( int iMidiDevice )  bool Channel::setMidiDevice ( int iMidiDevice )
294  {  {
295      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
296          return false;          if (pMainForm == nullptr)
297                    return false;
298            if (pMainForm->client() == nullptr || m_iChannelID < 0)
299                    return false;
300            if (m_iInstrumentStatus == 100 && m_iMidiDevice == iMidiDevice)
301                    return true;
302    
303            if (::lscp_set_channel_midi_device(pMainForm->client(), m_iChannelID, iMidiDevice) != LSCP_OK) {
304                    appendMessagesClient("lscp_set_channel_midi_device");
305                    return false;
306            }
307    
308      if (::lscp_set_channel_midi_device(client(), m_iChannelID, iMidiDevice) != LSCP_OK) {          appendMessages(QObject::tr("MIDI device: %1.").arg(iMidiDevice));
         appendMessagesClient("lscp_set_channel_midi_device");  
         return false;  
     }  
309    
310      m_iMidiDevice = iMidiDevice;          m_iMidiDevice = iMidiDevice;
311      return true;          return true;
312  }  }
313    
314    
315  // MIDI port number accessor.  // MIDI port number accessor.
316  int qsamplerChannel::midiPort (void)  int Channel::midiPort (void) const
317  {  {
318      return m_iMidiPort;          return m_iMidiPort;
319  }  }
320    
321  bool qsamplerChannel::setMidiPort ( int iMidiPort )  bool Channel::setMidiPort ( int iMidiPort )
322  {  {
323      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
324          return false;          if (pMainForm == nullptr)
325                    return false;
326            if (pMainForm->client() == nullptr || m_iChannelID < 0)
327                    return false;
328            if (m_iInstrumentStatus == 100 && m_iMidiPort == iMidiPort)
329                    return true;
330    
331      if (::lscp_set_channel_midi_port(client(), m_iChannelID, iMidiPort) != LSCP_OK) {          if (::lscp_set_channel_midi_port(pMainForm->client(), m_iChannelID, iMidiPort) != LSCP_OK) {
332          appendMessagesClient("lscp_set_channel_midi_port");                  appendMessagesClient("lscp_set_channel_midi_port");
333          return false;                  return false;
334      }          }
335    
336      m_iMidiPort = iMidiPort;          appendMessages(QObject::tr("MIDI port: %1.").arg(iMidiPort));
337      return true;  
338            m_iMidiPort = iMidiPort;
339            return true;
340  }  }
341    
342    
343  // MIDI channel accessor.  // MIDI channel accessor.
344  int qsamplerChannel::midiChannel (void)  int Channel::midiChannel (void) const
345  {  {
346      return m_iMidiChannel;          return m_iMidiChannel;
347  }  }
348    
349  bool qsamplerChannel::setMidiChannel ( int iMidiChannel )  bool Channel::setMidiChannel ( int iMidiChannel )
350  {  {
351      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
352          return false;          if (pMainForm == nullptr)
353                    return false;
354            if (pMainForm->client() == nullptr || m_iChannelID < 0)
355                    return false;
356            if (m_iInstrumentStatus == 100 && m_iMidiChannel == iMidiChannel)
357                    return true;
358    
359            if (::lscp_set_channel_midi_channel(pMainForm->client(), m_iChannelID, iMidiChannel) != LSCP_OK) {
360                    appendMessagesClient("lscp_set_channel_midi_channel");
361                    return false;
362            }
363    
364      if (::lscp_set_channel_midi_channel(client(), m_iChannelID, iMidiChannel) != LSCP_OK) {          appendMessages(QObject::tr("MIDI channel: %1.").arg(iMidiChannel));
         appendMessagesClient("lscp_set_channel_midi_channel");  
         return false;  
     }  
365    
366      m_iMidiChannel = iMidiChannel;          m_iMidiChannel = iMidiChannel;
367      return true;          return true;
368    }
369    
370    
371    // MIDI instrument map accessor.
372    int Channel::midiMap (void) const
373    {
374            return m_iMidiMap;
375    }
376    
377    bool Channel::setMidiMap ( int iMidiMap )
378    {
379            MainForm *pMainForm = MainForm::getInstance();
380            if (pMainForm == nullptr)
381                    return false;
382            if (pMainForm->client() == nullptr || m_iChannelID < 0)
383                    return false;
384            if (m_iInstrumentStatus == 100 && m_iMidiMap == iMidiMap)
385                    return true;
386    #ifdef CONFIG_MIDI_INSTRUMENT
387            if (::lscp_set_channel_midi_map(pMainForm->client(), m_iChannelID, iMidiMap) != LSCP_OK) {
388                    appendMessagesClient("lscp_set_channel_midi_map");
389                    return false;
390            }
391    #endif
392            appendMessages(QObject::tr("MIDI map: %1.").arg(iMidiMap));
393    
394            m_iMidiMap = iMidiMap;
395            return true;
396  }  }
397    
398    
399  // Audio device accessor.  // Audio device accessor.
400  int qsamplerChannel::audioDevice (void)  int Channel::audioDevice (void) const
401  {  {
402      return m_iAudioDevice;          return m_iAudioDevice;
403  }  }
404    
405  bool qsamplerChannel::setAudioDevice ( int iAudioDevice )  bool Channel::setAudioDevice ( int iAudioDevice )
406  {  {
407      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
408          return false;          if (pMainForm == nullptr)
409                    return false;
410            if (pMainForm->client() == nullptr || m_iChannelID < 0)
411                    return false;
412            if (m_iInstrumentStatus == 100 && m_iAudioDevice == iAudioDevice)
413                    return true;
414    
415      if (::lscp_set_channel_audio_device(client(), m_iChannelID, iAudioDevice) != LSCP_OK) {          if (::lscp_set_channel_audio_device(pMainForm->client(), m_iChannelID, iAudioDevice) != LSCP_OK) {
416          appendMessagesClient("lscp_set_channel_audio_device");                  appendMessagesClient("lscp_set_channel_audio_device");
417          return false;                  return false;
418      }          }
419    
420      m_iAudioDevice = iAudioDevice;          appendMessages(QObject::tr("Audio device: %1.").arg(iAudioDevice));
421      return true;  
422            m_iAudioDevice = iAudioDevice;
423            return true;
424  }  }
425    
426    
427  // Audio driver type accessors (DEPRECATED).  // Audio driver type accessors (DEPRECATED).
428  QString& qsamplerChannel::audioDriver (void)  const QString& Channel::audioDriver (void) const
429  {  {
430      return m_sAudioDriver;          return m_sAudioDriver;
431  }  }
432    
433  bool qsamplerChannel::setAudioDriver ( const QString& sAudioDriver )  bool Channel::setAudioDriver ( const QString& sAudioDriver )
434  {  {
435      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
436          return false;          if (pMainForm == nullptr)
437                    return false;
438            if (pMainForm->client() == nullptr || m_iChannelID < 0)
439                    return false;
440            if (m_iInstrumentStatus == 100 && m_sAudioDriver == sAudioDriver)
441                    return true;
442    
443            if (::lscp_set_channel_audio_type(pMainForm->client(),
444                            m_iChannelID, sAudioDriver.toUtf8().constData()) != LSCP_OK) {
445                    appendMessagesClient("lscp_set_channel_audio_type");
446                    return false;
447            }
448    
449      if (::lscp_set_channel_audio_type(client(), m_iChannelID, sAudioDriver.latin1()) != LSCP_OK) {          appendMessages(QObject::tr("Audio driver: %1.").arg(sAudioDriver));
         appendMessagesClient("lscp_set_channel_audio_type");  
         return false;  
     }  
450    
451      m_sAudioDriver = sAudioDriver;          m_sAudioDriver = sAudioDriver;
452      return true;          return true;
453  }  }
454    
455    
456  // Channel volume accessors.  // Channel volume accessors.
457  float qsamplerChannel::volume (void)  float Channel::volume (void) const
458  {  {
459      return m_fVolume;          return m_fVolume;
460  }  }
461    
462  bool qsamplerChannel::setVolume ( float fVolume )  bool Channel::setVolume ( float fVolume )
463  {  {
464      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
465          return false;          if (pMainForm == nullptr)
466                    return false;
467            if (pMainForm->client() == nullptr || m_iChannelID < 0)
468                    return false;
469            if (m_iInstrumentStatus == 100 && m_fVolume == fVolume)
470                    return true;
471    
472      if (::lscp_set_channel_volume(client(), m_iChannelID, fVolume) != LSCP_OK) {          if (::lscp_set_channel_volume(pMainForm->client(), m_iChannelID, fVolume) != LSCP_OK) {
473          appendMessagesClient("lscp_set_channel_volume");                  appendMessagesClient("lscp_set_channel_volume");
474          return false;                  return false;
475      }          }
476    
477            appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
478    
479            m_fVolume = fVolume;
480            return true;
481    }
482    
483    
484    // Sampler channel mute state.
485    bool Channel::channelMute (void) const
486    {
487            return m_bMute;
488    }
489    
490    bool Channel::setChannelMute ( bool bMute )
491    {
492            MainForm *pMainForm = MainForm::getInstance();
493            if (pMainForm == nullptr)
494                    return false;
495            if (pMainForm->client() == nullptr || m_iChannelID < 0)
496                    return false;
497            if (m_iInstrumentStatus == 100 && ((m_bMute && bMute) || (!m_bMute && !bMute)))
498                    return true;
499    
500    #ifdef CONFIG_MUTE_SOLO
501            if (::lscp_set_channel_mute(pMainForm->client(), m_iChannelID, bMute) != LSCP_OK) {
502                    appendMessagesClient("lscp_set_channel_mute");
503                    return false;
504            }
505            appendMessages(QObject::tr("Mute: %1.").arg((int) bMute));
506            m_bMute = bMute;
507            return true;
508    #else
509            return false;
510    #endif
511    }
512    
513    
514    // Sampler channel solo state.
515    bool Channel::channelSolo (void) const
516    {
517            return m_bSolo;
518    }
519    
520    bool Channel::setChannelSolo ( bool bSolo )
521    {
522            MainForm *pMainForm = MainForm::getInstance();
523            if (pMainForm == nullptr)
524                    return false;
525            if (pMainForm->client() == nullptr || m_iChannelID < 0)
526                    return false;
527            if (m_iInstrumentStatus == 100 && ((m_bSolo && bSolo) || (!m_bSolo && !bSolo)))
528                    return true;
529    
530    #ifdef CONFIG_MUTE_SOLO
531            if (::lscp_set_channel_solo(pMainForm->client(), m_iChannelID, bSolo) != LSCP_OK) {
532                    appendMessagesClient("lscp_set_channel_solo");
533                    return false;
534            }
535            appendMessages(QObject::tr("Solo: %1.").arg((int) bSolo));
536            m_bSolo = bSolo;
537            return true;
538    #else
539            return false;
540    #endif
541    }
542    
543    
544    // Audio routing accessors.
545    int Channel::audioChannel ( int iAudioOut ) const
546    {
547            return m_audioRouting[iAudioOut];
548    }
549    
550    bool Channel::setAudioChannel ( int iAudioOut, int iAudioIn )
551    {
552            MainForm *pMainForm = MainForm::getInstance();
553            if (pMainForm == nullptr)
554                    return false;
555            if (pMainForm->client() == nullptr || m_iChannelID < 0)
556                    return false;
557            if (m_iInstrumentStatus == 100 &&
558                            m_audioRouting[iAudioOut] == iAudioIn)
559                    return true;
560    
561            if (::lscp_set_channel_audio_channel(pMainForm->client(),
562                            m_iChannelID, iAudioOut, iAudioIn) != LSCP_OK) {
563                    appendMessagesClient("lscp_set_channel_audio_channel");
564                    return false;
565            }
566    
567            appendMessages(QObject::tr("Audio Channel: %1 -> %2.")
568                    .arg(iAudioOut).arg(iAudioIn));
569    
570            m_audioRouting[iAudioOut] = iAudioIn;
571            return true;
572    }
573    
574      m_fVolume = fVolume;  // The audio routing map itself.
575      return true;  const ChannelRoutingMap& Channel::audioRouting (void) const
576    {
577            return m_audioRouting;
578    }
579    
580    
581    // Istrument name remapper.
582    void Channel::updateInstrumentName (void)
583    {
584    #ifndef CONFIG_INSTRUMENT_NAME
585            m_sInstrumentName = getInstrumentName(m_sInstrumentFile,
586                    m_iInstrumentNr, (options() && options()->bInstrumentNames));
587    #endif
588  }  }
589    
590    
591  // Update whole channel info state.  // Update whole channel info state.
592  bool qsamplerChannel::updateChannelInfo (void)  bool Channel::updateChannelInfo (void)
593  {  {
594      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
595          return false;          if (pMainForm == nullptr)
596                    return false;
597            if (pMainForm->client() == nullptr || m_iChannelID < 0)
598                    return false;
599    
600            // Read channel information.
601            lscp_channel_info_t *pChannelInfo = ::lscp_get_channel_info(pMainForm->client(), m_iChannelID);
602            if (pChannelInfo == nullptr) {
603                    appendMessagesClient("lscp_get_channel_info");
604                    appendMessagesError(QObject::tr("Could not get channel information.\n\nSorry."));
605                    return false;
606            }
607    
608      // Read channel information.  #ifdef CONFIG_INSTRUMENT_NAME
609      lscp_channel_info_t *pChannelInfo = ::lscp_get_channel_info(client(), m_iChannelID);          // We got all actual instrument datum...
610      if (pChannelInfo == NULL) {          m_sInstrumentFile =
611          appendMessagesClient("lscp_get_channel_info");                  qsamplerUtilities::lscpEscapedPathToPosix(pChannelInfo->instrument_file);
612          appendMessagesError(QObject::tr("Could not get channel information.\n\nSorry."));          m_iInstrumentNr   = pChannelInfo->instrument_nr;
613          return false;          m_sInstrumentName =
614      }                  qsamplerUtilities::lscpEscapedTextToRaw(pChannelInfo->instrument_name);
615    #else
616      // First, check if intrument name has changed,          // First, check if intrument name has changed,
617      // taking care that instrument name lookup might be expensive,          // taking care that instrument name lookup might be expensive,
618      // so we better make it only once and when really needed...          // so we better make it only once and when really needed...
619      if ((m_sInstrumentFile != pChannelInfo->instrument_file) ||          if ((m_sInstrumentFile != pChannelInfo->instrument_file) ||
620          (m_iInstrumentNr   != pChannelInfo->instrument_nr)) {                  (m_iInstrumentNr   != pChannelInfo->instrument_nr)) {
621          m_sInstrumentFile = pChannelInfo->instrument_file;                  m_sInstrumentFile = pChannelInfo->instrument_file;
622          m_iInstrumentNr   = pChannelInfo->instrument_nr;                  m_iInstrumentNr   = pChannelInfo->instrument_nr;
623                  m_sInstrumentName = getInstrumentName(m_sInstrumentFile,                  updateInstrumentName();
624                          m_iInstrumentNr, (options() && options()->bInstrumentNames));          }
625          }  #endif
626      // Cache in other channel information.          // Cache in other channel information.
627      m_sEngineName       = pChannelInfo->engine_name;          m_sEngineName       = pChannelInfo->engine_name;
628      m_iInstrumentStatus = pChannelInfo->instrument_status;          m_iInstrumentStatus = pChannelInfo->instrument_status;
629      m_iMidiDevice       = pChannelInfo->midi_device;          m_iMidiDevice       = pChannelInfo->midi_device;
630      m_iMidiPort         = pChannelInfo->midi_port;          m_iMidiPort         = pChannelInfo->midi_port;
631      m_iMidiChannel      = pChannelInfo->midi_channel;          m_iMidiChannel      = pChannelInfo->midi_channel;
632      m_iAudioDevice      = pChannelInfo->audio_device;  #ifdef CONFIG_MIDI_INSTRUMENT
633      m_fVolume           = pChannelInfo->volume;          m_iMidiMap          = pChannelInfo->midi_map;
634      // Some sanity checks.  #endif
635      if (m_sEngineName == "NONE")          m_iAudioDevice      = pChannelInfo->audio_device;
636          m_sEngineName = QString::null;          m_fVolume           = pChannelInfo->volume;
637      if (m_sInstrumentFile == "NONE") {  #ifdef CONFIG_MUTE_SOLO
638          m_sInstrumentFile = QString::null;          m_bMute             = pChannelInfo->mute;
639          m_sInstrumentName = QString::null;          m_bSolo             = pChannelInfo->solo;
640    #endif
641            // Some sanity checks.
642            if (m_sEngineName == "NONE" || m_sEngineName.isEmpty())
643                    m_sEngineName.clear();
644            if (m_sInstrumentFile == "NONE" || m_sInstrumentFile.isEmpty()) {
645                    m_sInstrumentFile.clear();
646                    m_sInstrumentName.clear();
647          }          }
648    
649      return true;          // Time for device info grabbing...
650            lscp_device_info_t *pDeviceInfo;
651            const QString sNone = QObject::tr("(none)");
652            // Audio device driver type.
653            pDeviceInfo = ::lscp_get_audio_device_info(pMainForm->client(), m_iAudioDevice);
654            if (pDeviceInfo == nullptr) {
655                    appendMessagesClient("lscp_get_audio_device_info");
656                    m_sAudioDriver = sNone;
657            } else {
658                    m_sAudioDriver = pDeviceInfo->driver;
659            }
660            // MIDI device driver type.
661            pDeviceInfo = ::lscp_get_midi_device_info(pMainForm->client(), m_iMidiDevice);
662            if (pDeviceInfo == nullptr) {
663                    appendMessagesClient("lscp_get_midi_device_info");
664                    m_sMidiDriver = sNone;
665            } else {
666                    m_sMidiDriver = pDeviceInfo->driver;
667            }
668    
669            // Set the audio routing map.
670            m_audioRouting.clear();
671    #ifdef CONFIG_AUDIO_ROUTING
672            int *piAudioRouting = pChannelInfo->audio_routing;
673            for (int i = 0; piAudioRouting && piAudioRouting[i] >= 0; i++)
674                    m_audioRouting[i] = piAudioRouting[i];
675    #else
676            char **ppszAudioRouting = pChannelInfo->audio_routing;
677            for (int i = 0; ppszAudioRouting && ppszAudioRouting[i]; i++)
678                    m_audioRouting[i] = ::atoi(ppszAudioRouting[i]);
679    #endif
680    
681            return true;
682  }  }
683    
684    
685  // Reset channel method.  // Reset channel method.
686  bool qsamplerChannel::resetChannel (void)  bool Channel::channelReset (void)
687  {  {
688      if (client() == NULL || m_iChannelID < 0)          MainForm *pMainForm = MainForm::getInstance();
689          return false;          if (pMainForm == nullptr)
690                    return false;
691            if (pMainForm->client() == nullptr || m_iChannelID < 0)
692                    return false;
693    
694            if (::lscp_reset_channel(pMainForm->client(), m_iChannelID) != LSCP_OK) {
695                    appendMessagesClient("lscp_reset_channel");
696                    return false;
697            }
698    
699      if (::lscp_reset_channel(client(), m_iChannelID) != LSCP_OK) {          appendMessages(QObject::tr("reset."));
         appendMessagesClient("lscp_reset_channel");  
         return false;  
     }  
700    
701      appendMessages(QObject::tr("Channel %1 reset.").arg(m_iChannelID));          return true;
702      return true;  }
703    
704    
705    // Spawn instrument editor method.
706    bool Channel::editChannel (void)
707    {
708    #ifdef CONFIG_EDIT_INSTRUMENT
709    
710            MainForm *pMainForm = MainForm::getInstance();
711            if (pMainForm == nullptr)
712                    return false;
713            if (pMainForm->client() == nullptr || m_iChannelID < 0)
714                    return false;
715    
716            if (::lscp_edit_channel_instrument(pMainForm->client(), m_iChannelID)
717                    != LSCP_OK) {
718                    appendMessagesClient("lscp_edit_channel_instrument");
719                    appendMessagesError(QObject::tr(
720                            "Could not launch an appropriate instrument editor "
721                            "for the given instrument!\n\n"
722                            "Make sure you have an appropriate "
723                            "instrument editor like 'gigedit' installed "
724                            "and that it placed its mandatory DLL file "
725                            "into the sampler's plugin directory.")
726                    );
727                    return false;
728            }
729    
730            appendMessages(QObject::tr("edit instrument."));
731    
732            return true;
733    
734    #else
735    
736            appendMessagesError(QObject::tr(
737                    "Sorry, QSampler was compiled for a version of liblscp "
738                    "which lacks this feature.\n\n"
739                    "You may want to update liblscp and recompile QSampler afterwards.")
740            );
741    
742            return false;
743    
744    #endif
745  }  }
746    
747    
748  // Channel setup dialog form.  // Channel setup dialog form.
749  bool qsamplerChannel::channelSetup ( QWidget *pParent )  bool Channel::channelSetup ( QWidget *pParent )
750  {  {
751      bool bResult = false;          MainForm *pMainForm = MainForm::getInstance();
752            if (pMainForm == nullptr)
753                    return false;
754    
755      qsamplerChannelForm *pChannelForm = new qsamplerChannelForm(pParent);          bool bResult = false;
     if (pChannelForm) {  
         pChannelForm->setup(this);  
         bResult = pChannelForm->exec();  
         delete pChannelForm;  
     }  
756    
757      return bResult;          appendMessages(QObject::tr("setup..."));
758    
759            ChannelForm *pChannelForm = new ChannelForm(pParent);
760            if (pChannelForm) {
761                    pChannelForm->setup(this);
762                    bResult = pChannelForm->exec();
763                    delete pChannelForm;
764            }
765    
766            return bResult;
767  }  }
768    
769    
770  // Redirected messages output methods.  // Redirected messages output methods.
771  void qsamplerChannel::appendMessages( const QString& s )  void Channel::appendMessages ( const QString& sText ) const
772  {  {
773      if (m_pMainForm) m_pMainForm->appendMessages(s);          MainForm *pMainForm = MainForm::getInstance();
774            if (pMainForm)
775                    pMainForm->appendMessages(channelName() + ' ' + sText);
776  }  }
777    
778  void qsamplerChannel::appendMessagesColor( const QString& s, const QString& c )  void Channel::appendMessagesColor (
779            const QString& sText, const QColor& rgb ) const
780  {  {
781      if (m_pMainForm) m_pMainForm->appendMessagesColor(s, c);          MainForm *pMainForm = MainForm::getInstance();
782            if (pMainForm)
783                    pMainForm->appendMessagesColor(channelName() + ' ' + sText, rgb);
784  }  }
785    
786  void qsamplerChannel::appendMessagesText( const QString& s )  void Channel::appendMessagesText ( const QString& sText ) const
787  {  {
788      if (m_pMainForm) m_pMainForm->appendMessagesText(s);          MainForm *pMainForm = MainForm::getInstance();
789            if (pMainForm)
790                    pMainForm->appendMessagesText(channelName() + ' ' + sText);
791  }  }
792    
793  void qsamplerChannel::appendMessagesError( const QString& s )  void Channel::appendMessagesError ( const QString& sText ) const
794  {  {
795      if (m_pMainForm) m_pMainForm->appendMessagesError(s);          MainForm *pMainForm = MainForm::getInstance();
796            if (pMainForm)
797                    pMainForm->appendMessagesError(channelName() + "\n\n" + sText);
798  }  }
799    
800  void qsamplerChannel::appendMessagesClient( const QString& s )  void Channel::appendMessagesClient ( const QString& sText ) const
801  {  {
802      if (m_pMainForm) m_pMainForm->appendMessagesClient(s);          MainForm *pMainForm = MainForm::getInstance();
803            if (pMainForm)
804                    pMainForm->appendMessagesClient(channelName() + ' ' + sText);
805  }  }
806    
807    
808  // Context menu event handler.  // Context menu event handler.
809  void qsamplerChannel::contextMenuEvent( QContextMenuEvent *pEvent )  void Channel::contextMenuEvent ( QContextMenuEvent *pEvent )
810  {  {
811      if (m_pMainForm) m_pMainForm->contextMenuEvent(pEvent);          MainForm *pMainForm = MainForm::getInstance();
812            if (pMainForm)
813                    pMainForm->contextMenuEvent(pEvent);
814    }
815    
816    
817    // FIXME: Check whether a given file is an instrument file (DLS only).
818    bool Channel::isDlsInstrumentFile ( const QString& sInstrumentFile )
819    {
820            bool bResult = false;
821    
822            QFile file(sInstrumentFile);
823            if (file.open(QIODevice::ReadOnly)) {
824                    char achHeader[16];
825                    if (file.read(achHeader, 16) > 0) {
826                            bResult = (::memcmp(&achHeader[0], "RIFF", 4)     == 0
827                                            && ::memcmp(&achHeader[8], "DLS LIST", 8) == 0);
828                    }
829                    file.close();
830            }
831    
832            return bResult;
833    }
834    
835    
836    // FIXME: Check whether a given file is an instrument file (SF2 only).
837    bool Channel::isSf2InstrumentFile ( const QString& sInstrumentFile )
838    {
839            bool bResult = false;
840    
841            QFile file(sInstrumentFile);
842            if (file.open(QIODevice::ReadOnly)) {
843                    char achHeader[12];
844                    if (file.read(achHeader, 12) > 0) {
845                            bResult = (::memcmp(&achHeader[0], "RIFF", 4) == 0
846                                            && ::memcmp(&achHeader[8], "sfbk", 4) == 0);
847                    }
848                    file.close();
849            }
850    
851            return bResult;
852  }  }
853    
854    
855  // Retrieve the instrument list of a instrument file (.gig).  // Retrieve the instrument list of a instrument file (.gig).
856  QStringList qsamplerChannel::getInstrumentList( const QString& sInstrumentFile,  QStringList Channel::getInstrumentList (
857          bool bInstrumentNames )          const QString& sInstrumentFile, bool bInstrumentNames )
858  {  {
859      QFileInfo fileinfo(sInstrumentFile);          QStringList instlist;
860      QString sInstrumentName = fileinfo.fileName();  
861      QStringList instlist;          const QFileInfo fi(sInstrumentFile);
862            if (!fi.exists()) {
863                    instlist.append(noInstrumentName());
864                    return instlist;
865            }
866    
     if (fileinfo.exists()) {  
867  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
868                  if (bInstrumentNames) {          if (bInstrumentNames) {
869                  RIFF::File *pRiff = new RIFF::File(sInstrumentFile);                  if (isDlsInstrumentFile(sInstrumentFile)) {
870                  gig::File  *pGig  = new gig::File(pRiff);                          RIFF::File *pRiff
871                  gig::Instrument *pInstrument = pGig->GetFirstInstrument();                                  = new RIFF::File(sInstrumentFile.toUtf8().constData());
872                  while (pInstrument) {                          gig::File *pGig = new gig::File(pRiff);
873                      instlist.append((pInstrument->pInfo)->Name.c_str());                  #ifdef CONFIG_LIBGIG_SETAUTOLOAD
874                      pInstrument = pGig->GetNextInstrument();                          // prevent sleepy response time on large .gig files
875                  }                          pGig->SetAutoLoad(false);
876                  delete pGig;                  #endif
877                  delete pRiff;                          gig::Instrument *pInstrument = pGig->GetFirstInstrument();
878                            while (pInstrument) {
879                                    instlist.append((pInstrument->pInfo)->Name.c_str());
880                                    pInstrument = pGig->GetNextInstrument();
881                            }
882                            delete pGig;
883                            delete pRiff;
884                  }                  }
885            #ifdef CONFIG_LIBGIG_SF2
886                  else                  else
887                    if (isSf2InstrumentFile(sInstrumentFile)) {
888                            RIFF::File *pRiff
889                                    = new RIFF::File(sInstrumentFile.toUtf8().constData());
890                            sf2::File *pSf2 = new sf2::File(pRiff);
891                            const int iPresetCount = pSf2->GetPresetCount();
892                            for (int iIndex = 0; iIndex < iPresetCount; ++iIndex) {
893                                    sf2::Preset *pPreset = pSf2->GetPreset(iIndex);
894                                    if (pPreset) {
895                                            instlist.append(pPreset->Name.c_str());
896                                    } else {
897                                            instlist.append(fi.fileName()
898                                                    + " [" + QString::number(iIndex) + "]");
899                                    }
900                            }
901                            delete pSf2;
902                            delete pRiff;
903                    }
904            #endif
905            }
906  #endif  #endif
         for (int iInstrumentNr = 0; iInstrumentNr < QSAMPLER_INSTRUMENT_MAX; iInstrumentNr++)  
             instlist.append(sInstrumentName + " [" + QString::number(iInstrumentNr) + "]");  
     }  
     else instlist.append(sInstrumentName);  
907    
908      return instlist;          if (instlist.isEmpty()) {
909                    for (int iIndex = 0; iIndex < QSAMPLER_INSTRUMENT_MAX; ++iIndex) {
910                            instlist.append(fi.fileName()
911                                    + " [" + QString::number(iIndex) + "]");
912                    }
913            }
914    
915            return instlist;
916  }  }
917    
918    
919  // Retrieve the spacific instrument name of a instrument file (.gig), given its index.  // Retrieve the spacific instrument name of a instrument file (.gig), given its index.
920  QString qsamplerChannel::getInstrumentName( const QString& sInstrumentFile,  QString Channel::getInstrumentName (
921          int iInstrumentNr, bool bInstrumentNames )          const QString& sInstrumentFile, int iInstrumentNr, bool bInstrumentNames )
922  {  {
923      QFileInfo fileinfo(sInstrumentFile);          const QFileInfo fi(sInstrumentFile);
924      QString sInstrumentName = fileinfo.fileName();          if (!fi.exists())
925                    return noInstrumentName();
926    
927            QString sInstrumentName;
928    
     if (fileinfo.exists()) {  
929  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
930                  if (bInstrumentNames) {          if (bInstrumentNames) {
931                  RIFF::File *pRiff = new RIFF::File(sInstrumentFile);                  if (isDlsInstrumentFile(sInstrumentFile)) {
932                  gig::File  *pGig  = new gig::File(pRiff);                          RIFF::File *pRiff
933                  int iIndex = 0;                                  = new RIFF::File(sInstrumentFile.toUtf8().constData());
934                  gig::Instrument *pInstrument = pGig->GetFirstInstrument();                          gig::File *pGig = new gig::File(pRiff);
935                  while (pInstrument) {                  #ifdef CONFIG_LIBGIG_SETAUTOLOAD
936                      if (iIndex == iInstrumentNr) {                          // prevent sleepy response time on large .gig files
937                          sInstrumentName = (pInstrument->pInfo)->Name.c_str();                          pGig->SetAutoLoad(false);
938                          break;                  #endif
939                      }                          int iIndex = 0;
940                      iIndex++;                          gig::Instrument *pInstrument = pGig->GetFirstInstrument();
941                      pInstrument = pGig->GetNextInstrument();                          while (pInstrument) {
942                  }                                  if (iIndex == iInstrumentNr) {
943                  delete pGig;                                          sInstrumentName = (pInstrument->pInfo)->Name.c_str();
944                  delete pRiff;                                          break;
945                                    }
946                                    iIndex++;
947                                    pInstrument = pGig->GetNextInstrument();
948                            }
949                            delete pGig;
950                            delete pRiff;
951                  }                  }
952            #ifdef CONFIG_LIBGIG_SF2
953                  else                  else
954                    if (isSf2InstrumentFile(sInstrumentFile)) {
955                            RIFF::File *pRiff
956                                    = new RIFF::File(sInstrumentFile.toUtf8().constData());
957                            sf2::File *pSf2 = new sf2::File(pRiff);
958                            sf2::Preset *pPreset = pSf2->GetPreset(iInstrumentNr);
959                            if (pPreset)
960                                    sInstrumentName = pPreset->Name.c_str();
961                            delete pSf2;
962                            delete pRiff;
963                    }
964            #endif
965            }
966  #endif  #endif
         sInstrumentName += " [" + QString::number(iInstrumentNr) + "]";  
     }  
967    
968      return sInstrumentName;          if (sInstrumentName.isEmpty()) {
969                    sInstrumentName  = fi.fileName();
970                    sInstrumentName += " [" + QString::number(iInstrumentNr) + "]";
971            }
972    
973            return sInstrumentName;
974    }
975    
976    
977    // Common invalid name-helpers.
978    QString Channel::noEngineName (void)
979    {
980            return QObject::tr("(No engine)");
981    }
982    
983    QString Channel::noInstrumentName (void)
984    {
985            return QObject::tr("(No instrument)");
986    }
987    
988    QString Channel::loadingInstrument (void) {
989            return QObject::tr("(Loading instrument...)");
990    }
991    
992    
993    //-------------------------------------------------------------------------
994    // QSampler::ChannelRoutingModel - data model for audio routing
995    //                                 (used for QTableView)
996    
997    ChannelRoutingModel::ChannelRoutingModel ( QObject *pParent )
998            : QAbstractTableModel(pParent), m_pDevice(nullptr)
999    {
1000    }
1001    
1002    
1003    int ChannelRoutingModel::rowCount ( const QModelIndex& /*parent*/) const
1004    {
1005            return (m_pDevice) ? m_routing.size() : 0;
1006    }
1007    
1008    
1009    int ChannelRoutingModel::columnCount ( const QModelIndex& /*parent*/) const
1010    {
1011            return 1;
1012  }  }
1013    
1014    
1015    Qt::ItemFlags ChannelRoutingModel::flags ( const QModelIndex& /*index*/) const
1016    {
1017            return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
1018    }
1019    
1020    
1021    bool ChannelRoutingModel::setData ( const QModelIndex& index,
1022            const QVariant& value, int /*role*/)
1023    {
1024            if (!index.isValid())
1025                    return false;
1026    
1027            m_routing[index.row()] = value.toInt();
1028    
1029            emit dataChanged(index, index);
1030            return true;
1031    }
1032    
1033    
1034    QVariant ChannelRoutingModel::data ( const QModelIndex &index, int role ) const
1035    {
1036            if (!index.isValid())
1037                    return QVariant();
1038            if (role != Qt::DisplayRole)
1039                    return QVariant();
1040            if (index.column() != 0)
1041                    return QVariant();
1042    
1043            ChannelRoutingItem item;
1044    
1045            // The common device port item list.
1046            DevicePortList& ports = m_pDevice->ports();
1047            QListIterator<DevicePort *> iter(ports);
1048            while (iter.hasNext()) {
1049                    DevicePort *pPort = iter.next();
1050                    item.options.append(
1051                            m_pDevice->deviceTypeName()
1052                            + ' ' + m_pDevice->driverName()
1053                            + ' ' + pPort->portName()
1054                    );
1055            }
1056    
1057            item.selection = m_routing[index.row()];
1058    
1059            return QVariant::fromValue(item);
1060    }
1061    
1062    
1063    QVariant ChannelRoutingModel::headerData ( int section,
1064            Qt::Orientation orientation, int role) const
1065    {
1066            if (role != Qt::DisplayRole)
1067                    return QVariant();
1068    
1069            switch (orientation) {
1070                    case Qt::Horizontal:
1071                            return UNICODE_RIGHT_ARROW + QObject::tr(" Device Channel");
1072                    case Qt::Vertical:
1073                            return QObject::tr("Audio Channel ") +
1074                                    QString::number(section) + " " + UNICODE_RIGHT_ARROW;
1075                    default:
1076                            return QVariant();
1077            }
1078    }
1079    
1080    
1081    void ChannelRoutingModel::refresh ( Device *pDevice,
1082            const ChannelRoutingMap& routing )
1083    {
1084            m_pDevice = pDevice;
1085            m_routing = routing;
1086            // inform the outer world (QTableView) that our data changed
1087    #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1088            QAbstractTableModel::reset();
1089    #else
1090            QAbstractTableModel::beginResetModel();
1091            QAbstractTableModel::endResetModel();
1092    #endif
1093    }
1094    
1095    
1096    //-------------------------------------------------------------------------
1097    // QSampler::ChannelRoutingDelegate - table cell renderer for audio routing
1098    //
1099    
1100    ChannelRoutingDelegate::ChannelRoutingDelegate ( QObject *pParent )
1101            : QItemDelegate(pParent)
1102    {
1103    }
1104    
1105    
1106    QWidget* ChannelRoutingDelegate::createEditor ( QWidget *pParent,
1107            const QStyleOptionViewItem & option, const QModelIndex& index ) const
1108    {
1109            if (!index.isValid())
1110                    return nullptr;
1111    
1112            if (index.column() != 0)
1113                    return nullptr;
1114    
1115            ChannelRoutingItem item = index.model()->data(index, Qt::DisplayRole).value<ChannelRoutingItem>();
1116    
1117            QComboBox* pComboBox = new QComboBox(pParent);
1118            pComboBox->addItems(item.options);
1119            pComboBox->setCurrentIndex(item.selection);
1120            pComboBox->setEnabled(true);
1121            pComboBox->setEditable(true);
1122            pComboBox->setGeometry(option.rect);
1123            return pComboBox;
1124    }
1125    
1126    
1127    void ChannelRoutingDelegate::setEditorData ( QWidget *pEditor,
1128            const QModelIndex &index) const
1129    {
1130            ChannelRoutingItem item = index.model()->data(index,
1131                    Qt::DisplayRole).value<ChannelRoutingItem> ();
1132            QComboBox* pComboBox = static_cast<QComboBox*> (pEditor);
1133            pComboBox->setCurrentIndex(item.selection);
1134    }
1135    
1136    
1137    void ChannelRoutingDelegate::setModelData ( QWidget* pEditor,
1138            QAbstractItemModel *pModel, const QModelIndex& index ) const
1139    {
1140            QComboBox *pComboBox = static_cast<QComboBox*> (pEditor);
1141            pModel->setData(index, pComboBox->currentIndex());
1142    }
1143    
1144    
1145    void ChannelRoutingDelegate::updateEditorGeometry ( QWidget *pEditor,
1146            const QStyleOptionViewItem& option, const QModelIndex &/* index */) const
1147    {
1148            pEditor->setGeometry(option.rect);
1149    }
1150    
1151    } // namespace QSampler
1152    
1153    
1154  // end of qsamplerChannel.cpp  // end of qsamplerChannel.cpp

Legend:
Removed from v.344  
changed lines
  Added in v.3855

  ViewVC Help
Powered by ViewVC