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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1466 - (show 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 // 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 "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
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 // 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
477
478 // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC