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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 388 - (show annotations) (download)
Thu Feb 17 17:27:59 2005 UTC (19 years, 1 month ago) by capela
File size: 15668 byte(s)
* Drag-and-drop of either session files (LSCP scripts) or
  instrument files (GIG) are now supported. Multiple files
  drop is allowed, but it only makes sense for instrument
  files, each one prompting to create a new sampler channel.

1 // qsamplerChannel.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2003-2005, rncbc aka Rui Nuno Capela. All rights reserved.
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 *****************************************************************************/
21
22 #include "qsamplerChannel.h"
23
24 #include "qsamplerMainForm.h"
25 #include "qsamplerChannelForm.h"
26
27 #include "config.h"
28
29 #include <qfileinfo.h>
30
31 #ifdef CONFIG_LIBGIG
32 #include "gig.h"
33 #endif
34
35 #define QSAMPLER_INSTRUMENT_MAX 8
36
37
38 //-------------------------------------------------------------------------
39 // qsamplerChannel - Sampler channel structure.
40 //
41
42 // Constructor.
43 qsamplerChannel::qsamplerChannel ( qsamplerMainForm *pMainForm, int iChannelID )
44 {
45 m_pMainForm = pMainForm;
46 m_iChannelID = iChannelID;
47
48 // m_sEngineName = noEngineName();
49 // m_sInstrumentName = noInstrumentName();
50 // m_sInstrumentFile = m_sInstrumentName;
51 m_iInstrumentNr = -1;
52 m_iInstrumentStatus = -1;
53 m_sMidiDriver = "Alsa"; // DEPRECATED.
54 m_iMidiDevice = -1;
55 m_iMidiPort = -1;
56 m_iMidiChannel = -1;
57 m_sAudioDriver = "Alsa"; // DEPRECATED.
58 m_iAudioDevice = -1;
59 m_fVolume = 0.0;
60
61 }
62
63 // Default destructor.
64 qsamplerChannel::~qsamplerChannel (void)
65 {
66 }
67
68
69 // The global options settings delegated property.
70 qsamplerOptions *qsamplerChannel::options (void)
71 {
72 if (m_pMainForm == NULL)
73 return NULL;
74
75 return m_pMainForm->options();
76 }
77
78
79 // The client descriptor delegated property.
80 lscp_client_t *qsamplerChannel::client (void)
81 {
82 if (m_pMainForm == NULL)
83 return NULL;
84
85 return m_pMainForm->client();
86 }
87
88
89 // Create a new sampler channel, if not already.
90 bool qsamplerChannel::addChannel (void)
91 {
92 if (client() == NULL)
93 return false;
94
95 // Are we a new channel?
96 if (m_iChannelID < 0) {
97 m_iChannelID = ::lscp_add_channel(client());
98 if (m_iChannelID < 0) {
99 appendMessagesClient("lscp_add_channel");
100 appendMessagesError(QObject::tr("Could not create the new channel.\n\nSorry."));
101 } // Otherwise it's created...
102 else appendMessages(QObject::tr("Channel %1 created.").arg(m_iChannelID));
103 }
104
105 // Return whether we're a valid channel...
106 return (m_iChannelID >= 0);
107 }
108
109
110 // Remove sampler channel.
111 bool qsamplerChannel::removeChannel (void)
112 {
113 if (client() == NULL)
114 return false;
115
116 // Are we an existing channel?
117 if (m_iChannelID >= 0) {
118 if (::lscp_remove_channel(client(), m_iChannelID) != LSCP_OK) {
119 appendMessagesClient("lscp_remove_channel");
120 appendMessagesError(QObject::tr("Could not remove channel.\n\nSorry."));
121 } else {
122 // Otherwise it's removed.
123 appendMessages(QObject::tr("Channel %1 removed.").arg(m_iChannelID));
124 m_iChannelID = -1;
125 }
126 }
127
128 // Return whether we've removed the channel...
129 return (m_iChannelID < 0);
130 }
131
132
133 // Channel-ID (aka Sammpler-Channel) accessors.
134 int qsamplerChannel::channelID (void)
135 {
136 return m_iChannelID;
137 }
138
139 void qsamplerChannel::setChannelID ( int iChannelID )
140 {
141 m_iChannelID = iChannelID;
142 }
143
144
145 // Readable channel name.
146 QString qsamplerChannel::channelName (void)
147 {
148 return (m_iChannelID < 0 ? QObject::tr("New Channel") : QObject::tr("Channel %1").arg(m_iChannelID));
149 }
150
151
152 // Engine name accessors.
153 QString& qsamplerChannel::engineName (void)
154 {
155 return m_sEngineName;
156 }
157
158 bool qsamplerChannel::loadEngine ( const QString& sEngineName )
159 {
160 if (client() == NULL || m_iChannelID < 0)
161 return false;
162
163 if (::lscp_load_engine(client(), sEngineName.latin1(), m_iChannelID) != LSCP_OK) {
164 appendMessagesClient("lscp_load_engine");
165 return false;
166 }
167
168 m_sEngineName = sEngineName;
169 return true;
170 }
171
172
173 // Instrument filename accessor.
174 QString& qsamplerChannel::instrumentFile (void)
175 {
176 return m_sInstrumentFile;
177 }
178
179 // Instrument index accessor.
180 int qsamplerChannel::instrumentNr (void)
181 {
182 return m_iInstrumentNr;
183 }
184
185 // Instrument name accessor.
186 QString& qsamplerChannel::instrumentName (void)
187 {
188 return m_sInstrumentName;
189 }
190
191 // Instrument status accessor.
192 int qsamplerChannel::instrumentStatus (void)
193 {
194 return m_iInstrumentStatus;
195 }
196
197 // Instrument file loader.
198 bool qsamplerChannel::loadInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
199 {
200 if (client() == NULL || m_iChannelID < 0)
201 return false;
202 if (!isInstrumentFile(sInstrumentFile))
203 return false;
204
205 if (::lscp_load_instrument_non_modal(client(), sInstrumentFile.latin1(), iInstrumentNr, m_iChannelID) != LSCP_OK) {
206 appendMessagesClient("lscp_load_instrument");
207 return false;
208 }
209
210 return setInstrument(sInstrumentFile, iInstrumentNr);
211 }
212
213
214 // Special instrument file/name/number settler.
215 bool qsamplerChannel::setInstrument ( const QString& sInstrumentFile, int iInstrumentNr )
216 {
217 m_sInstrumentFile = sInstrumentFile;
218 m_iInstrumentNr = iInstrumentNr;
219 #ifdef CONFIG_INSTRUMENT_NAME
220 m_sInstrumentName = QString::null; // We'll get it, maybe later, on channel_info...
221 #else
222 m_sInstrumentName = getInstrumentName(sInstrumentFile, iInstrumentNr, true);
223 #endif
224 m_iInstrumentStatus = 0;
225
226 return true;
227 }
228
229
230 // MIDI driver type accessors (DEPRECATED).
231 QString& qsamplerChannel::midiDriver (void)
232 {
233 return m_sMidiDriver;
234 }
235
236 bool qsamplerChannel::setMidiDriver ( const QString& sMidiDriver )
237 {
238 if (client() == NULL || m_iChannelID < 0)
239 return false;
240
241 if (::lscp_set_channel_midi_type(client(), m_iChannelID, sMidiDriver.latin1()) != LSCP_OK) {
242 appendMessagesClient("lscp_set_channel_midi_type");
243 return false;
244 }
245
246 m_sMidiDriver = sMidiDriver;
247 return true;
248 }
249
250
251 // MIDI device accessors.
252 int qsamplerChannel::midiDevice (void)
253 {
254 return m_iMidiDevice;
255 }
256
257 bool qsamplerChannel::setMidiDevice ( int iMidiDevice )
258 {
259 if (client() == NULL || m_iChannelID < 0)
260 return false;
261
262 if (::lscp_set_channel_midi_device(client(), m_iChannelID, iMidiDevice) != LSCP_OK) {
263 appendMessagesClient("lscp_set_channel_midi_device");
264 return false;
265 }
266
267 m_iMidiDevice = iMidiDevice;
268 return true;
269 }
270
271
272 // MIDI port number accessor.
273 int qsamplerChannel::midiPort (void)
274 {
275 return m_iMidiPort;
276 }
277
278 bool qsamplerChannel::setMidiPort ( int iMidiPort )
279 {
280 if (client() == NULL || m_iChannelID < 0)
281 return false;
282
283 if (::lscp_set_channel_midi_port(client(), m_iChannelID, iMidiPort) != LSCP_OK) {
284 appendMessagesClient("lscp_set_channel_midi_port");
285 return false;
286 }
287
288 m_iMidiPort = iMidiPort;
289 return true;
290 }
291
292
293 // MIDI channel accessor.
294 int qsamplerChannel::midiChannel (void)
295 {
296 return m_iMidiChannel;
297 }
298
299 bool qsamplerChannel::setMidiChannel ( int iMidiChannel )
300 {
301 if (client() == NULL || m_iChannelID < 0)
302 return false;
303
304 if (::lscp_set_channel_midi_channel(client(), m_iChannelID, iMidiChannel) != LSCP_OK) {
305 appendMessagesClient("lscp_set_channel_midi_channel");
306 return false;
307 }
308
309 m_iMidiChannel = iMidiChannel;
310 return true;
311 }
312
313
314 // Audio device accessor.
315 int qsamplerChannel::audioDevice (void)
316 {
317 return m_iAudioDevice;
318 }
319
320 bool qsamplerChannel::setAudioDevice ( int iAudioDevice )
321 {
322 if (client() == NULL || m_iChannelID < 0)
323 return false;
324
325 if (::lscp_set_channel_audio_device(client(), m_iChannelID, iAudioDevice) != LSCP_OK) {
326 appendMessagesClient("lscp_set_channel_audio_device");
327 return false;
328 }
329
330 m_iAudioDevice = iAudioDevice;
331 return true;
332 }
333
334
335 // Audio driver type accessors (DEPRECATED).
336 QString& qsamplerChannel::audioDriver (void)
337 {
338 return m_sAudioDriver;
339 }
340
341 bool qsamplerChannel::setAudioDriver ( const QString& sAudioDriver )
342 {
343 if (client() == NULL || m_iChannelID < 0)
344 return false;
345
346 if (::lscp_set_channel_audio_type(client(), m_iChannelID, sAudioDriver.latin1()) != LSCP_OK) {
347 appendMessagesClient("lscp_set_channel_audio_type");
348 return false;
349 }
350
351 m_sAudioDriver = sAudioDriver;
352 return true;
353 }
354
355
356 // Channel volume accessors.
357 float qsamplerChannel::volume (void)
358 {
359 return m_fVolume;
360 }
361
362 bool qsamplerChannel::setVolume ( float fVolume )
363 {
364 if (client() == NULL || m_iChannelID < 0)
365 return false;
366
367 if (::lscp_set_channel_volume(client(), m_iChannelID, fVolume) != LSCP_OK) {
368 appendMessagesClient("lscp_set_channel_volume");
369 return false;
370 }
371
372 m_fVolume = fVolume;
373 return true;
374 }
375
376
377 // Istrument name remapper.
378 void qsamplerChannel::updateInstrumentName (void)
379 {
380 #ifndef CONFIG_INSTRUMENT_NAME
381 m_sInstrumentName = getInstrumentName(m_sInstrumentFile,
382 m_iInstrumentNr, (options() && options()->bInstrumentNames));
383 #endif
384 }
385
386
387 // Update whole channel info state.
388 bool qsamplerChannel::updateChannelInfo (void)
389 {
390 if (client() == NULL || m_iChannelID < 0)
391 return false;
392
393 // Read channel information.
394 lscp_channel_info_t *pChannelInfo = ::lscp_get_channel_info(client(), m_iChannelID);
395 if (pChannelInfo == NULL) {
396 appendMessagesClient("lscp_get_channel_info");
397 appendMessagesError(QObject::tr("Could not get channel information.\n\nSorry."));
398 return false;
399 }
400
401 #ifdef CONFIG_INSTRUMENT_NAME
402 // We got all actual instrument datum...
403 m_sInstrumentFile = pChannelInfo->instrument_file;
404 m_iInstrumentNr = pChannelInfo->instrument_nr;
405 m_sInstrumentName = pChannelInfo->instrument_name;
406 #else
407 // First, check if intrument name has changed,
408 // taking care that instrument name lookup might be expensive,
409 // so we better make it only once and when really needed...
410 if ((m_sInstrumentFile != pChannelInfo->instrument_file) ||
411 (m_iInstrumentNr != pChannelInfo->instrument_nr)) {
412 m_sInstrumentFile = pChannelInfo->instrument_file;
413 m_iInstrumentNr = pChannelInfo->instrument_nr;
414 updateInstrumentName();
415 }
416 #endif
417 // Cache in other channel information.
418 m_sEngineName = pChannelInfo->engine_name;
419 m_iInstrumentStatus = pChannelInfo->instrument_status;
420 m_iMidiDevice = pChannelInfo->midi_device;
421 m_iMidiPort = pChannelInfo->midi_port;
422 m_iMidiChannel = pChannelInfo->midi_channel;
423 m_iAudioDevice = pChannelInfo->audio_device;
424 m_fVolume = pChannelInfo->volume;
425 // Some sanity checks.
426 if (m_sEngineName == "NONE")
427 m_sEngineName = QString::null;
428 if (m_sInstrumentFile == "NONE") {
429 m_sInstrumentFile = QString::null;
430 m_sInstrumentName = QString::null;
431 }
432
433 return true;
434 }
435
436
437 // Reset channel method.
438 bool qsamplerChannel::resetChannel (void)
439 {
440 if (client() == NULL || m_iChannelID < 0)
441 return false;
442
443 if (::lscp_reset_channel(client(), m_iChannelID) != LSCP_OK) {
444 appendMessagesClient("lscp_reset_channel");
445 return false;
446 }
447
448 appendMessages(QObject::tr("Channel %1 reset.").arg(m_iChannelID));
449 return true;
450 }
451
452
453 // Channel setup dialog form.
454 bool qsamplerChannel::channelSetup ( QWidget *pParent )
455 {
456 bool bResult = false;
457
458 qsamplerChannelForm *pChannelForm = new qsamplerChannelForm(pParent);
459 if (pChannelForm) {
460 pChannelForm->setup(this);
461 bResult = pChannelForm->exec();
462 delete pChannelForm;
463 }
464
465 return bResult;
466 }
467
468
469 // Redirected messages output methods.
470 void qsamplerChannel::appendMessages( const QString& s )
471 {
472 if (m_pMainForm) m_pMainForm->appendMessages(s);
473 }
474
475 void qsamplerChannel::appendMessagesColor( const QString& s, const QString& c )
476 {
477 if (m_pMainForm) m_pMainForm->appendMessagesColor(s, c);
478 }
479
480 void qsamplerChannel::appendMessagesText( const QString& s )
481 {
482 if (m_pMainForm) m_pMainForm->appendMessagesText(s);
483 }
484
485 void qsamplerChannel::appendMessagesError( const QString& s )
486 {
487 if (m_pMainForm) m_pMainForm->appendMessagesError(s);
488 }
489
490 void qsamplerChannel::appendMessagesClient( const QString& s )
491 {
492 if (m_pMainForm) m_pMainForm->appendMessagesClient(s);
493 }
494
495
496 // Context menu event handler.
497 void qsamplerChannel::contextMenuEvent( QContextMenuEvent *pEvent )
498 {
499 if (m_pMainForm) m_pMainForm->contextMenuEvent(pEvent);
500 }
501
502
503 // FIXME: Check whether a given file is an instrument file.
504 bool qsamplerChannel::isInstrumentFile ( const QString& sInstrumentFile )
505 {
506 bool bResult = false;
507
508 QFile file(sInstrumentFile);
509 if (file.open(IO_ReadOnly)) {
510 char achHeader[4];
511 if (file.readBlock(achHeader, 4)) {
512 bResult = (achHeader[0] == 'R'
513 && achHeader[1] == 'I'
514 && achHeader[2] == 'F'
515 && achHeader[3] == 'F');
516 }
517 file.close();
518 }
519
520 return bResult;
521 }
522
523
524 // Retrieve the instrument list of a instrument file (.gig).
525 QStringList qsamplerChannel::getInstrumentList( const QString& sInstrumentFile,
526 bool bInstrumentNames )
527 {
528 QString sInstrumentName = QFileInfo(sInstrumentFile).fileName();
529 QStringList instlist;
530
531 if (isInstrumentFile(sInstrumentFile)) {
532 #ifdef CONFIG_LIBGIG
533 if (bInstrumentNames) {
534 RIFF::File *pRiff = new RIFF::File(sInstrumentFile);
535 gig::File *pGig = new gig::File(pRiff);
536 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
537 while (pInstrument) {
538 instlist.append((pInstrument->pInfo)->Name.c_str());
539 pInstrument = pGig->GetNextInstrument();
540 }
541 delete pGig;
542 delete pRiff;
543 }
544 else
545 #endif
546 for (int iInstrumentNr = 0; iInstrumentNr < QSAMPLER_INSTRUMENT_MAX; iInstrumentNr++)
547 instlist.append(sInstrumentName + " [" + QString::number(iInstrumentNr) + "]");
548 }
549 else instlist.append(noInstrumentName());
550
551 return instlist;
552 }
553
554
555 // Retrieve the spacific instrument name of a instrument file (.gig), given its index.
556 QString qsamplerChannel::getInstrumentName( const QString& sInstrumentFile,
557 int iInstrumentNr, bool bInstrumentNames )
558 {
559 QString sInstrumentName;
560
561 if (isInstrumentFile(sInstrumentFile)) {
562 sInstrumentName = QFileInfo(sInstrumentFile).fileName();
563 #ifdef CONFIG_LIBGIG
564 if (bInstrumentNames) {
565 RIFF::File *pRiff = new RIFF::File(sInstrumentFile);
566 gig::File *pGig = new gig::File(pRiff);
567 int iIndex = 0;
568 gig::Instrument *pInstrument = pGig->GetFirstInstrument();
569 while (pInstrument) {
570 if (iIndex == iInstrumentNr) {
571 sInstrumentName = (pInstrument->pInfo)->Name.c_str();
572 break;
573 }
574 iIndex++;
575 pInstrument = pGig->GetNextInstrument();
576 }
577 delete pGig;
578 delete pRiff;
579 }
580 else
581 #endif
582 sInstrumentName += " [" + QString::number(iInstrumentNr) + "]";
583 }
584 else sInstrumentName = noInstrumentName();
585
586 return sInstrumentName;
587 }
588
589
590 // Common invalid name-helpers.
591 QString qsamplerChannel::noEngineName (void)
592 {
593 return QObject::tr("(No engine)");
594 }
595
596 QString qsamplerChannel::noInstrumentName (void)
597 {
598 return QObject::tr("(No instrument)");
599 }
600
601
602 // end of qsamplerChannel.cpp

  ViewVC Help
Powered by ViewVC