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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1466 - (hide annotations) (download)
Thu Nov 1 19:25:10 2007 UTC (16 years, 5 months ago) by capela
File size: 12587 byte(s)
* Qt4 migration: added missing signal/slot connections for most forms.

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     QPixmap(":/qsampler/pixmaps/displaybg1.png") : QPixmap();
168     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