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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1499 - (hide annotations) (download)
Tue Nov 20 16:48:04 2007 UTC (16 years, 4 months ago) by capela
File size: 12537 byte(s)
* Qt4 migration: one first step forward to kiss Qt3Support goodbye.

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

  ViewVC Help
Powered by ViewVC