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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1464 - (show annotations) (download)
Thu Nov 1 17:14:21 2007 UTC (16 years, 5 months ago) by capela
File size: 12025 byte(s)
- Qt4 migration: missing copyright headers update.

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
50 ChannelStrip::~ChannelStrip() {
51 // Destroy existing channel descriptor.
52 if (m_pChannel)
53 delete m_pChannel;
54 m_pChannel = NULL;
55 }
56
57
58 // Drag'n'drop file handler.
59 bool ChannelStrip::decodeDragFile ( const QMimeSource *pEvent, QString& sInstrumentFile )
60 {
61 if (m_pChannel == NULL)
62 return false;
63 if (Q3TextDrag::canDecode(pEvent)) {
64 QString sText;
65 if (Q3TextDrag::decode(pEvent, sText)) {
66 QStringList files = QStringList::split('\n', sText);
67 for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
68 *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
69 if (qsamplerChannel::isInstrumentFile(*iter)) {
70 sInstrumentFile = *iter;
71 return true;
72 }
73 }
74 }
75 }
76 // Fail.
77 return false;
78 }
79
80
81 // Window drag-n-drop event handlers.
82 void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
83 {
84 QString sInstrumentFile;
85 pDragEnterEvent->accept(decodeDragFile(pDragEnterEvent, sInstrumentFile));
86 }
87
88
89 void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
90 {
91 QString sInstrumentFile;
92
93 if (decodeDragFile(pDropEvent, sInstrumentFile)) {
94 // Go and set the dropped instrument filename...
95 m_pChannel->setInstrument(sInstrumentFile, 0);
96 // Open up the channel dialog.
97 channelSetup();
98 }
99 }
100
101
102 // Channel strip setup formal initializer.
103 void ChannelStrip::setup ( qsamplerChannel *pChannel )
104 {
105 // Destroy any previous channel descriptor;
106 // (remember that once setup we own it!)
107 if (m_pChannel)
108 delete m_pChannel;
109
110 // Set the new one...
111 m_pChannel = pChannel;
112
113 // Stabilize this around.
114 updateChannelInfo();
115
116 // We'll accept drops from now on...
117 if (m_pChannel)
118 setAcceptDrops(true);
119 }
120
121 // Channel secriptor accessor.
122 qsamplerChannel *ChannelStrip::channel (void)
123 {
124 return m_pChannel;
125 }
126
127
128 // Messages view font accessors.
129 QFont ChannelStrip::displayFont (void)
130 {
131 return ui.EngineNameTextLabel->font();
132 }
133
134 void ChannelStrip::setDisplayFont ( const QFont & font )
135 {
136 ui.EngineNameTextLabel->setFont(font);
137 ui.MidiPortChannelTextLabel->setFont(font);
138 ui.InstrumentNameTextLabel->setFont(font);
139 ui.InstrumentStatusTextLabel->setFont(font);
140 }
141
142
143 // Channel display background effect.
144 void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
145 {
146 QPixmap pm =
147 (bDisplayEffect) ?
148 QPixmap(":/qsampler/pixmaps/displaybg1.png") : QPixmap();
149 setDisplayBackground(pm);
150 }
151
152
153 // Update main display background pixmap.
154 void ChannelStrip::setDisplayBackground ( const QPixmap& pm )
155 {
156 // Set the main origin...
157 ui.ChannelInfoFrame->setPaletteBackgroundPixmap(pm);
158
159 // Iterate for every child text label...
160 QList<QObject*> list = ui.ChannelInfoFrame->queryList("QLabel");
161 for (QList<QObject*>::iterator iter = list.begin(); iter != list.end(); iter++) {
162 static_cast<QLabel*>(*iter)->setPaletteBackgroundPixmap(pm);
163 }
164
165 // And this standalone too.
166 ui.StreamVoiceCountTextLabel->setPaletteBackgroundPixmap(pm);
167 }
168
169
170 // Maximum volume slider accessors.
171 void ChannelStrip::setMaxVolume ( int iMaxVolume )
172 {
173 m_iDirtyChange++;
174 ui.VolumeSlider->setRange(0, iMaxVolume);
175 ui.VolumeSpinBox->setRange(0, iMaxVolume);
176 m_iDirtyChange--;
177 }
178
179
180 // Channel setup dialog slot.
181 bool ChannelStrip::channelSetup (void)
182 {
183 if (m_pChannel == NULL)
184 return false;
185
186 // Invoke the channel setup dialog.
187 bool bResult = m_pChannel->channelSetup(this);
188 // Notify that this channel has changed.
189 if (bResult)
190 emit channelChanged(this);
191
192 return bResult;
193 }
194
195
196 // Channel mute slot.
197 bool ChannelStrip::channelMute ( bool bMute )
198 {
199 if (m_pChannel == NULL)
200 return false;
201
202 // Invoke the channel mute method.
203 bool bResult = m_pChannel->setChannelMute(bMute);
204 // Notify that this channel has changed.
205 if (bResult)
206 emit channelChanged(this);
207
208 return bResult;
209 }
210
211
212 // Channel solo slot.
213 bool ChannelStrip::channelSolo ( bool bSolo )
214 {
215 if (m_pChannel == NULL)
216 return false;
217
218 // Invoke the channel solo method.
219 bool bResult = m_pChannel->setChannelSolo(bSolo);
220 // Notify that this channel has changed.
221 if (bResult)
222 emit channelChanged(this);
223
224 return bResult;
225 }
226
227
228 // Channel edit slot.
229 void ChannelStrip::channelEdit (void)
230 {
231 if (m_pChannel == NULL)
232 return;
233
234 m_pChannel->editChannel();
235 }
236
237
238 // Channel reset slot.
239 bool ChannelStrip::channelReset (void)
240 {
241 if (m_pChannel == NULL)
242 return false;
243
244 // Invoke the channel reset method.
245 bool bResult = m_pChannel->channelReset();
246 // Notify that this channel has changed.
247 if (bResult)
248 emit channelChanged(this);
249
250 return bResult;
251 }
252
253
254 // Update the channel instrument name.
255 bool ChannelStrip::updateInstrumentName ( bool bForce )
256 {
257 if (m_pChannel == NULL)
258 return false;
259
260 // Do we refresh the actual name?
261 if (bForce)
262 m_pChannel->updateInstrumentName();
263
264 // Instrument name...
265 if (m_pChannel->instrumentName().isEmpty()) {
266 if (m_pChannel->instrumentStatus() >= 0)
267 ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::loadingInstrument());
268 else
269 ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName());
270 } else
271 ui.InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName());
272
273 return true;
274 }
275
276
277 // Do the dirty volume change.
278 bool ChannelStrip::updateChannelVolume (void)
279 {
280 if (m_pChannel == NULL)
281 return false;
282
283 // Convert...
284 #ifdef CONFIG_ROUND
285 int iVolume = (int) ::round(100.0 * m_pChannel->volume());
286 #else
287 double fIPart = 0.0;
288 double fFPart = ::modf(100.0 * m_pChannel->volume(), &fIPart);
289 int iVolume = (int) fIPart;
290 if (fFPart >= +0.5)
291 iVolume++;
292 else
293 if (fFPart <= -0.5)
294 iVolume--;
295 #endif
296
297 // And clip...
298 if (iVolume < 0)
299 iVolume = 0;
300
301 // Flag it here, to avoid infinite recursion.
302 m_iDirtyChange++;
303 ui.VolumeSlider->setValue(iVolume);
304 ui.VolumeSpinBox->setValue(iVolume);
305 m_iDirtyChange--;
306
307 return true;
308 }
309
310
311 // Update whole channel info state.
312 bool ChannelStrip::updateChannelInfo (void)
313 {
314 if (m_pChannel == NULL)
315 return false;
316
317 // Check for error limit/recycle...
318 if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
319 return true;
320
321 // Update strip caption.
322 QString sText = m_pChannel->channelName();
323 setCaption(sText);
324 ui.ChannelSetupPushButton->setText(sText);
325
326 // Check if we're up and connected.
327 MainForm* pMainForm = MainForm::getInstance();
328 if (pMainForm->client() == NULL)
329 return false;
330
331 // Read actual channel information.
332 m_pChannel->updateChannelInfo();
333
334 // Engine name...
335 if (m_pChannel->engineName().isEmpty())
336 ui.EngineNameTextLabel->setText(' ' + qsamplerChannel::noEngineName());
337 else
338 ui.EngineNameTextLabel->setText(' ' + m_pChannel->engineName());
339
340 // Instrument name...
341 updateInstrumentName(false);
342
343 // MIDI Port/Channel...
344 QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";
345 if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
346 sMidiPortChannel += tr("All");
347 else
348 sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);
349 ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
350
351 // Instrument status...
352 int iInstrumentStatus = m_pChannel->instrumentStatus();
353 if (iInstrumentStatus < 0) {
354 ui.InstrumentStatusTextLabel->setPaletteForegroundColor(Qt::red);
355 ui.InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus));
356 m_iErrorCount++;
357 return false;
358 }
359 // All seems normal...
360 ui.InstrumentStatusTextLabel->setPaletteForegroundColor(iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
361 ui.InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + '%');
362 m_iErrorCount = 0;
363
364 #ifdef CONFIG_MUTE_SOLO
365 // Mute/Solo button state coloring...
366 const QColor& rgbNormal = ChannelSetupPushButton->paletteBackgroundColor();
367 bool bMute = m_pChannel->channelMute();
368 ChannelMutePushButton->setPaletteBackgroundColor(bMute ? Qt::yellow : rgbNormal);
369 ChannelMutePushButton->setDown(bMute);
370 bool bSolo = m_pChannel->channelSolo();
371 ChannelSoloPushButton->setPaletteBackgroundColor(bSolo ? Qt::cyan : rgbNormal);
372 ChannelSoloPushButton->setDown(bSolo);
373 #else
374 ui.ChannelMutePushButton->setEnabled(false);
375 ui.ChannelSoloPushButton->setEnabled(false);
376 #endif
377
378 // And update the both GUI volume elements;
379 // return success if, and only if, intrument is fully loaded...
380 return updateChannelVolume() && (iInstrumentStatus == 100);
381 }
382
383
384 // Update whole channel usage state.
385 bool ChannelStrip::updateChannelUsage (void)
386 {
387 if (m_pChannel == NULL)
388 return false;
389
390 MainForm *pMainForm = MainForm::getInstance();
391 if (pMainForm->client() == NULL)
392 return false;
393
394 // This only makes sense on fully loaded channels...
395 if (m_pChannel->instrumentStatus() < 100)
396 return false;
397
398 // Get current channel voice count.
399 int iVoiceCount = ::lscp_get_channel_voice_count(pMainForm->client(), m_pChannel->channelID());
400 // Get current stream count.
401 int iStreamCount = ::lscp_get_channel_stream_count(pMainForm->client(), m_pChannel->channelID());
402 // Get current channel buffer fill usage.
403 // As benno has suggested this is the percentage usage
404 // of the least filled buffer stream...
405 int iStreamUsage = ::lscp_get_channel_stream_usage(pMainForm->client(), m_pChannel->channelID());;
406
407 // Update the GUI elements...
408 ui.StreamUsageProgressBar->setValue(iStreamUsage);
409 ui.StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
410
411 // We're clean.
412 return true;
413 }
414
415
416 // Volume change slot.
417 void ChannelStrip::volumeChanged ( int iVolume )
418 {
419 if (m_pChannel == NULL)
420 return;
421
422 // Avoid recursion.
423 if (m_iDirtyChange > 0)
424 return;
425
426 // Convert and clip.
427 float fVolume = (float) iVolume / 100.0;
428 if (fVolume < 0.001)
429 fVolume = 0.0;
430
431 // Update the GUI elements.
432 if (m_pChannel->setVolume(fVolume)) {
433 updateChannelVolume();
434 emit channelChanged(this);
435 }
436 }
437
438
439 // Context menu event handler.
440 void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
441 {
442 if (m_pChannel == NULL)
443 return;
444
445 // We'll just show up the main form's edit menu (thru qsamplerChannel).
446 m_pChannel->contextMenuEvent(pEvent);
447 }
448
449
450 // Error count hackish accessors.
451 void ChannelStrip::resetErrorCount (void)
452 {
453 m_iErrorCount = 0;
454 }
455
456 } // namespace QSampler
457
458
459 // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC