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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1514 - (hide annotations) (download)
Fri Nov 23 10:51:37 2007 UTC (16 years, 5 months ago) by capela
File size: 13150 byte(s)
* The current selected/activated channel-strip is now visually
  evident while in the application workspace (highlighting).

1 capela 1464 // qsamplerChannelStrip.cpp
2     //
3     /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, 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 capela 1499 #include "qsamplerAbout.h"
24 schoenebeck 1461 #include "qsamplerChannelStrip.h"
25    
26     #include "qsamplerMainForm.h"
27    
28 capela 1499 #include <QDragEnterEvent>
29 schoenebeck 1461 #include <QUrl>
30    
31     // Channel status/usage usage limit control.
32     #define QSAMPLER_ERROR_LIMIT 3
33    
34 capela 1510 // Needed for lroundf()
35     #include <math.h>
36    
37     #ifndef CONFIG_ROUND
38     static inline long lroundf ( float x )
39     {
40     if (x >= 0.0f)
41     return long(x + 0.5f);
42     else
43     return long(x - 0.5f);
44     }
45     #endif
46    
47 capela 1514
48     namespace QSampler {
49    
50     // Channel strip activation/selection.
51     ChannelStrip *ChannelStrip::g_pSelectedStrip = NULL;
52    
53    
54 capela 1509 ChannelStrip::ChannelStrip ( QWidget* pParent, Qt::WindowFlags wflags )
55     : QWidget(pParent, wflags)
56     {
57 capela 1510 m_ui.setupUi(this);
58 schoenebeck 1461
59 capela 1510 // Initialize locals.
60     m_pChannel = NULL;
61     m_iDirtyChange = 0;
62     m_iErrorCount = 0;
63 schoenebeck 1461
64 capela 1510 // Try to restore normal window positioning.
65     adjustSize();
66 capela 1514 setSelected(false);
67 capela 1466
68 capela 1509 QObject::connect(m_ui.ChannelSetupPushButton,
69 capela 1466 SIGNAL(clicked()),
70     SLOT(channelSetup()));
71 capela 1509 QObject::connect(m_ui.ChannelMutePushButton,
72 capela 1466 SIGNAL(toggled(bool)),
73     SLOT(channelMute(bool)));
74 capela 1509 QObject::connect(m_ui.ChannelSoloPushButton,
75 capela 1466 SIGNAL(toggled(bool)),
76     SLOT(channelSolo(bool)));
77 capela 1509 QObject::connect(m_ui.VolumeSlider,
78 capela 1466 SIGNAL(valueChanged(int)),
79     SLOT(volumeChanged(int)));
80 capela 1509 QObject::connect(m_ui.VolumeSpinBox,
81 capela 1466 SIGNAL(valueChanged(int)),
82     SLOT(volumeChanged(int)));
83 capela 1509 QObject::connect(m_ui.ChannelEditPushButton,
84 capela 1466 SIGNAL(clicked()),
85     SLOT(channelEdit()));
86 schoenebeck 1461 }
87    
88 capela 1513
89     ChannelStrip::~ChannelStrip (void)
90     {
91 capela 1510 // Destroy existing channel descriptor.
92     if (m_pChannel)
93     delete m_pChannel;
94     m_pChannel = NULL;
95 schoenebeck 1461 }
96    
97    
98 capela 1499 // Window drag-n-drop event handlers.
99     void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
100 schoenebeck 1461 {
101     if (m_pChannel == NULL)
102 capela 1499 return;
103    
104     bool bAccept = false;
105    
106     if (pDragEnterEvent->source() == NULL) {
107     const QMimeData *pMimeData = pDragEnterEvent->mimeData();
108     if (pMimeData && pMimeData->hasUrls()) {
109     QListIterator<QUrl> iter(pMimeData->urls());
110     while (iter.hasNext()) {
111     const QString& sFilename = iter.next().toLocalFile();
112     if (!sFilename.isEmpty()) {
113     bAccept = qsamplerChannel::isInstrumentFile(sFilename);
114     break;
115 schoenebeck 1461 }
116     }
117     }
118     }
119    
120 capela 1499 if (bAccept)
121     pDragEnterEvent->accept();
122     else
123     pDragEnterEvent->ignore();
124 schoenebeck 1461 }
125    
126    
127     void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
128     {
129 capela 1499 if (m_pChannel == NULL)
130     return;
131 schoenebeck 1461
132 capela 1499 if (pDropEvent->source())
133     return;
134    
135     const QMimeData *pMimeData = pDropEvent->mimeData();
136     if (pMimeData && pMimeData->hasUrls()) {
137     QStringList files;
138     QListIterator<QUrl> iter(pMimeData->urls());
139     while (iter.hasNext()) {
140     const QString& sFilename = iter.next().toLocalFile();
141     if (!sFilename.isEmpty()) {
142     // Go and set the dropped instrument filename...
143     m_pChannel->setInstrument(sFilename, 0);
144     // Open up the channel dialog.
145     channelSetup();
146     break;
147     }
148     }
149 schoenebeck 1461 }
150     }
151    
152    
153     // Channel strip setup formal initializer.
154     void ChannelStrip::setup ( qsamplerChannel *pChannel )
155     {
156 capela 1510 // Destroy any previous channel descriptor;
157     // (remember that once setup we own it!)
158     if (m_pChannel)
159     delete m_pChannel;
160 schoenebeck 1461
161 capela 1510 // Set the new one...
162     m_pChannel = pChannel;
163 schoenebeck 1461
164 capela 1510 // Stabilize this around.
165     updateChannelInfo();
166 schoenebeck 1461
167     // We'll accept drops from now on...
168     if (m_pChannel)
169     setAcceptDrops(true);
170     }
171    
172 capela 1513
173 schoenebeck 1461 // Channel secriptor accessor.
174 capela 1509 qsamplerChannel *ChannelStrip::channel (void) const
175 schoenebeck 1461 {
176 capela 1510 return m_pChannel;
177 schoenebeck 1461 }
178    
179    
180     // Messages view font accessors.
181 capela 1509 QFont ChannelStrip::displayFont (void) const
182 schoenebeck 1461 {
183 capela 1510 return m_ui.EngineNameTextLabel->font();
184 schoenebeck 1461 }
185    
186     void ChannelStrip::setDisplayFont ( const QFont & font )
187     {
188 capela 1510 m_ui.EngineNameTextLabel->setFont(font);
189     m_ui.MidiPortChannelTextLabel->setFont(font);
190     m_ui.InstrumentNameTextLabel->setFont(font);
191     m_ui.InstrumentStatusTextLabel->setFont(font);
192 schoenebeck 1461 }
193    
194    
195     // Channel display background effect.
196     void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
197     {
198 capela 1499 QPalette pal;
199 capela 1507 pal.setColor(QPalette::Foreground, Qt::yellow);
200 capela 1509 m_ui.EngineNameTextLabel->setPalette(pal);
201     m_ui.MidiPortChannelTextLabel->setPalette(pal);
202 capela 1499 pal.setColor(QPalette::Foreground, Qt::green);
203     if (bDisplayEffect) {
204     QPixmap pm(":/icons/displaybg1.png");
205     pal.setBrush(QPalette::Background, QBrush(pm));
206     } else {
207     pal.setColor(QPalette::Background, Qt::black);
208     }
209 capela 1509 m_ui.ChannelInfoFrame->setPalette(pal);
210     m_ui.StreamVoiceCountTextLabel->setPalette(pal);
211 schoenebeck 1461 }
212    
213    
214     // Maximum volume slider accessors.
215     void ChannelStrip::setMaxVolume ( int iMaxVolume )
216     {
217 capela 1510 m_iDirtyChange++;
218     m_ui.VolumeSlider->setRange(0, iMaxVolume);
219     m_ui.VolumeSpinBox->setRange(0, iMaxVolume);
220     m_iDirtyChange--;
221 schoenebeck 1461 }
222    
223    
224     // Channel setup dialog slot.
225     bool ChannelStrip::channelSetup (void)
226     {
227     if (m_pChannel == NULL)
228     return false;
229    
230     // Invoke the channel setup dialog.
231     bool bResult = m_pChannel->channelSetup(this);
232     // Notify that this channel has changed.
233     if (bResult)
234     emit channelChanged(this);
235    
236     return bResult;
237     }
238    
239    
240     // Channel mute slot.
241     bool ChannelStrip::channelMute ( bool bMute )
242     {
243     if (m_pChannel == NULL)
244     return false;
245    
246     // Invoke the channel mute method.
247     bool bResult = m_pChannel->setChannelMute(bMute);
248     // Notify that this channel has changed.
249     if (bResult)
250     emit channelChanged(this);
251    
252     return bResult;
253     }
254    
255    
256     // Channel solo slot.
257     bool ChannelStrip::channelSolo ( bool bSolo )
258     {
259     if (m_pChannel == NULL)
260     return false;
261    
262     // Invoke the channel solo method.
263     bool bResult = m_pChannel->setChannelSolo(bSolo);
264     // Notify that this channel has changed.
265     if (bResult)
266     emit channelChanged(this);
267    
268     return bResult;
269     }
270    
271    
272     // Channel edit slot.
273     void ChannelStrip::channelEdit (void)
274     {
275     if (m_pChannel == NULL)
276     return;
277    
278     m_pChannel->editChannel();
279     }
280    
281    
282     // Channel reset slot.
283     bool ChannelStrip::channelReset (void)
284     {
285     if (m_pChannel == NULL)
286     return false;
287    
288     // Invoke the channel reset method.
289     bool bResult = m_pChannel->channelReset();
290     // Notify that this channel has changed.
291     if (bResult)
292     emit channelChanged(this);
293    
294     return bResult;
295     }
296    
297    
298     // Update the channel instrument name.
299     bool ChannelStrip::updateInstrumentName ( bool bForce )
300     {
301     if (m_pChannel == NULL)
302     return false;
303    
304     // Do we refresh the actual name?
305     if (bForce)
306     m_pChannel->updateInstrumentName();
307    
308     // Instrument name...
309     if (m_pChannel->instrumentName().isEmpty()) {
310 capela 1513 if (m_pChannel->instrumentStatus() >= 0) {
311     m_ui.InstrumentNameTextLabel->setText(
312     ' ' + qsamplerChannel::loadingInstrument());
313     } else {
314     m_ui.InstrumentNameTextLabel->setText(
315     ' ' + qsamplerChannel::noInstrumentName());
316     }
317     } else {
318     m_ui.InstrumentNameTextLabel->setText(
319     ' ' + m_pChannel->instrumentName());
320     }
321 schoenebeck 1461
322     return true;
323     }
324    
325    
326     // Do the dirty volume change.
327     bool ChannelStrip::updateChannelVolume (void)
328     {
329 capela 1510 if (m_pChannel == NULL)
330     return false;
331 schoenebeck 1461
332 capela 1510 // Convert...
333     int iVolume = ::lroundf(100.0f * m_pChannel->volume());
334     // And clip...
335     if (iVolume < 0)
336     iVolume = 0;
337 schoenebeck 1461
338 capela 1510 // Flag it here, to avoid infinite recursion.
339     m_iDirtyChange++;
340     m_ui.VolumeSlider->setValue(iVolume);
341     m_ui.VolumeSpinBox->setValue(iVolume);
342     m_iDirtyChange--;
343 schoenebeck 1461
344 capela 1510 return true;
345 schoenebeck 1461 }
346    
347    
348     // Update whole channel info state.
349     bool ChannelStrip::updateChannelInfo (void)
350     {
351 capela 1510 if (m_pChannel == NULL)
352     return false;
353 schoenebeck 1461
354     // Check for error limit/recycle...
355     if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
356     return true;
357    
358 capela 1510 // Update strip caption.
359     QString sText = m_pChannel->channelName();
360     setWindowTitle(sText);
361 capela 1513 m_ui.ChannelSetupPushButton->setText('&' + sText);
362 schoenebeck 1461
363 capela 1510 // Check if we're up and connected.
364 schoenebeck 1461 MainForm* pMainForm = MainForm::getInstance();
365     if (pMainForm->client() == NULL)
366     return false;
367    
368 capela 1510 // Read actual channel information.
369     m_pChannel->updateChannelInfo();
370 schoenebeck 1461
371 capela 1510 // Engine name...
372 capela 1513 if (m_pChannel->engineName().isEmpty()) {
373     m_ui.EngineNameTextLabel->setText(
374     ' ' + qsamplerChannel::noEngineName());
375     } else {
376     m_ui.EngineNameTextLabel->setText(
377     ' ' + m_pChannel->engineName());
378     }
379 schoenebeck 1461
380     // Instrument name...
381     updateInstrumentName(false);
382    
383 capela 1510 // MIDI Port/Channel...
384 schoenebeck 1461 QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";
385     if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
386     sMidiPortChannel += tr("All");
387     else
388     sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);
389 capela 1509 m_ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
390 schoenebeck 1461
391 capela 1499 // Common palette...
392     QPalette pal;
393     const QColor& rgbFore = pal.color(QPalette::Foreground);
394    
395 capela 1510 // Instrument status...
396     int iInstrumentStatus = m_pChannel->instrumentStatus();
397     if (iInstrumentStatus < 0) {
398 capela 1499 pal.setColor(QPalette::Foreground, Qt::red);
399 capela 1509 m_ui.InstrumentStatusTextLabel->setPalette(pal);
400 capela 1513 m_ui.InstrumentStatusTextLabel->setText(
401     tr("ERR%1").arg(iInstrumentStatus));
402 capela 1510 m_iErrorCount++;
403     return false;
404     }
405     // All seems normal...
406 capela 1499 pal.setColor(QPalette::Foreground,
407     iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
408 capela 1510 m_ui.InstrumentStatusTextLabel->setPalette(pal);
409 capela 1513 m_ui.InstrumentStatusTextLabel->setText(
410     QString::number(iInstrumentStatus) + '%');
411 capela 1510 m_iErrorCount = 0;
412 schoenebeck 1461
413     #ifdef CONFIG_MUTE_SOLO
414 capela 1510 // Mute/Solo button state coloring...
415     bool bMute = m_pChannel->channelMute();
416 capela 1499 const QColor& rgbButton = pal.color(QPalette::Button);
417     pal.setColor(QPalette::Foreground, rgbFore);
418     pal.setColor(QPalette::Button, bMute ? Qt::yellow : rgbButton);
419 capela 1509 m_ui.ChannelMutePushButton->setPalette(pal);
420     m_ui.ChannelMutePushButton->setDown(bMute);
421 capela 1510 bool bSolo = m_pChannel->channelSolo();
422 capela 1499 pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);
423 capela 1509 m_ui.ChannelSoloPushButton->setPalette(pal);
424     m_ui.ChannelSoloPushButton->setDown(bSolo);
425 schoenebeck 1461 #else
426 capela 1509 m_ui.ChannelMutePushButton->setEnabled(false);
427     m_ui.ChannelSoloPushButton->setEnabled(false);
428 schoenebeck 1461 #endif
429    
430 capela 1510 // And update the both GUI volume elements;
431     // return success if, and only if, intrument is fully loaded...
432     return updateChannelVolume() && (iInstrumentStatus == 100);
433 schoenebeck 1461 }
434    
435    
436     // Update whole channel usage state.
437     bool ChannelStrip::updateChannelUsage (void)
438     {
439 capela 1510 if (m_pChannel == NULL)
440     return false;
441 schoenebeck 1461
442     MainForm *pMainForm = MainForm::getInstance();
443     if (pMainForm->client() == NULL)
444     return false;
445    
446     // This only makes sense on fully loaded channels...
447     if (m_pChannel->instrumentStatus() < 100)
448 capela 1510 return false;
449 schoenebeck 1461
450 capela 1510 // Get current channel voice count.
451 capela 1513 int iVoiceCount = ::lscp_get_channel_voice_count(
452     pMainForm->client(), m_pChannel->channelID());
453 capela 1510 // Get current stream count.
454 capela 1513 int iStreamCount = ::lscp_get_channel_stream_count(
455     pMainForm->client(), m_pChannel->channelID());
456 capela 1510 // Get current channel buffer fill usage.
457     // As benno has suggested this is the percentage usage
458     // of the least filled buffer stream...
459 capela 1513 int iStreamUsage = ::lscp_get_channel_stream_usage(
460     pMainForm->client(), m_pChannel->channelID());;
461 schoenebeck 1461
462 capela 1510 // Update the GUI elements...
463     m_ui.StreamUsageProgressBar->setValue(iStreamUsage);
464 capela 1513 m_ui.StreamVoiceCountTextLabel->setText(
465     QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
466 schoenebeck 1461
467 capela 1510 // We're clean.
468     return true;
469 schoenebeck 1461 }
470    
471    
472     // Volume change slot.
473     void ChannelStrip::volumeChanged ( int iVolume )
474     {
475 capela 1510 if (m_pChannel == NULL)
476     return;
477 schoenebeck 1461
478 capela 1510 // Avoid recursion.
479     if (m_iDirtyChange > 0)
480     return;
481 schoenebeck 1461
482 capela 1510 // Convert and clip.
483     float fVolume = (float) iVolume / 100.0f;
484     if (fVolume < 0.001f)
485     fVolume = 0.0f;
486 schoenebeck 1461
487 capela 1510 // Update the GUI elements.
488     if (m_pChannel->setVolume(fVolume)) {
489     updateChannelVolume();
490     emit channelChanged(this);
491     }
492 schoenebeck 1461 }
493    
494    
495     // Context menu event handler.
496     void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
497     {
498 capela 1510 if (m_pChannel == NULL)
499     return;
500 schoenebeck 1461
501 capela 1510 // We'll just show up the main form's edit menu (thru qsamplerChannel).
502     m_pChannel->contextMenuEvent(pEvent);
503 schoenebeck 1461 }
504    
505    
506     // Error count hackish accessors.
507     void ChannelStrip::resetErrorCount (void)
508     {
509     m_iErrorCount = 0;
510     }
511    
512 capela 1514
513     // Channel strip activation/selection.
514     void ChannelStrip::setSelected ( bool bSelected )
515     {
516     if (bSelected) {
517     if (g_pSelectedStrip == this)
518     return;
519     if (g_pSelectedStrip)
520     g_pSelectedStrip->setSelected(false);
521     g_pSelectedStrip = this;
522     } else {
523     if (g_pSelectedStrip == this)
524     g_pSelectedStrip = NULL;
525     }
526    
527     QPalette pal;
528     if (bSelected) {
529     const QColor& color = pal.midlight().color();
530     pal.setColor(QPalette::Background, color.dark(150));
531     pal.setColor(QPalette::Foreground, color.light(150));
532     }
533     QWidget::setPalette(pal);
534     }
535    
536    
537     bool ChannelStrip::isSelected (void) const
538     {
539     return (this == g_pSelectedStrip);
540     }
541    
542    
543 schoenebeck 1461 } // namespace QSampler
544 capela 1464
545    
546     // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC