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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3555 - (hide annotations) (download)
Tue Aug 13 10:19:32 2019 UTC (5 weeks, 2 days ago) by capela
File size: 17839 byte(s)
- In late compliance to C++11, all NULL constants replaced for nullptr.
1 capela 1464 // qsamplerChannelStrip.cpp
2     //
3     /****************************************************************************
4 capela 3518 Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5 schoenebeck 2569 Copyright (C) 2007, 2008, 2014 Christian Schoenebeck
6 capela 1464
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 capela 1499 #include "qsamplerAbout.h"
24 schoenebeck 1461 #include "qsamplerChannelStrip.h"
25    
26     #include "qsamplerMainForm.h"
27    
28 schoenebeck 1667 #include "qsamplerChannelFxForm.h"
29    
30     #include <QMessageBox>
31 capela 1499 #include <QDragEnterEvent>
32 capela 2108 #include <QFileInfo>
33 capela 2036 #include <QTimer>
34 schoenebeck 1461 #include <QUrl>
35 schoenebeck 2569 #include <QMenu>
36 schoenebeck 1461
37 capela 3520 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
38 capela 2387 #include <QMimeData>
39     #endif
40 schoenebeck 1691
41 schoenebeck 1461 // Channel status/usage usage limit control.
42     #define QSAMPLER_ERROR_LIMIT 3
43    
44 capela 1510 // 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 capela 1514
58     namespace QSampler {
59    
60 capela 1558 //-------------------------------------------------------------------------
61     // QSampler::ChannelStrip -- Channel strip form implementation.
62     //
63    
64 capela 2036 // MIDI activity pixmap common resources.
65     int ChannelStrip::g_iMidiActivityRefCount = 0;
66 capela 3555 QPixmap *ChannelStrip::g_pMidiActivityLedOn = nullptr;
67     QPixmap *ChannelStrip::g_pMidiActivityLedOff = nullptr;
68 capela 2036
69 capela 1514 // Channel strip activation/selection.
70 capela 3555 ChannelStrip *ChannelStrip::g_pSelectedStrip = nullptr;
71 capela 1514
72 capela 1509 ChannelStrip::ChannelStrip ( QWidget* pParent, Qt::WindowFlags wflags )
73     : QWidget(pParent, wflags)
74     {
75 capela 1510 m_ui.setupUi(this);
76 schoenebeck 1461
77 capela 1510 // Initialize locals.
78 capela 3555 m_pChannel = nullptr;
79 capela 1510 m_iDirtyChange = 0;
80     m_iErrorCount = 0;
81 capela 3555 m_instrumentListPopupMenu = nullptr;
82 schoenebeck 1461
83 capela 2036 if (++g_iMidiActivityRefCount == 1) {
84 capela 2074 g_pMidiActivityLedOn = new QPixmap(":/images/ledon1.png");
85     g_pMidiActivityLedOff = new QPixmap(":/images/ledoff1.png");
86 capela 2036 }
87    
88     m_ui.MidiActivityLabel->setPixmap(*g_pMidiActivityLedOff);
89    
90     #ifndef CONFIG_EVENT_CHANNEL_MIDI
91     m_ui.MidiActivityLabel->setToolTip("MIDI activity (disabled)");
92     #endif
93    
94     m_pMidiActivityTimer = new QTimer(this);
95     m_pMidiActivityTimer->setSingleShot(true);
96    
97     QObject::connect(m_pMidiActivityTimer,
98     SIGNAL(timeout()),
99     SLOT(midiActivityLedOff())
100     );
101    
102 capela 1510 // Try to restore normal window positioning.
103     adjustSize();
104 capela 1466
105 capela 1509 QObject::connect(m_ui.ChannelSetupPushButton,
106 capela 1466 SIGNAL(clicked()),
107     SLOT(channelSetup()));
108 capela 1509 QObject::connect(m_ui.ChannelMutePushButton,
109 capela 1466 SIGNAL(toggled(bool)),
110     SLOT(channelMute(bool)));
111 capela 1509 QObject::connect(m_ui.ChannelSoloPushButton,
112 capela 1466 SIGNAL(toggled(bool)),
113     SLOT(channelSolo(bool)));
114 capela 2978 QObject::connect(m_ui.ChannelVolumeSlider,
115 capela 1466 SIGNAL(valueChanged(int)),
116     SLOT(volumeChanged(int)));
117 capela 2978 QObject::connect(m_ui.ChannelVolumeSpinBox,
118 capela 1466 SIGNAL(valueChanged(int)),
119     SLOT(volumeChanged(int)));
120 capela 1509 QObject::connect(m_ui.ChannelEditPushButton,
121 capela 1466 SIGNAL(clicked()),
122     SLOT(channelEdit()));
123 capela 2978 QObject::connect(m_ui.ChannelFxPushButton,
124 schoenebeck 1667 SIGNAL(clicked()),
125     SLOT(channelFxEdit()));
126 capela 1515
127     setSelected(false);
128 schoenebeck 1461 }
129    
130 capela 1513
131     ChannelStrip::~ChannelStrip (void)
132     {
133 capela 1515 setSelected(false);
134    
135 capela 1510 // Destroy existing channel descriptor.
136     if (m_pChannel)
137     delete m_pChannel;
138 capela 3555 m_pChannel = nullptr;
139 capela 2036
140     if (--g_iMidiActivityRefCount == 0) {
141     if (g_pMidiActivityLedOn)
142     delete g_pMidiActivityLedOn;
143 capela 3555 g_pMidiActivityLedOn = nullptr;
144 capela 2036 if (g_pMidiActivityLedOff)
145     delete g_pMidiActivityLedOff;
146 capela 3555 g_pMidiActivityLedOff = nullptr;
147 capela 2036 }
148 schoenebeck 1461 }
149    
150    
151 capela 1499 // Window drag-n-drop event handlers.
152     void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
153 schoenebeck 1461 {
154 capela 3555 if (m_pChannel == nullptr)
155 capela 1499 return;
156    
157     bool bAccept = false;
158    
159 capela 3555 if (pDragEnterEvent->source() == nullptr) {
160 capela 1499 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 capela 2108 // bAccept = Channel::isDlsInstrumentFile(sFilename);
167     bAccept = QFileInfo(sFilename).exists();
168 capela 1499 break;
169 schoenebeck 1461 }
170     }
171     }
172     }
173    
174 capela 1499 if (bAccept)
175     pDragEnterEvent->accept();
176     else
177     pDragEnterEvent->ignore();
178 schoenebeck 1461 }
179    
180    
181     void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
182     {
183 capela 3555 if (m_pChannel == nullptr)
184 capela 1499 return;
185 schoenebeck 1461
186 capela 1499 if (pDropEvent->source())
187     return;
188    
189     const QMimeData *pMimeData = pDropEvent->mimeData();
190     if (pMimeData && pMimeData->hasUrls()) {
191     QStringList files;
192     QListIterator<QUrl> iter(pMimeData->urls());
193     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 schoenebeck 1461 }
204     }
205    
206    
207     // Channel strip setup formal initializer.
208 capela 1558 void ChannelStrip::setup ( Channel *pChannel )
209 schoenebeck 1461 {
210 capela 1510 // Destroy any previous channel descriptor;
211     // (remember that once setup we own it!)
212     if (m_pChannel)
213     delete m_pChannel;
214 schoenebeck 1461
215 capela 1510 // Set the new one...
216     m_pChannel = pChannel;
217 schoenebeck 1461
218 capela 1510 // Stabilize this around.
219     updateChannelInfo();
220 schoenebeck 1461
221     // We'll accept drops from now on...
222     if (m_pChannel)
223     setAcceptDrops(true);
224     }
225    
226 capela 1513
227 schoenebeck 1461 // Channel secriptor accessor.
228 capela 1558 Channel *ChannelStrip::channel (void) const
229 schoenebeck 1461 {
230 capela 1510 return m_pChannel;
231 schoenebeck 1461 }
232    
233    
234     // Messages view font accessors.
235 capela 1509 QFont ChannelStrip::displayFont (void) const
236 schoenebeck 1461 {
237 capela 1510 return m_ui.EngineNameTextLabel->font();
238 schoenebeck 1461 }
239    
240 capela 2978
241 schoenebeck 1461 void ChannelStrip::setDisplayFont ( const QFont & font )
242     {
243 capela 1510 m_ui.EngineNameTextLabel->setFont(font);
244     m_ui.MidiPortChannelTextLabel->setFont(font);
245 schoenebeck 2569 m_ui.InstrumentNamePushButton->setFont(font);
246 capela 1510 m_ui.InstrumentStatusTextLabel->setFont(font);
247 schoenebeck 1461 }
248    
249    
250     // Channel display background effect.
251     void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
252     {
253 capela 1499 QPalette pal;
254 capela 1507 pal.setColor(QPalette::Foreground, Qt::yellow);
255 schoenebeck 2569 pal.setColor(QPalette::ButtonText, Qt::yellow);
256 capela 1509 m_ui.EngineNameTextLabel->setPalette(pal);
257     m_ui.MidiPortChannelTextLabel->setPalette(pal);
258 capela 1499 pal.setColor(QPalette::Foreground, Qt::green);
259 capela 2570 pal.setColor(QPalette::ButtonText, Qt::green);
260 capela 1499 if (bDisplayEffect) {
261 capela 2074 QPixmap pm(":/images/displaybg1.png");
262 capela 1499 pal.setBrush(QPalette::Background, QBrush(pm));
263     } else {
264     pal.setColor(QPalette::Background, Qt::black);
265     }
266 capela 1509 m_ui.ChannelInfoFrame->setPalette(pal);
267 schoenebeck 2569 m_ui.InstrumentNamePushButton->setPalette(pal);
268 capela 1509 m_ui.StreamVoiceCountTextLabel->setPalette(pal);
269 schoenebeck 1461 }
270    
271    
272     // Maximum volume slider accessors.
273     void ChannelStrip::setMaxVolume ( int iMaxVolume )
274     {
275 capela 1510 m_iDirtyChange++;
276 capela 2978 m_ui.ChannelVolumeSlider->setRange(0, iMaxVolume);
277     m_ui.ChannelVolumeSpinBox->setRange(0, iMaxVolume);
278 capela 1510 m_iDirtyChange--;
279 schoenebeck 1461 }
280    
281    
282     // Channel setup dialog slot.
283     bool ChannelStrip::channelSetup (void)
284     {
285 capela 3555 if (m_pChannel == nullptr)
286 schoenebeck 1461 return false;
287    
288     // Invoke the channel setup dialog.
289 capela 2978 const bool bResult = m_pChannel->channelSetup(this);
290 schoenebeck 1461 // Notify that this channel has changed.
291     if (bResult)
292     emit channelChanged(this);
293    
294     return bResult;
295     }
296    
297    
298     // Channel mute slot.
299     bool ChannelStrip::channelMute ( bool bMute )
300     {
301 capela 3555 if (m_pChannel == nullptr)
302 schoenebeck 1461 return false;
303    
304     // Invoke the channel mute method.
305 capela 2978 const bool bResult = m_pChannel->setChannelMute(bMute);
306 schoenebeck 1461 // Notify that this channel has changed.
307     if (bResult)
308     emit channelChanged(this);
309    
310     return bResult;
311     }
312    
313    
314     // Channel solo slot.
315     bool ChannelStrip::channelSolo ( bool bSolo )
316     {
317 capela 3555 if (m_pChannel == nullptr)
318 schoenebeck 1461 return false;
319    
320     // Invoke the channel solo method.
321 capela 2978 const bool bResult = m_pChannel->setChannelSolo(bSolo);
322 schoenebeck 1461 // Notify that this channel has changed.
323     if (bResult)
324     emit channelChanged(this);
325    
326     return bResult;
327     }
328    
329    
330     // Channel edit slot.
331     void ChannelStrip::channelEdit (void)
332     {
333 capela 3555 if (m_pChannel == nullptr)
334 schoenebeck 1461 return;
335    
336     m_pChannel->editChannel();
337     }
338    
339 schoenebeck 1667 bool ChannelStrip::channelFxEdit (void)
340     {
341     MainForm *pMainForm = MainForm::getInstance();
342     if (!pMainForm || !channel())
343     return false;
344 schoenebeck 1461
345 schoenebeck 1667 pMainForm->appendMessages(QObject::tr("channel fx sends..."));
346    
347     bool bResult = false;
348    
349     #if CONFIG_FXSEND
350     ChannelFxForm *pChannelFxForm =
351 schoenebeck 1668 new ChannelFxForm(channel(), parentWidget());
352 schoenebeck 1667 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 capela 2978
368 schoenebeck 1461 // Channel reset slot.
369     bool ChannelStrip::channelReset (void)
370     {
371 capela 3555 if (m_pChannel == nullptr)
372 schoenebeck 1461 return false;
373    
374     // Invoke the channel reset method.
375 capela 2978 const bool bResult = m_pChannel->channelReset();
376 schoenebeck 1461 // Notify that this channel has changed.
377     if (bResult)
378     emit channelChanged(this);
379    
380     return bResult;
381     }
382    
383    
384     // Update the channel instrument name.
385     bool ChannelStrip::updateInstrumentName ( bool bForce )
386     {
387 capela 3555 if (m_pChannel == nullptr)
388 schoenebeck 1461 return false;
389    
390     // Do we refresh the actual name?
391     if (bForce)
392     m_pChannel->updateInstrumentName();
393    
394     // Instrument name...
395     if (m_pChannel->instrumentName().isEmpty()) {
396 capela 1513 if (m_pChannel->instrumentStatus() >= 0) {
397 schoenebeck 2569 m_ui.InstrumentNamePushButton->setText(
398 capela 1558 ' ' + Channel::loadingInstrument());
399 capela 1513 } else {
400 schoenebeck 2569 m_ui.InstrumentNamePushButton->setText(
401 capela 1558 ' ' + Channel::noInstrumentName());
402 capela 1513 }
403     } else {
404 schoenebeck 2569 m_ui.InstrumentNamePushButton->setText(
405 capela 1513 ' ' + m_pChannel->instrumentName());
406     }
407 schoenebeck 2569
408     bool bShowInstrumentPopup = false;
409 schoenebeck 1461
410 schoenebeck 2569 // Instrument list popup (for fast switching among sounds of the same file)
411     if (!m_pChannel->instrumentFile().isEmpty()) {
412 capela 2570 const QStringList instruments
413     = Channel::getInstrumentList(m_pChannel->instrumentFile(), true);
414 schoenebeck 2569 if (!instruments.isEmpty()) {
415     bShowInstrumentPopup = true;
416     if (!m_instrumentListPopupMenu) {
417 capela 2570 m_instrumentListPopupMenu
418     = new QMenu(m_ui.InstrumentNamePushButton);
419 schoenebeck 2569 m_instrumentListPopupMenu->setTitle(tr("Instruments"));
420 capela 2570 // for cosmetical reasons, should have at least
421     // the width of the instrument name label...
422     m_instrumentListPopupMenu->setMinimumWidth(120);
423 schoenebeck 2569 m_ui.InstrumentNamePushButton->setMenu(m_instrumentListPopupMenu);
424 capela 2570 QObject::connect(m_instrumentListPopupMenu,
425     SIGNAL(triggered(QAction*)),
426     SLOT(instrumentListPopupItemClicked(QAction *)));
427     } else {
428     m_instrumentListPopupMenu->clear();
429     }
430     QAction *action;
431 schoenebeck 2569 for (int i = 0; i < instruments.size(); ++i) {
432 capela 2570 action = m_instrumentListPopupMenu->addAction(instruments.at(i));
433 schoenebeck 2569 action->setData(i);
434 capela 2570 action->setCheckable(true);
435     action->setChecked(i == m_pChannel->instrumentNr());
436 schoenebeck 2569 }
437     }
438     }
439    
440     if (!bShowInstrumentPopup && m_instrumentListPopupMenu) {
441     delete m_instrumentListPopupMenu;
442 capela 3555 m_instrumentListPopupMenu = nullptr;
443 schoenebeck 2569 }
444    
445 schoenebeck 1461 return true;
446     }
447    
448 capela 2978
449 capela 2570 void ChannelStrip::instrumentListPopupItemClicked ( QAction *action )
450 schoenebeck 2569 {
451     if (!action) return;
452 schoenebeck 1461
453 schoenebeck 2569 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 capela 2978
461 schoenebeck 1461 // Do the dirty volume change.
462     bool ChannelStrip::updateChannelVolume (void)
463     {
464 capela 3555 if (m_pChannel == nullptr)
465 capela 1510 return false;
466 schoenebeck 1461
467 capela 1510 // Convert...
468     int iVolume = ::lroundf(100.0f * m_pChannel->volume());
469     // And clip...
470     if (iVolume < 0)
471     iVolume = 0;
472 schoenebeck 1461
473 capela 1510 // Flag it here, to avoid infinite recursion.
474     m_iDirtyChange++;
475 capela 2978 m_ui.ChannelVolumeSlider->setValue(iVolume);
476     m_ui.ChannelVolumeSpinBox->setValue(iVolume);
477 capela 1510 m_iDirtyChange--;
478 schoenebeck 1461
479 capela 1510 return true;
480 schoenebeck 1461 }
481    
482    
483     // Update whole channel info state.
484     bool ChannelStrip::updateChannelInfo (void)
485     {
486 capela 3555 if (m_pChannel == nullptr)
487 capela 1510 return false;
488 schoenebeck 1461
489     // Check for error limit/recycle...
490     if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
491     return true;
492    
493 capela 1510 // Update strip caption.
494 capela 2978 const QString& sText = m_pChannel->channelName();
495 capela 1510 setWindowTitle(sText);
496 capela 1513 m_ui.ChannelSetupPushButton->setText('&' + sText);
497 schoenebeck 1461
498 capela 1510 // Check if we're up and connected.
499 capela 2978 MainForm *pMainForm = MainForm::getInstance();
500 capela 3555 if (pMainForm->client() == nullptr)
501 schoenebeck 1461 return false;
502    
503 capela 1510 // Read actual channel information.
504     m_pChannel->updateChannelInfo();
505 schoenebeck 1461
506 capela 1510 // Engine name...
507 capela 1513 if (m_pChannel->engineName().isEmpty()) {
508     m_ui.EngineNameTextLabel->setText(
509 capela 1558 ' ' + Channel::noEngineName());
510 capela 1513 } else {
511     m_ui.EngineNameTextLabel->setText(
512     ' ' + m_pChannel->engineName());
513     }
514 schoenebeck 1461
515     // Instrument name...
516     updateInstrumentName(false);
517    
518 capela 1510 // MIDI Port/Channel...
519 schoenebeck 1461 QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";
520     if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
521     sMidiPortChannel += tr("All");
522     else
523     sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);
524 capela 1509 m_ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
525 schoenebeck 1461
526 capela 1499 // Common palette...
527     QPalette pal;
528     const QColor& rgbFore = pal.color(QPalette::Foreground);
529    
530 capela 1510 // Instrument status...
531 capela 2570 const int iInstrumentStatus = m_pChannel->instrumentStatus();
532 capela 1510 if (iInstrumentStatus < 0) {
533 capela 1499 pal.setColor(QPalette::Foreground, Qt::red);
534 capela 1509 m_ui.InstrumentStatusTextLabel->setPalette(pal);
535 capela 1513 m_ui.InstrumentStatusTextLabel->setText(
536     tr("ERR%1").arg(iInstrumentStatus));
537 capela 1510 m_iErrorCount++;
538     return false;
539     }
540 capela 2570
541 capela 1510 // All seems normal...
542 capela 1499 pal.setColor(QPalette::Foreground,
543     iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
544 capela 1510 m_ui.InstrumentStatusTextLabel->setPalette(pal);
545 capela 1513 m_ui.InstrumentStatusTextLabel->setText(
546     QString::number(iInstrumentStatus) + '%');
547 capela 1510 m_iErrorCount = 0;
548 schoenebeck 1461
549     #ifdef CONFIG_MUTE_SOLO
550 capela 1510 // Mute/Solo button state coloring...
551 capela 2978 const bool bMute = m_pChannel->channelMute();
552 capela 1499 const QColor& rgbButton = pal.color(QPalette::Button);
553 capela 2068 const QColor& rgbButtonText = pal.color(QPalette::ButtonText);
554 capela 1499 pal.setColor(QPalette::Foreground, rgbFore);
555     pal.setColor(QPalette::Button, bMute ? Qt::yellow : rgbButton);
556 capela 2068 pal.setColor(QPalette::ButtonText, bMute ? Qt::darkYellow : rgbButtonText);
557 capela 1509 m_ui.ChannelMutePushButton->setPalette(pal);
558     m_ui.ChannelMutePushButton->setDown(bMute);
559 capela 2978 const bool bSolo = m_pChannel->channelSolo();
560 capela 1499 pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);
561 capela 2068 pal.setColor(QPalette::ButtonText, bSolo ? Qt::darkCyan : rgbButtonText);
562 capela 1509 m_ui.ChannelSoloPushButton->setPalette(pal);
563     m_ui.ChannelSoloPushButton->setDown(bSolo);
564 schoenebeck 1461 #else
565 capela 1509 m_ui.ChannelMutePushButton->setEnabled(false);
566     m_ui.ChannelSoloPushButton->setEnabled(false);
567 schoenebeck 1461 #endif
568    
569 capela 1510 // And update the both GUI volume elements;
570     // return success if, and only if, intrument is fully loaded...
571     return updateChannelVolume() && (iInstrumentStatus == 100);
572 schoenebeck 1461 }
573    
574    
575     // Update whole channel usage state.
576     bool ChannelStrip::updateChannelUsage (void)
577     {
578 capela 3555 if (m_pChannel == nullptr)
579 capela 1510 return false;
580 schoenebeck 1461
581     MainForm *pMainForm = MainForm::getInstance();
582 capela 3555 if (pMainForm->client() == nullptr)
583 schoenebeck 1461 return false;
584    
585     // This only makes sense on fully loaded channels...
586     if (m_pChannel->instrumentStatus() < 100)
587 capela 1510 return false;
588 schoenebeck 1461
589 capela 1510 // Get current channel voice count.
590 capela 2978 const int iVoiceCount = ::lscp_get_channel_voice_count(
591 capela 1513 pMainForm->client(), m_pChannel->channelID());
592 capela 2978 // Get current stream count.
593     const int iStreamCount = ::lscp_get_channel_stream_count(
594 capela 1513 pMainForm->client(), m_pChannel->channelID());
595 capela 1510 // Get current channel buffer fill usage.
596     // As benno has suggested this is the percentage usage
597     // of the least filled buffer stream...
598 capela 2978 const int iStreamUsage = ::lscp_get_channel_stream_usage(
599 capela 3518 pMainForm->client(), m_pChannel->channelID());
600 schoenebeck 1461
601 capela 1510 // Update the GUI elements...
602     m_ui.StreamUsageProgressBar->setValue(iStreamUsage);
603 capela 1513 m_ui.StreamVoiceCountTextLabel->setText(
604     QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
605 schoenebeck 1461
606 capela 1510 // We're clean.
607     return true;
608 schoenebeck 1461 }
609    
610    
611     // Volume change slot.
612     void ChannelStrip::volumeChanged ( int iVolume )
613     {
614 capela 3555 if (m_pChannel == nullptr)
615 capela 1510 return;
616 schoenebeck 1461
617 capela 1510 // Avoid recursion.
618     if (m_iDirtyChange > 0)
619     return;
620 schoenebeck 1461
621 capela 1510 // Convert and clip.
622     float fVolume = (float) iVolume / 100.0f;
623     if (fVolume < 0.001f)
624     fVolume = 0.0f;
625 schoenebeck 1461
626 capela 1510 // Update the GUI elements.
627     if (m_pChannel->setVolume(fVolume)) {
628     updateChannelVolume();
629     emit channelChanged(this);
630     }
631 schoenebeck 1461 }
632    
633    
634     // Context menu event handler.
635     void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
636     {
637 capela 3555 if (m_pChannel == nullptr)
638 capela 1510 return;
639 schoenebeck 1461
640 capela 1510 // We'll just show up the main form's edit menu (thru qsamplerChannel).
641     m_pChannel->contextMenuEvent(pEvent);
642 schoenebeck 1461 }
643    
644 capela 2036
645     void ChannelStrip::midiActivityLedOn (void)
646     {
647     m_ui.MidiActivityLabel->setPixmap(*g_pMidiActivityLedOn);
648 capela 2038 m_pMidiActivityTimer->start(100);
649 schoenebeck 1691 }
650 schoenebeck 1461
651 capela 2036
652     void ChannelStrip::midiActivityLedOff (void)
653     {
654     m_ui.MidiActivityLabel->setPixmap(*g_pMidiActivityLedOff);
655     }
656    
657    
658 schoenebeck 1461 // Error count hackish accessors.
659     void ChannelStrip::resetErrorCount (void)
660     {
661     m_iErrorCount = 0;
662     }
663    
664 capela 1514
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 capela 3555 g_pSelectedStrip = nullptr;
677 capela 1514 }
678    
679     QPalette pal;
680     if (bSelected) {
681     const QColor& color = pal.midlight().color();
682 capela 3518 pal.setColor(QPalette::Background, color.darker(150));
683     pal.setColor(QPalette::Foreground, color.lighter(150));
684 capela 1514 }
685 capela 2979
686     QWidget *pParentWidget = QWidget::parentWidget();
687     if (pParentWidget)
688     pParentWidget->setPalette(pal);
689 capela 1514 }
690    
691    
692     bool ChannelStrip::isSelected (void) const
693     {
694     return (this == g_pSelectedStrip);
695     }
696    
697    
698 schoenebeck 1461 } // namespace QSampler
699 capela 1464
700    
701     // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC