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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1474 - (hide annotations) (download)
Mon Nov 5 20:47:38 2007 UTC (16 years, 5 months ago) by schoenebeck
File size: 12576 byte(s)
* Qt4 migration: fixed another bunch of ghost connections, fixed engine
  combo box in channel form, fixed stdout ouptut in message window (a lot
  of white lines were shown), show channel strip on the work space (and not
  in the nirvana of the desktop universe)

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 schoenebeck 1461 #include "qsamplerChannelStrip.h"
24    
25     #include "qsamplerMainForm.h"
26    
27     #include <q3dragobject.h>
28    
29     #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     // Drag'n'drop file handler.
78     bool ChannelStrip::decodeDragFile ( const QMimeSource *pEvent, QString& sInstrumentFile )
79     {
80     if (m_pChannel == NULL)
81     return false;
82     if (Q3TextDrag::canDecode(pEvent)) {
83     QString sText;
84     if (Q3TextDrag::decode(pEvent, sText)) {
85     QStringList files = QStringList::split('\n', sText);
86     for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
87     *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
88     if (qsamplerChannel::isInstrumentFile(*iter)) {
89     sInstrumentFile = *iter;
90     return true;
91     }
92     }
93     }
94     }
95     // Fail.
96     return false;
97     }
98    
99    
100     // Window drag-n-drop event handlers.
101     void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
102     {
103     QString sInstrumentFile;
104     pDragEnterEvent->accept(decodeDragFile(pDragEnterEvent, sInstrumentFile));
105     }
106    
107    
108     void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
109     {
110     QString sInstrumentFile;
111    
112     if (decodeDragFile(pDropEvent, sInstrumentFile)) {
113     // Go and set the dropped instrument filename...
114     m_pChannel->setInstrument(sInstrumentFile, 0);
115     // Open up the channel dialog.
116     channelSetup();
117     }
118     }
119    
120    
121     // Channel strip setup formal initializer.
122     void ChannelStrip::setup ( qsamplerChannel *pChannel )
123     {
124     // Destroy any previous channel descriptor;
125     // (remember that once setup we own it!)
126     if (m_pChannel)
127     delete m_pChannel;
128    
129     // Set the new one...
130     m_pChannel = pChannel;
131    
132     // Stabilize this around.
133     updateChannelInfo();
134    
135     // We'll accept drops from now on...
136     if (m_pChannel)
137     setAcceptDrops(true);
138     }
139    
140     // Channel secriptor accessor.
141     qsamplerChannel *ChannelStrip::channel (void)
142     {
143     return m_pChannel;
144     }
145    
146    
147     // Messages view font accessors.
148     QFont ChannelStrip::displayFont (void)
149     {
150     return ui.EngineNameTextLabel->font();
151     }
152    
153     void ChannelStrip::setDisplayFont ( const QFont & font )
154     {
155     ui.EngineNameTextLabel->setFont(font);
156     ui.MidiPortChannelTextLabel->setFont(font);
157     ui.InstrumentNameTextLabel->setFont(font);
158     ui.InstrumentStatusTextLabel->setFont(font);
159     }
160    
161    
162     // Channel display background effect.
163     void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
164     {
165     QPixmap pm =
166     (bDisplayEffect) ?
167 schoenebeck 1474 QPixmap(":/icons/displaybg1.png") : QPixmap();
168 schoenebeck 1461 setDisplayBackground(pm);
169     }
170    
171    
172     // Update main display background pixmap.
173     void ChannelStrip::setDisplayBackground ( const QPixmap& pm )
174     {
175     // Set the main origin...
176     ui.ChannelInfoFrame->setPaletteBackgroundPixmap(pm);
177    
178     // Iterate for every child text label...
179     QList<QObject*> list = ui.ChannelInfoFrame->queryList("QLabel");
180     for (QList<QObject*>::iterator iter = list.begin(); iter != list.end(); iter++) {
181     static_cast<QLabel*>(*iter)->setPaletteBackgroundPixmap(pm);
182     }
183    
184     // And this standalone too.
185     ui.StreamVoiceCountTextLabel->setPaletteBackgroundPixmap(pm);
186     }
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     setCaption(sText);
343     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     // Instrument status...
371     int iInstrumentStatus = m_pChannel->instrumentStatus();
372     if (iInstrumentStatus < 0) {
373     ui.InstrumentStatusTextLabel->setPaletteForegroundColor(Qt::red);
374     ui.InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus));
375     m_iErrorCount++;
376     return false;
377     }
378     // All seems normal...
379     ui.InstrumentStatusTextLabel->setPaletteForegroundColor(iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
380     ui.InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + '%');
381     m_iErrorCount = 0;
382    
383     #ifdef CONFIG_MUTE_SOLO
384     // Mute/Solo button state coloring...
385     const QColor& rgbNormal = ChannelSetupPushButton->paletteBackgroundColor();
386     bool bMute = m_pChannel->channelMute();
387     ChannelMutePushButton->setPaletteBackgroundColor(bMute ? Qt::yellow : rgbNormal);
388     ChannelMutePushButton->setDown(bMute);
389     bool bSolo = m_pChannel->channelSolo();
390     ChannelSoloPushButton->setPaletteBackgroundColor(bSolo ? Qt::cyan : rgbNormal);
391     ChannelSoloPushButton->setDown(bSolo);
392     #else
393     ui.ChannelMutePushButton->setEnabled(false);
394     ui.ChannelSoloPushButton->setEnabled(false);
395     #endif
396    
397     // And update the both GUI volume elements;
398     // return success if, and only if, intrument is fully loaded...
399     return updateChannelVolume() && (iInstrumentStatus == 100);
400     }
401    
402    
403     // Update whole channel usage state.
404     bool ChannelStrip::updateChannelUsage (void)
405     {
406     if (m_pChannel == NULL)
407     return false;
408    
409     MainForm *pMainForm = MainForm::getInstance();
410     if (pMainForm->client() == NULL)
411     return false;
412    
413     // This only makes sense on fully loaded channels...
414     if (m_pChannel->instrumentStatus() < 100)
415     return false;
416    
417     // Get current channel voice count.
418     int iVoiceCount = ::lscp_get_channel_voice_count(pMainForm->client(), m_pChannel->channelID());
419     // Get current stream count.
420     int iStreamCount = ::lscp_get_channel_stream_count(pMainForm->client(), m_pChannel->channelID());
421     // Get current channel buffer fill usage.
422     // As benno has suggested this is the percentage usage
423     // of the least filled buffer stream...
424     int iStreamUsage = ::lscp_get_channel_stream_usage(pMainForm->client(), m_pChannel->channelID());;
425    
426     // Update the GUI elements...
427     ui.StreamUsageProgressBar->setValue(iStreamUsage);
428     ui.StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
429    
430     // We're clean.
431     return true;
432     }
433    
434    
435     // Volume change slot.
436     void ChannelStrip::volumeChanged ( int iVolume )
437     {
438     if (m_pChannel == NULL)
439     return;
440    
441     // Avoid recursion.
442     if (m_iDirtyChange > 0)
443     return;
444    
445     // Convert and clip.
446     float fVolume = (float) iVolume / 100.0;
447     if (fVolume < 0.001)
448     fVolume = 0.0;
449    
450     // Update the GUI elements.
451     if (m_pChannel->setVolume(fVolume)) {
452     updateChannelVolume();
453     emit channelChanged(this);
454     }
455     }
456    
457    
458     // Context menu event handler.
459     void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
460     {
461     if (m_pChannel == NULL)
462     return;
463    
464     // We'll just show up the main form's edit menu (thru qsamplerChannel).
465     m_pChannel->contextMenuEvent(pEvent);
466     }
467    
468    
469     // Error count hackish accessors.
470     void ChannelStrip::resetErrorCount (void)
471     {
472     m_iErrorCount = 0;
473     }
474    
475     } // namespace QSampler
476 capela 1464
477    
478     // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC