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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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 #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
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 }
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 // Window drag-n-drop event handlers.
78 void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
79 {
80 if (m_pChannel == NULL)
81 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 }
95 }
96 }
97 }
98
99 if (bAccept)
100 pDragEnterEvent->accept();
101 else
102 pDragEnterEvent->ignore();
103 }
104
105
106 void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
107 {
108 if (m_pChannel == NULL)
109 return;
110
111 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 }
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 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 }
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 setWindowTitle(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 // Common palette...
371 QPalette pal;
372 const QColor& rgbFore = pal.color(QPalette::Foreground);
373
374 // Instrument status...
375 int iInstrumentStatus = m_pChannel->instrumentStatus();
376 if (iInstrumentStatus < 0) {
377 pal.setColor(QPalette::Foreground, Qt::red);
378 ui.InstrumentStatusTextLabel->setPalette(pal);
379 ui.InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus));
380 m_iErrorCount++;
381 return false;
382 }
383 // All seems normal...
384 pal.setColor(QPalette::Foreground,
385 iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
386 ui.InstrumentStatusTextLabel->setPalette(pal);
387 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 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 bool bSolo = m_pChannel->channelSolo();
399 pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);
400 ui.ChannelSoloPushButton->setPalette(pal);
401 ui.ChannelSoloPushButton->setDown(bSolo);
402 #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 // Get current stream count.
430 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
487
488 // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC