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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1461 - (show annotations) (download)
Sun Oct 28 23:30:36 2007 UTC (16 years, 5 months ago) by schoenebeck
File size: 10963 byte(s)
* started to port QSampler to Qt4 (NOTE: this version is yet broken, use
  the latest tarball release 0.1.5 until the Qt4 port is completed)

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

  ViewVC Help
Powered by ViewVC