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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1510 - (hide annotations) (download)
Thu Nov 22 14:17:24 2007 UTC (16 years, 5 months ago) by capela
File size: 12326 byte(s)
- Qt4 migration: code cleanup, personal standards beautification :)

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

  ViewVC Help
Powered by ViewVC