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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 // 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 #include "qsamplerAbout.h"
24 #include "qsamplerChannelStrip.h"
25
26 #include "qsamplerMainForm.h"
27
28 #include <QDragEnterEvent>
29 #include <QUrl>
30
31 // Channel status/usage usage limit control.
32 #define QSAMPLER_ERROR_LIMIT 3
33
34 // Needed for lroundf()
35 #include <math.h>
36
37 namespace QSampler {
38
39 #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 ChannelStrip::ChannelStrip ( QWidget* pParent, Qt::WindowFlags wflags )
50 : QWidget(pParent, wflags)
51 {
52 m_ui.setupUi(this);
53
54 // Initialize locals.
55 m_pChannel = NULL;
56 m_iDirtyChange = 0;
57 m_iErrorCount = 0;
58
59 // Try to restore normal window positioning.
60 adjustSize();
61
62 QObject::connect(m_ui.ChannelSetupPushButton,
63 SIGNAL(clicked()),
64 SLOT(channelSetup()));
65 QObject::connect(m_ui.ChannelMutePushButton,
66 SIGNAL(toggled(bool)),
67 SLOT(channelMute(bool)));
68 QObject::connect(m_ui.ChannelSoloPushButton,
69 SIGNAL(toggled(bool)),
70 SLOT(channelSolo(bool)));
71 QObject::connect(m_ui.VolumeSlider,
72 SIGNAL(valueChanged(int)),
73 SLOT(volumeChanged(int)));
74 QObject::connect(m_ui.VolumeSpinBox,
75 SIGNAL(valueChanged(int)),
76 SLOT(volumeChanged(int)));
77 QObject::connect(m_ui.ChannelEditPushButton,
78 SIGNAL(clicked()),
79 SLOT(channelEdit()));
80 }
81
82 ChannelStrip::~ChannelStrip() {
83 // Destroy existing channel descriptor.
84 if (m_pChannel)
85 delete m_pChannel;
86 m_pChannel = NULL;
87 }
88
89
90 // Window drag-n-drop event handlers.
91 void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
92 {
93 if (m_pChannel == NULL)
94 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 }
108 }
109 }
110 }
111
112 if (bAccept)
113 pDragEnterEvent->accept();
114 else
115 pDragEnterEvent->ignore();
116 }
117
118
119 void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
120 {
121 if (m_pChannel == NULL)
122 return;
123
124 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 }
142 }
143
144
145 // Channel strip setup formal initializer.
146 void ChannelStrip::setup ( qsamplerChannel *pChannel )
147 {
148 // Destroy any previous channel descriptor;
149 // (remember that once setup we own it!)
150 if (m_pChannel)
151 delete m_pChannel;
152
153 // Set the new one...
154 m_pChannel = pChannel;
155
156 // Stabilize this around.
157 updateChannelInfo();
158
159 // We'll accept drops from now on...
160 if (m_pChannel)
161 setAcceptDrops(true);
162 }
163
164 // Channel secriptor accessor.
165 qsamplerChannel *ChannelStrip::channel (void) const
166 {
167 return m_pChannel;
168 }
169
170
171 // Messages view font accessors.
172 QFont ChannelStrip::displayFont (void) const
173 {
174 return m_ui.EngineNameTextLabel->font();
175 }
176
177 void ChannelStrip::setDisplayFont ( const QFont & font )
178 {
179 m_ui.EngineNameTextLabel->setFont(font);
180 m_ui.MidiPortChannelTextLabel->setFont(font);
181 m_ui.InstrumentNameTextLabel->setFont(font);
182 m_ui.InstrumentStatusTextLabel->setFont(font);
183 }
184
185
186 // Channel display background effect.
187 void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
188 {
189 QPalette pal;
190 pal.setColor(QPalette::Foreground, Qt::yellow);
191 m_ui.EngineNameTextLabel->setPalette(pal);
192 m_ui.MidiPortChannelTextLabel->setPalette(pal);
193 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 m_ui.ChannelInfoFrame->setPalette(pal);
201 m_ui.StreamVoiceCountTextLabel->setPalette(pal);
202 }
203
204
205 // Maximum volume slider accessors.
206 void ChannelStrip::setMaxVolume ( int iMaxVolume )
207 {
208 m_iDirtyChange++;
209 m_ui.VolumeSlider->setRange(0, iMaxVolume);
210 m_ui.VolumeSpinBox->setRange(0, iMaxVolume);
211 m_iDirtyChange--;
212 }
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 m_ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::loadingInstrument());
303 else
304 m_ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName());
305 } else
306 m_ui.InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName());
307
308 return true;
309 }
310
311
312 // Do the dirty volume change.
313 bool ChannelStrip::updateChannelVolume (void)
314 {
315 if (m_pChannel == NULL)
316 return false;
317
318 // Convert...
319 int iVolume = ::lroundf(100.0f * m_pChannel->volume());
320 // And clip...
321 if (iVolume < 0)
322 iVolume = 0;
323
324 // 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
330 return true;
331 }
332
333
334 // Update whole channel info state.
335 bool ChannelStrip::updateChannelInfo (void)
336 {
337 if (m_pChannel == NULL)
338 return false;
339
340 // Check for error limit/recycle...
341 if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
342 return true;
343
344 // Update strip caption.
345 QString sText = m_pChannel->channelName();
346 setWindowTitle(sText);
347 m_ui.ChannelSetupPushButton->setText(sText);
348
349 // Check if we're up and connected.
350 MainForm* pMainForm = MainForm::getInstance();
351 if (pMainForm->client() == NULL)
352 return false;
353
354 // Read actual channel information.
355 m_pChannel->updateChannelInfo();
356
357 // 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
363 // Instrument name...
364 updateInstrumentName(false);
365
366 // MIDI Port/Channel...
367 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 m_ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
373
374 // Common palette...
375 QPalette pal;
376 const QColor& rgbFore = pal.color(QPalette::Foreground);
377
378 // Instrument status...
379 int iInstrumentStatus = m_pChannel->instrumentStatus();
380 if (iInstrumentStatus < 0) {
381 pal.setColor(QPalette::Foreground, Qt::red);
382 m_ui.InstrumentStatusTextLabel->setPalette(pal);
383 m_ui.InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus));
384 m_iErrorCount++;
385 return false;
386 }
387 // All seems normal...
388 pal.setColor(QPalette::Foreground,
389 iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
390 m_ui.InstrumentStatusTextLabel->setPalette(pal);
391 m_ui.InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + '%');
392 m_iErrorCount = 0;
393
394 #ifdef CONFIG_MUTE_SOLO
395 // Mute/Solo button state coloring...
396 bool bMute = m_pChannel->channelMute();
397 const QColor& rgbButton = pal.color(QPalette::Button);
398 pal.setColor(QPalette::Foreground, rgbFore);
399 pal.setColor(QPalette::Button, bMute ? Qt::yellow : rgbButton);
400 m_ui.ChannelMutePushButton->setPalette(pal);
401 m_ui.ChannelMutePushButton->setDown(bMute);
402 bool bSolo = m_pChannel->channelSolo();
403 pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);
404 m_ui.ChannelSoloPushButton->setPalette(pal);
405 m_ui.ChannelSoloPushButton->setDown(bSolo);
406 #else
407 m_ui.ChannelMutePushButton->setEnabled(false);
408 m_ui.ChannelSoloPushButton->setEnabled(false);
409 #endif
410
411 // And update the both GUI volume elements;
412 // return success if, and only if, intrument is fully loaded...
413 return updateChannelVolume() && (iInstrumentStatus == 100);
414 }
415
416
417 // Update whole channel usage state.
418 bool ChannelStrip::updateChannelUsage (void)
419 {
420 if (m_pChannel == NULL)
421 return false;
422
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 return false;
430
431 // 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
440 // Update the GUI elements...
441 m_ui.StreamUsageProgressBar->setValue(iStreamUsage);
442 m_ui.StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
443
444 // We're clean.
445 return true;
446 }
447
448
449 // Volume change slot.
450 void ChannelStrip::volumeChanged ( int iVolume )
451 {
452 if (m_pChannel == NULL)
453 return;
454
455 // Avoid recursion.
456 if (m_iDirtyChange > 0)
457 return;
458
459 // Convert and clip.
460 float fVolume = (float) iVolume / 100.0f;
461 if (fVolume < 0.001f)
462 fVolume = 0.0f;
463
464 // Update the GUI elements.
465 if (m_pChannel->setVolume(fVolume)) {
466 updateChannelVolume();
467 emit channelChanged(this);
468 }
469 }
470
471
472 // Context menu event handler.
473 void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
474 {
475 if (m_pChannel == NULL)
476 return;
477
478 // We'll just show up the main form's edit menu (thru qsamplerChannel).
479 m_pChannel->contextMenuEvent(pEvent);
480 }
481
482
483 // Error count hackish accessors.
484 void ChannelStrip::resetErrorCount (void)
485 {
486 m_iErrorCount = 0;
487 }
488
489 } // namespace QSampler
490
491
492 // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC