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

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

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

revision 1461 by schoenebeck, Sun Oct 28 23:30:36 2007 UTC revision 3555 by capela, Tue Aug 13 10:19:32 2019 UTC
# Line 1  Line 1 
1    // qsamplerChannelStrip.cpp
2    //
3    /****************************************************************************
4       Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5       Copyright (C) 2007, 2008, 2014 Christian Schoenebeck
6    
7       This program is free software; you can redistribute it and/or
8       modify it under the terms of the GNU General Public License
9       as published by the Free Software Foundation; either version 2
10       of the License, or (at your option) any later version.
11    
12       This program is distributed in the hope that it will be useful,
13       but WITHOUT ANY WARRANTY; without even the implied warranty of
14       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15       GNU General Public License for more details.
16    
17       You should have received a copy of the GNU General Public License along
18       with this program; if not, write to the Free Software Foundation, Inc.,
19       51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21    *****************************************************************************/
22    
23    #include "qsamplerAbout.h"
24  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
25    
26  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
27    
28  #include <q3dragobject.h>  #include "qsamplerChannelFxForm.h"
29    
30    #include <QMessageBox>
31    #include <QDragEnterEvent>
32    #include <QFileInfo>
33    #include <QTimer>
34  #include <QUrl>  #include <QUrl>
35    #include <QMenu>
36    
37  #include <math.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
38    #include <QMimeData>
39    #endif
40    
41  // Channel status/usage usage limit control.  // Channel status/usage usage limit control.
42  #define QSAMPLER_ERROR_LIMIT    3  #define QSAMPLER_ERROR_LIMIT    3
43    
44    // Needed for lroundf()
45    #include <math.h>
46    
47    #ifndef CONFIG_ROUND
48    static inline long lroundf ( float x )
49    {
50            if (x >= 0.0f)
51                    return long(x + 0.5f);
52            else
53                    return long(x - 0.5f);
54    }
55    #endif
56    
57    
58  namespace QSampler {  namespace QSampler {
59    
60  ChannelStrip::ChannelStrip(QWidget* parent, Qt::WFlags f) : QWidget(parent, f) {  //-------------------------------------------------------------------------
61      ui.setupUi(this);  // QSampler::ChannelStrip -- Channel strip form implementation.
62    //
63    
64    // MIDI activity pixmap common resources.
65    int      ChannelStrip::g_iMidiActivityRefCount = 0;
66    QPixmap *ChannelStrip::g_pMidiActivityLedOn    = nullptr;
67    QPixmap *ChannelStrip::g_pMidiActivityLedOff   = nullptr;
68    
69    // Channel strip activation/selection.
70    ChannelStrip *ChannelStrip::g_pSelectedStrip = nullptr;
71    
72    ChannelStrip::ChannelStrip ( QWidget* pParent, Qt::WindowFlags wflags )
73            : QWidget(pParent, wflags)
74    {
75            m_ui.setupUi(this);
76    
77            // Initialize locals.
78            m_pChannel     = nullptr;
79            m_iDirtyChange = 0;
80            m_iErrorCount  = 0;
81            m_instrumentListPopupMenu = nullptr;
82    
83            if (++g_iMidiActivityRefCount == 1) {
84                    g_pMidiActivityLedOn  = new QPixmap(":/images/ledon1.png");
85                    g_pMidiActivityLedOff = new QPixmap(":/images/ledoff1.png");
86            }
87    
88      // Initialize locals.          m_ui.MidiActivityLabel->setPixmap(*g_pMidiActivityLedOff);
     m_pChannel     = NULL;  
     m_iDirtyChange = 0;  
     m_iErrorCount  = 0;  
89    
90      // Try to restore normal window positioning.  #ifndef CONFIG_EVENT_CHANNEL_MIDI
91      adjustSize();          m_ui.MidiActivityLabel->setToolTip("MIDI activity (disabled)");
92  }  #endif
93    
94            m_pMidiActivityTimer = new QTimer(this);
95            m_pMidiActivityTimer->setSingleShot(true);
96    
97  ChannelStrip::~ChannelStrip() {          QObject::connect(m_pMidiActivityTimer,
98      // Destroy existing channel descriptor.                  SIGNAL(timeout()),
99      if (m_pChannel)                  SLOT(midiActivityLedOff())
100          delete m_pChannel;          );
101      m_pChannel = NULL;  
102            // Try to restore normal window positioning.
103            adjustSize();
104    
105            QObject::connect(m_ui.ChannelSetupPushButton,
106                    SIGNAL(clicked()),
107                    SLOT(channelSetup()));
108            QObject::connect(m_ui.ChannelMutePushButton,
109                    SIGNAL(toggled(bool)),
110                    SLOT(channelMute(bool)));
111            QObject::connect(m_ui.ChannelSoloPushButton,
112                    SIGNAL(toggled(bool)),
113                    SLOT(channelSolo(bool)));
114            QObject::connect(m_ui.ChannelVolumeSlider,
115                    SIGNAL(valueChanged(int)),
116                    SLOT(volumeChanged(int)));
117            QObject::connect(m_ui.ChannelVolumeSpinBox,
118                    SIGNAL(valueChanged(int)),
119                    SLOT(volumeChanged(int)));
120            QObject::connect(m_ui.ChannelEditPushButton,
121                    SIGNAL(clicked()),
122                    SLOT(channelEdit()));
123            QObject::connect(m_ui.ChannelFxPushButton,
124                    SIGNAL(clicked()),
125                    SLOT(channelFxEdit()));
126    
127            setSelected(false);
128  }  }
129    
130    
131  // Drag'n'drop file handler.  ChannelStrip::~ChannelStrip (void)
 bool ChannelStrip::decodeDragFile ( const QMimeSource *pEvent, QString& sInstrumentFile )  
132  {  {
133          if (m_pChannel == NULL)          setSelected(false);
134                  return false;  
135          if (Q3TextDrag::canDecode(pEvent)) {          // Destroy existing channel descriptor.
136                  QString sText;          if (m_pChannel)
137                  if (Q3TextDrag::decode(pEvent, sText)) {                  delete m_pChannel;
138                          QStringList files = QStringList::split('\n', sText);          m_pChannel = nullptr;
139                          for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {  
140                                  *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();          if (--g_iMidiActivityRefCount == 0) {
141                                  if (qsamplerChannel::isInstrumentFile(*iter)) {                  if (g_pMidiActivityLedOn)
142                                          sInstrumentFile = *iter;                          delete g_pMidiActivityLedOn;
143                                          return true;                  g_pMidiActivityLedOn = nullptr;
144                                  }                  if (g_pMidiActivityLedOff)
145                          }                          delete g_pMidiActivityLedOff;
146                  }                  g_pMidiActivityLedOff = nullptr;
147          }          }
         // Fail.  
         return false;  
148  }  }
149    
150    
151  // Window drag-n-drop event handlers.  // Window drag-n-drop event handlers.
152  void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
153  {  {
154          QString sInstrumentFile;          if (m_pChannel == nullptr)
155          pDragEnterEvent->accept(decodeDragFile(pDragEnterEvent, sInstrumentFile));                  return;
156    
157            bool bAccept = false;
158    
159            if (pDragEnterEvent->source() == nullptr) {
160                    const QMimeData *pMimeData = pDragEnterEvent->mimeData();
161                    if (pMimeData && pMimeData->hasUrls()) {
162                            QListIterator<QUrl> iter(pMimeData->urls());
163                            while (iter.hasNext()) {
164                                    const QString& sFilename = iter.next().toLocalFile();
165                                    if (!sFilename.isEmpty()) {
166                                    //      bAccept = Channel::isDlsInstrumentFile(sFilename);
167                                            bAccept = QFileInfo(sFilename).exists();
168                                            break;
169                                    }
170                            }
171                    }
172            }
173    
174            if (bAccept)
175                    pDragEnterEvent->accept();
176            else
177                    pDragEnterEvent->ignore();
178  }  }
179    
180    
181  void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )  void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
182  {  {
183          QString sInstrumentFile;          if (m_pChannel == nullptr)
184                    return;
185    
186            if (pDropEvent->source())
187                    return;
188    
189          if (decodeDragFile(pDropEvent, sInstrumentFile)) {          const QMimeData *pMimeData = pDropEvent->mimeData();
190                  // Go and set the dropped instrument filename...          if (pMimeData && pMimeData->hasUrls()) {
191                  m_pChannel->setInstrument(sInstrumentFile, 0);                  QStringList files;
192                  // Open up the channel dialog.                  QListIterator<QUrl> iter(pMimeData->urls());
193                  channelSetup();                  while (iter.hasNext()) {
194                            const QString& sFilename = iter.next().toLocalFile();
195                            if (!sFilename.isEmpty()) {
196                                    // Go and set the dropped instrument filename...
197                                    m_pChannel->setInstrument(sFilename, 0);
198                                    // Open up the channel dialog.
199                                    channelSetup();
200                                    break;
201                            }
202                    }
203          }          }
204  }  }
205    
206    
207  // Channel strip setup formal initializer.  // Channel strip setup formal initializer.
208  void ChannelStrip::setup ( qsamplerChannel *pChannel )  void ChannelStrip::setup ( Channel *pChannel )
209  {  {
210      // Destroy any previous channel descriptor;          // Destroy any previous channel descriptor;
211      // (remember that once setup we own it!)          // (remember that once setup we own it!)
212      if (m_pChannel)          if (m_pChannel)
213          delete m_pChannel;                  delete m_pChannel;
214    
215      // Set the new one...          // Set the new one...
216      m_pChannel = pChannel;          m_pChannel = pChannel;
217    
218      // Stabilize this around.          // Stabilize this around.
219      updateChannelInfo();          updateChannelInfo();
220    
221          // We'll accept drops from now on...          // We'll accept drops from now on...
222          if (m_pChannel)          if (m_pChannel)
223                  setAcceptDrops(true);                  setAcceptDrops(true);
224  }  }
225    
226    
227  // Channel secriptor accessor.  // Channel secriptor accessor.
228  qsamplerChannel *ChannelStrip::channel (void)  Channel *ChannelStrip::channel (void) const
229  {  {
230      return m_pChannel;          return m_pChannel;
231  }  }
232    
233    
234  // Messages view font accessors.  // Messages view font accessors.
235  QFont ChannelStrip::displayFont (void)  QFont ChannelStrip::displayFont (void) const
236  {  {
237      return ui.EngineNameTextLabel->font();          return m_ui.EngineNameTextLabel->font();
238  }  }
239    
240    
241  void ChannelStrip::setDisplayFont ( const QFont & font )  void ChannelStrip::setDisplayFont ( const QFont & font )
242  {  {
243      ui.EngineNameTextLabel->setFont(font);          m_ui.EngineNameTextLabel->setFont(font);
244      ui.MidiPortChannelTextLabel->setFont(font);          m_ui.MidiPortChannelTextLabel->setFont(font);
245      ui.InstrumentNameTextLabel->setFont(font);          m_ui.InstrumentNamePushButton->setFont(font);
246      ui.InstrumentStatusTextLabel->setFont(font);          m_ui.InstrumentStatusTextLabel->setFont(font);
247  }  }
248    
249    
250  // Channel display background effect.  // Channel display background effect.
251  void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )  void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
252  {  {
253      QPixmap pm =          QPalette pal;
254          (bDisplayEffect) ?          pal.setColor(QPalette::Foreground, Qt::yellow);
255              QPixmap(":/qsampler/pixmaps/displaybg1.png") : QPixmap();          pal.setColor(QPalette::ButtonText, Qt::yellow);
256      setDisplayBackground(pm);          m_ui.EngineNameTextLabel->setPalette(pal);
257  }          m_ui.MidiPortChannelTextLabel->setPalette(pal);
258            pal.setColor(QPalette::Foreground, Qt::green);
259            pal.setColor(QPalette::ButtonText, Qt::green);
260  // Update main display background pixmap.          if (bDisplayEffect) {
261  void ChannelStrip::setDisplayBackground ( const QPixmap& pm )                  QPixmap pm(":/images/displaybg1.png");
262  {                  pal.setBrush(QPalette::Background, QBrush(pm));
263      // Set the main origin...          } else {
264      ui.ChannelInfoFrame->setPaletteBackgroundPixmap(pm);                  pal.setColor(QPalette::Background, Qt::black);
265            }
266      // Iterate for every child text label...          m_ui.ChannelInfoFrame->setPalette(pal);
267      QList<QObject*> list = ui.ChannelInfoFrame->queryList("QLabel");          m_ui.InstrumentNamePushButton->setPalette(pal);
268      for (QList<QObject*>::iterator iter = list.begin(); iter != list.end(); iter++) {          m_ui.StreamVoiceCountTextLabel->setPalette(pal);
         static_cast<QLabel*>(*iter)->setPaletteBackgroundPixmap(pm);  
     }  
   
     // And this standalone too.  
     ui.StreamVoiceCountTextLabel->setPaletteBackgroundPixmap(pm);  
269  }  }
270    
271    
272  // Maximum volume slider accessors.  // Maximum volume slider accessors.
273  void ChannelStrip::setMaxVolume ( int iMaxVolume )  void ChannelStrip::setMaxVolume ( int iMaxVolume )
274  {  {
275      m_iDirtyChange++;          m_iDirtyChange++;
276      ui.VolumeSlider->setRange(0, iMaxVolume);          m_ui.ChannelVolumeSlider->setRange(0, iMaxVolume);
277      ui.VolumeSpinBox->setRange(0, iMaxVolume);          m_ui.ChannelVolumeSpinBox->setRange(0, iMaxVolume);
278      m_iDirtyChange--;          m_iDirtyChange--;
279  }  }
280    
281    
282  // Channel setup dialog slot.  // Channel setup dialog slot.
283  bool ChannelStrip::channelSetup (void)  bool ChannelStrip::channelSetup (void)
284  {  {
285          if (m_pChannel == NULL)          if (m_pChannel == nullptr)
286                  return false;                  return false;
287    
288          // Invoke the channel setup dialog.          // Invoke the channel setup dialog.
289          bool bResult = m_pChannel->channelSetup(this);          const bool bResult = m_pChannel->channelSetup(this);
290          // Notify that this channel has changed.          // Notify that this channel has changed.
291          if (bResult)          if (bResult)
292                  emit channelChanged(this);                  emit channelChanged(this);
# Line 174  bool ChannelStrip::channelSetup (void) Line 298  bool ChannelStrip::channelSetup (void)
298  // Channel mute slot.  // Channel mute slot.
299  bool ChannelStrip::channelMute ( bool bMute )  bool ChannelStrip::channelMute ( bool bMute )
300  {  {
301          if (m_pChannel == NULL)          if (m_pChannel == nullptr)
302                  return false;                  return false;
303    
304          // Invoke the channel mute method.          // Invoke the channel mute method.
305          bool bResult = m_pChannel->setChannelMute(bMute);          const bool bResult = m_pChannel->setChannelMute(bMute);
306          // Notify that this channel has changed.          // Notify that this channel has changed.
307          if (bResult)          if (bResult)
308                  emit channelChanged(this);                  emit channelChanged(this);
# Line 190  bool ChannelStrip::channelMute ( bool bM Line 314  bool ChannelStrip::channelMute ( bool bM
314  // Channel solo slot.  // Channel solo slot.
315  bool ChannelStrip::channelSolo ( bool bSolo )  bool ChannelStrip::channelSolo ( bool bSolo )
316  {  {
317          if (m_pChannel == NULL)          if (m_pChannel == nullptr)
318                  return false;                  return false;
319    
320          // Invoke the channel solo method.          // Invoke the channel solo method.
321          bool bResult = m_pChannel->setChannelSolo(bSolo);          const bool bResult = m_pChannel->setChannelSolo(bSolo);
322          // Notify that this channel has changed.          // Notify that this channel has changed.
323          if (bResult)          if (bResult)
324                  emit channelChanged(this);                  emit channelChanged(this);
# Line 206  bool ChannelStrip::channelSolo ( bool bS Line 330  bool ChannelStrip::channelSolo ( bool bS
330  // Channel edit slot.  // Channel edit slot.
331  void ChannelStrip::channelEdit (void)  void ChannelStrip::channelEdit (void)
332  {  {
333          if (m_pChannel == NULL)          if (m_pChannel == nullptr)
334                  return;                  return;
335    
336          m_pChannel->editChannel();          m_pChannel->editChannel();
337  }  }
338    
339    bool ChannelStrip::channelFxEdit (void)
340    {
341            MainForm *pMainForm = MainForm::getInstance();
342            if (!pMainForm || !channel())
343                    return false;
344    
345            pMainForm->appendMessages(QObject::tr("channel fx sends..."));
346    
347            bool bResult = false;
348    
349    #if CONFIG_FXSEND
350            ChannelFxForm *pChannelFxForm =
351                    new ChannelFxForm(channel(), parentWidget());
352            if (pChannelFxForm) {
353                    //pChannelForm->setup(this);
354                    bResult = pChannelFxForm->exec();
355                    delete pChannelFxForm;
356            }
357    #else // CONFIG_FXSEND
358            QMessageBox::critical(this,
359                    QSAMPLER_TITLE ": " + tr("Unavailable"),
360                            tr("Sorry, QSampler was built without FX send support!\n\n"
361                               "(Make sure you have a recent liblscp when recompiling QSampler)"));
362    #endif // CONFIG_FXSEND
363    
364            return bResult;
365    }
366    
367    
368  // Channel reset slot.  // Channel reset slot.
369  bool ChannelStrip::channelReset (void)  bool ChannelStrip::channelReset (void)
370  {  {
371          if (m_pChannel == NULL)          if (m_pChannel == nullptr)
372                  return false;                  return false;
373    
374          // Invoke the channel reset method.          // Invoke the channel reset method.
375          bool bResult = m_pChannel->channelReset();          const bool bResult = m_pChannel->channelReset();
376          // Notify that this channel has changed.          // Notify that this channel has changed.
377          if (bResult)          if (bResult)
378                  emit channelChanged(this);                  emit channelChanged(this);
# Line 232  bool ChannelStrip::channelReset (void) Line 384  bool ChannelStrip::channelReset (void)
384  // Update the channel instrument name.  // Update the channel instrument name.
385  bool ChannelStrip::updateInstrumentName ( bool bForce )  bool ChannelStrip::updateInstrumentName ( bool bForce )
386  {  {
387          if (m_pChannel == NULL)          if (m_pChannel == nullptr)
388                  return false;                  return false;
389    
390          // Do we refresh the actual name?          // Do we refresh the actual name?
# Line 241  bool ChannelStrip::updateInstrumentName Line 393  bool ChannelStrip::updateInstrumentName
393    
394          // Instrument name...          // Instrument name...
395          if (m_pChannel->instrumentName().isEmpty()) {          if (m_pChannel->instrumentName().isEmpty()) {
396                  if (m_pChannel->instrumentStatus() >= 0)                  if (m_pChannel->instrumentStatus() >= 0) {
397                          ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::loadingInstrument());                          m_ui.InstrumentNamePushButton->setText(
398                  else                                  ' ' + Channel::loadingInstrument());
399                          ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName());                  } else {
400          } else                          m_ui.InstrumentNamePushButton->setText(
401                  ui.InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName());                                  ' ' + Channel::noInstrumentName());
402                    }
403            } else {
404                    m_ui.InstrumentNamePushButton->setText(
405                            ' ' + m_pChannel->instrumentName());
406            }
407            
408            bool bShowInstrumentPopup = false;
409    
410            // Instrument list popup (for fast switching among sounds of the same file)
411            if (!m_pChannel->instrumentFile().isEmpty()) {
412                    const QStringList instruments
413                            = Channel::getInstrumentList(m_pChannel->instrumentFile(), true);
414                    if (!instruments.isEmpty()) {
415                            bShowInstrumentPopup = true;
416                            if (!m_instrumentListPopupMenu) {
417                                    m_instrumentListPopupMenu
418                                            = new QMenu(m_ui.InstrumentNamePushButton);
419                                    m_instrumentListPopupMenu->setTitle(tr("Instruments"));
420                                    // for cosmetical reasons, should have at least
421                                    // the width of the instrument name label...
422                                    m_instrumentListPopupMenu->setMinimumWidth(120);
423                                    m_ui.InstrumentNamePushButton->setMenu(m_instrumentListPopupMenu);
424                                    QObject::connect(m_instrumentListPopupMenu,
425                                            SIGNAL(triggered(QAction*)),
426                                            SLOT(instrumentListPopupItemClicked(QAction *)));
427                            } else {
428                                    m_instrumentListPopupMenu->clear();
429                            }
430                            QAction *action;
431                            for (int i = 0; i < instruments.size(); ++i) {
432                                    action = m_instrumentListPopupMenu->addAction(instruments.at(i));
433                                    action->setData(i);
434                                    action->setCheckable(true);
435                                    action->setChecked(i == m_pChannel->instrumentNr());
436                            }
437                    }
438            }
439    
440            if (!bShowInstrumentPopup && m_instrumentListPopupMenu) {
441                    delete m_instrumentListPopupMenu;
442                    m_instrumentListPopupMenu = nullptr;
443            }
444    
445          return true;          return true;
446  }  }
447    
448    
449    void ChannelStrip::instrumentListPopupItemClicked ( QAction *action )
450    {
451            if (!action) return;
452    
453            QVariant data = action->data();
454            if (data.isValid() && !m_pChannel->instrumentFile().isEmpty()) {
455                    m_pChannel->loadInstrument(m_pChannel->instrumentFile(), data.toInt());
456                    emit channelChanged(this);
457            }
458    }
459    
460    
461  // Do the dirty volume change.  // Do the dirty volume change.
462  bool ChannelStrip::updateChannelVolume (void)  bool ChannelStrip::updateChannelVolume (void)
463  {  {
464      if (m_pChannel == NULL)          if (m_pChannel == nullptr)
465          return false;                  return false;
   
     // Convert...  
 #ifdef CONFIG_ROUND  
     int iVolume = (int) ::round(100.0 * m_pChannel->volume());  
 #else  
     double fIPart = 0.0;  
     double fFPart = ::modf(100.0 * m_pChannel->volume(), &fIPart);  
     int iVolume = (int) fIPart;  
     if (fFPart >= +0.5)  
         iVolume++;  
     else  
     if (fFPart <= -0.5)  
         iVolume--;  
 #endif  
466    
467      // And clip...          // Convert...
468      if (iVolume < 0)          int iVolume = ::lroundf(100.0f * m_pChannel->volume());
469          iVolume = 0;          // And clip...
470            if (iVolume < 0)
471      // Flag it here, to avoid infinite recursion.                  iVolume = 0;
472      m_iDirtyChange++;  
473      ui.VolumeSlider->setValue(iVolume);          // Flag it here, to avoid infinite recursion.
474      ui.VolumeSpinBox->setValue(iVolume);          m_iDirtyChange++;
475      m_iDirtyChange--;          m_ui.ChannelVolumeSlider->setValue(iVolume);
476            m_ui.ChannelVolumeSpinBox->setValue(iVolume);
477            m_iDirtyChange--;
478    
479      return true;          return true;
480  }  }
481    
482    
483  // Update whole channel info state.  // Update whole channel info state.
484  bool ChannelStrip::updateChannelInfo (void)  bool ChannelStrip::updateChannelInfo (void)
485  {  {
486      if (m_pChannel == NULL)          if (m_pChannel == nullptr)
487          return false;                  return false;
488    
489          // Check for error limit/recycle...          // Check for error limit/recycle...
490          if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)          if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
491                  return true;                  return true;
492    
493      // Update strip caption.          // Update strip caption.
494      QString sText = m_pChannel->channelName();          const QString& sText = m_pChannel->channelName();
495      setCaption(sText);          setWindowTitle(sText);
496      ui.ChannelSetupPushButton->setText(sText);          m_ui.ChannelSetupPushButton->setText('&' + sText);
497    
498      // Check if we're up and connected.          // Check if we're up and connected.
499          MainForm* pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
500          if (pMainForm->client() == NULL)          if (pMainForm->client() == nullptr)
501                  return false;                  return false;
502    
503      // Read actual channel information.          // Read actual channel information.
504      m_pChannel->updateChannelInfo();          m_pChannel->updateChannelInfo();
505    
506      // Engine name...          // Engine name...
507      if (m_pChannel->engineName().isEmpty())          if (m_pChannel->engineName().isEmpty()) {
508          ui.EngineNameTextLabel->setText(' ' + qsamplerChannel::noEngineName());                  m_ui.EngineNameTextLabel->setText(
509      else                          ' ' + Channel::noEngineName());
510          ui.EngineNameTextLabel->setText(' ' + m_pChannel->engineName());          } else {
511                    m_ui.EngineNameTextLabel->setText(
512                            ' ' + m_pChannel->engineName());
513            }
514    
515          // Instrument name...          // Instrument name...
516          updateInstrumentName(false);          updateInstrumentName(false);
517    
518      // MIDI Port/Channel...          // MIDI Port/Channel...
519          QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";          QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";
520          if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)          if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
521                  sMidiPortChannel += tr("All");                  sMidiPortChannel += tr("All");
522          else          else
523                  sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);                  sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);
524          ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);          m_ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
525    
526      // Instrument status...          // Common palette...
527      int iInstrumentStatus = m_pChannel->instrumentStatus();          QPalette pal;
528      if (iInstrumentStatus < 0) {          const QColor& rgbFore = pal.color(QPalette::Foreground);
529          ui.InstrumentStatusTextLabel->setPaletteForegroundColor(Qt::red);  
530          ui.InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus));          // Instrument status...
531          m_iErrorCount++;          const int iInstrumentStatus = m_pChannel->instrumentStatus();
532          return false;          if (iInstrumentStatus < 0) {
533      }                  pal.setColor(QPalette::Foreground, Qt::red);
534      // All seems normal...                  m_ui.InstrumentStatusTextLabel->setPalette(pal);
535      ui.InstrumentStatusTextLabel->setPaletteForegroundColor(iInstrumentStatus < 100 ? Qt::yellow : Qt::green);                  m_ui.InstrumentStatusTextLabel->setText(
536      ui.InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + '%');                          tr("ERR%1").arg(iInstrumentStatus));
537      m_iErrorCount = 0;                  m_iErrorCount++;
538                    return false;
539            }
540    
541            // All seems normal...
542            pal.setColor(QPalette::Foreground,
543                    iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
544            m_ui.InstrumentStatusTextLabel->setPalette(pal);
545            m_ui.InstrumentStatusTextLabel->setText(
546                    QString::number(iInstrumentStatus) + '%');
547            m_iErrorCount = 0;
548    
549  #ifdef CONFIG_MUTE_SOLO  #ifdef CONFIG_MUTE_SOLO
550      // Mute/Solo button state coloring...          // Mute/Solo button state coloring...
551      const QColor& rgbNormal = ChannelSetupPushButton->paletteBackgroundColor();          const bool bMute = m_pChannel->channelMute();
552      bool bMute = m_pChannel->channelMute();          const QColor& rgbButton = pal.color(QPalette::Button);
553      ChannelMutePushButton->setPaletteBackgroundColor(bMute ? Qt::yellow : rgbNormal);          const QColor& rgbButtonText = pal.color(QPalette::ButtonText);
554      ChannelMutePushButton->setDown(bMute);          pal.setColor(QPalette::Foreground, rgbFore);
555      bool bSolo = m_pChannel->channelSolo();          pal.setColor(QPalette::Button, bMute ? Qt::yellow : rgbButton);
556      ChannelSoloPushButton->setPaletteBackgroundColor(bSolo ? Qt::cyan : rgbNormal);          pal.setColor(QPalette::ButtonText, bMute ? Qt::darkYellow : rgbButtonText);
557      ChannelSoloPushButton->setDown(bSolo);          m_ui.ChannelMutePushButton->setPalette(pal);
558            m_ui.ChannelMutePushButton->setDown(bMute);
559            const bool bSolo = m_pChannel->channelSolo();
560            pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);  
561            pal.setColor(QPalette::ButtonText, bSolo ? Qt::darkCyan : rgbButtonText);
562            m_ui.ChannelSoloPushButton->setPalette(pal);
563            m_ui.ChannelSoloPushButton->setDown(bSolo);
564  #else  #else
565          ui.ChannelMutePushButton->setEnabled(false);          m_ui.ChannelMutePushButton->setEnabled(false);
566          ui.ChannelSoloPushButton->setEnabled(false);          m_ui.ChannelSoloPushButton->setEnabled(false);
567  #endif  #endif
568    
569      // And update the both GUI volume elements;          // And update the both GUI volume elements;
570      // return success if, and only if, intrument is fully loaded...          // return success if, and only if, intrument is fully loaded...
571      return updateChannelVolume() && (iInstrumentStatus == 100);          return updateChannelVolume() && (iInstrumentStatus == 100);
572  }  }
573    
574    
575  // Update whole channel usage state.  // Update whole channel usage state.
576  bool ChannelStrip::updateChannelUsage (void)  bool ChannelStrip::updateChannelUsage (void)
577  {  {
578      if (m_pChannel == NULL)          if (m_pChannel == nullptr)
579          return false;                  return false;
580    
581          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
582          if (pMainForm->client() == NULL)          if (pMainForm->client() == nullptr)
583                  return false;                  return false;
584    
585          // This only makes sense on fully loaded channels...          // This only makes sense on fully loaded channels...
586          if (m_pChannel->instrumentStatus() < 100)          if (m_pChannel->instrumentStatus() < 100)
587              return false;                  return false;
588    
589      // Get current channel voice count.          // Get current channel voice count.
590      int iVoiceCount  = ::lscp_get_channel_voice_count(pMainForm->client(), m_pChannel->channelID());          const int iVoiceCount  = ::lscp_get_channel_voice_count(
591      // Get current stream count.                  pMainForm->client(), m_pChannel->channelID());
592      int iStreamCount = ::lscp_get_channel_stream_count(pMainForm->client(), m_pChannel->channelID());          // Get current stream count.
593      // Get current channel buffer fill usage.          const int iStreamCount = ::lscp_get_channel_stream_count(
594      // As benno has suggested this is the percentage usage                  pMainForm->client(), m_pChannel->channelID());
595      // of the least filled buffer stream...          // Get current channel buffer fill usage.
596      int iStreamUsage = ::lscp_get_channel_stream_usage(pMainForm->client(), m_pChannel->channelID());;          // As benno has suggested this is the percentage usage
597            // of the least filled buffer stream...
598      // Update the GUI elements...          const int iStreamUsage = ::lscp_get_channel_stream_usage(
599      ui.StreamUsageProgressBar->setValue(iStreamUsage);                  pMainForm->client(), m_pChannel->channelID());
600      ui.StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));  
601            // Update the GUI elements...
602            m_ui.StreamUsageProgressBar->setValue(iStreamUsage);
603            m_ui.StreamVoiceCountTextLabel->setText(
604                    QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
605    
606      // We're clean.          // We're clean.
607      return true;          return true;
608  }  }
609    
610    
611  // Volume change slot.  // Volume change slot.
612  void ChannelStrip::volumeChanged ( int iVolume )  void ChannelStrip::volumeChanged ( int iVolume )
613  {  {
614      if (m_pChannel == NULL)          if (m_pChannel == nullptr)
615          return;                  return;
616    
617            // Avoid recursion.
618            if (m_iDirtyChange > 0)
619                    return;
620    
621      // Avoid recursion.          // Convert and clip.
622      if (m_iDirtyChange > 0)          float fVolume = (float) iVolume / 100.0f;
623          return;          if (fVolume < 0.001f)
624                    fVolume = 0.0f;
625      // Convert and clip.  
626      float fVolume = (float) iVolume / 100.0;          // Update the GUI elements.
627      if (fVolume < 0.001)          if (m_pChannel->setVolume(fVolume)) {
628          fVolume = 0.0;                  updateChannelVolume();
629                    emit channelChanged(this);
630      // Update the GUI elements.          }
     if (m_pChannel->setVolume(fVolume)) {  
         updateChannelVolume();  
         emit channelChanged(this);  
     }  
631  }  }
632    
633    
634  // Context menu event handler.  // Context menu event handler.
635  void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )  void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
636  {  {
637      if (m_pChannel == NULL)          if (m_pChannel == nullptr)
638          return;                  return;
639    
640      // We'll just show up the main form's edit menu (thru qsamplerChannel).          // We'll just show up the main form's edit menu (thru qsamplerChannel).
641      m_pChannel->contextMenuEvent(pEvent);          m_pChannel->contextMenuEvent(pEvent);
642    }
643    
644    
645    void ChannelStrip::midiActivityLedOn (void)
646    {
647            m_ui.MidiActivityLabel->setPixmap(*g_pMidiActivityLedOn);
648            m_pMidiActivityTimer->start(100);
649    }
650    
651    
652    void ChannelStrip::midiActivityLedOff (void)
653    {
654            m_ui.MidiActivityLabel->setPixmap(*g_pMidiActivityLedOff);
655  }  }
656    
657    
# Line 431  void ChannelStrip::resetErrorCount (void Line 661  void ChannelStrip::resetErrorCount (void
661          m_iErrorCount = 0;          m_iErrorCount = 0;
662  }  }
663    
664    
665    // Channel strip activation/selection.
666    void ChannelStrip::setSelected ( bool bSelected )
667    {
668            if (bSelected) {
669                    if (g_pSelectedStrip == this)
670                            return;
671                    if (g_pSelectedStrip)
672                            g_pSelectedStrip->setSelected(false);
673                    g_pSelectedStrip = this;
674            } else {
675                    if (g_pSelectedStrip == this)
676                            g_pSelectedStrip = nullptr;
677            }
678    
679            QPalette pal;
680            if (bSelected) {
681                    const QColor& color = pal.midlight().color();
682                    pal.setColor(QPalette::Background, color.darker(150));
683                    pal.setColor(QPalette::Foreground, color.lighter(150));
684            }
685    
686            QWidget *pParentWidget = QWidget::parentWidget();
687            if (pParentWidget)
688                    pParentWidget->setPalette(pal);
689    }
690    
691    
692    bool ChannelStrip::isSelected (void) const
693    {
694            return (this == g_pSelectedStrip);
695    }
696    
697    
698  } // namespace QSampler  } // namespace QSampler
699    
700    
701    // end of qsamplerChannelStrip.cpp

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

  ViewVC Help
Powered by ViewVC