/[svn]/linuxsampler/trunk/src/engines/gig/Engine.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/Engine.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1012 by capela, Sun Jan 7 15:52:36 2007 UTC revision 1297 by iliev, Thu Aug 16 15:55:21 2007 UTC
# Line 51  namespace LinuxSampler { namespace gig { Line 51  namespace LinuxSampler { namespace gig {
51          if (engines.count(pDevice)) {          if (engines.count(pDevice)) {
52              dmsg(4,("Using existing gig::Engine.\n"));              dmsg(4,("Using existing gig::Engine.\n"));
53              pEngine = engines[pDevice];              pEngine = engines[pDevice];
54    
55                // Disable the engine while the new engine channel is
56                // added and initialized. The engine will be enabled again
57                // in EngineChannel::Connect.
58                pEngine->DisableAndLock();
59          } else { // create a new engine (and disk thread) instance for the given audio output device          } else { // create a new engine (and disk thread) instance for the given audio output device
60              dmsg(4,("Creating new gig::Engine.\n"));              dmsg(4,("Creating new gig::Engine.\n"));
61              pEngine = (Engine*) EngineFactory::Create("gig");              pEngine = (Engine*) EngineFactory::Create("gig");
# Line 101  namespace LinuxSampler { namespace gig { Line 106  namespace LinuxSampler { namespace gig {
106          pEventQueue        = new RingBuffer<Event,false>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);          pEventQueue        = new RingBuffer<Event,false>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);
107          pEventPool         = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);          pEventPool         = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);
108          pVoicePool         = new Pool<Voice>(CONFIG_MAX_VOICES);          pVoicePool         = new Pool<Voice>(CONFIG_MAX_VOICES);
109            pDimRegionsInUse   = new ::gig::DimensionRegion*[CONFIG_MAX_VOICES + 1];
110          pVoiceStealingQueue = new RTList<Event>(pEventPool);          pVoiceStealingQueue = new RTList<Event>(pEventPool);
111          pGlobalEvents      = new RTList<Event>(pEventPool);          pGlobalEvents      = new RTList<Event>(pEventPool);
112            InstrumentChangeQueue      = new RingBuffer<instrument_change_command_t,false>(1, 0);
113            InstrumentChangeReplyQueue = new RingBuffer<instrument_change_reply_t,false>(1, 0);
114    
115          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
116              iterVoice->SetEngine(this);              iterVoice->SetEngine(this);
117          }          }
# Line 132  namespace LinuxSampler { namespace gig { Line 141  namespace LinuxSampler { namespace gig {
141          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
142          if (pVoiceStealingQueue) delete pVoiceStealingQueue;          if (pVoiceStealingQueue) delete pVoiceStealingQueue;
143          if (pSysexBuffer) delete pSysexBuffer;          if (pSysexBuffer) delete pSysexBuffer;
144            if (pGlobalEvents) delete pGlobalEvents;
145            if (InstrumentChangeQueue) delete InstrumentChangeQueue;
146            if (InstrumentChangeReplyQueue) delete InstrumentChangeReplyQueue;
147            if (pDimRegionsInUse) delete[] pDimRegionsInUse;
148          Unregister();          Unregister();
149      }      }
150    
# Line 257  namespace LinuxSampler { namespace gig { Line 270  namespace LinuxSampler { namespace gig {
270              delete this->pDiskThread;              delete this->pDiskThread;
271              dmsg(1,("OK\n"));              dmsg(1,("OK\n"));
272          }          }
273          this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6); //FIXME: assuming stereo          this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
274                                               &instruments);
275          if (!pDiskThread) {          if (!pDiskThread) {
276              dmsg(0,("gig::Engine  new diskthread = NULL\n"));              dmsg(0,("gig::Engine  new diskthread = NULL\n"));
277              exit(EXIT_FAILURE);              exit(EXIT_FAILURE);
# Line 377  namespace LinuxSampler { namespace gig { Line 391  namespace LinuxSampler { namespace gig {
391          // reset internal voice counter (just for statistic of active voices)          // reset internal voice counter (just for statistic of active voices)
392          ActiveVoiceCountTemp = 0;          ActiveVoiceCountTemp = 0;
393    
394            // handle instrument change commands
395            instrument_change_command_t command;
396            if (InstrumentChangeQueue->pop(&command) > 0) {
397                EngineChannel* pEngineChannel = command.pEngineChannel;
398                pEngineChannel->pInstrument = command.pInstrument;
399    
400                // iterate through all active voices and mark their
401                // dimension regions as "in use". The instrument resource
402                // manager may delete all of the instrument except the
403                // dimension regions and samples that are in use.
404                int i = 0;
405                RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
406                RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
407                while (iuiKey != end) { // iterate through all active keys
408                    midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
409                    ++iuiKey;
410    
411                    RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
412                    RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
413                    for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
414                        if (!itVoice->Orphan) {
415                            itVoice->Orphan = true;
416                            pDimRegionsInUse[i++] = itVoice->pDimRgn;
417                        }
418                    }
419                }
420                pDimRegionsInUse[i] = 0; // end of list
421    
422                // send a reply to the calling thread, which is waiting
423                instrument_change_reply_t reply;
424                InstrumentChangeReplyQueue->push(&reply);
425            }
426    
427          // handle events on all engine channels          // handle events on all engine channels
428          for (int i = 0; i < engineChannels.size(); i++) {          for (int i = 0; i < engineChannels.size(); i++) {
             if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded  
429              ProcessEvents(engineChannels[i], Samples);              ProcessEvents(engineChannels[i], Samples);
430          }          }
431    
432          // render all 'normal', active voices on all engine channels          // render all 'normal', active voices on all engine channels
433          for (int i = 0; i < engineChannels.size(); i++) {          for (int i = 0; i < engineChannels.size(); i++) {
             if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded  
434              RenderActiveVoices(engineChannels[i], Samples);              RenderActiveVoices(engineChannels[i], Samples);
435          }          }
436    
# Line 400  namespace LinuxSampler { namespace gig { Line 445  namespace LinuxSampler { namespace gig {
445    
446          // handle cleanup on all engine channels for the next audio fragment          // handle cleanup on all engine channels for the next audio fragment
447          for (int i = 0; i < engineChannels.size(); i++) {          for (int i = 0; i < engineChannels.size(); i++) {
             if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded  
448              PostProcess(engineChannels[i]);              PostProcess(engineChannels[i]);
449          }          }
450    
# Line 482  namespace LinuxSampler { namespace gig { Line 526  namespace LinuxSampler { namespace gig {
526          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
527          #endif          #endif
528    
529            uint vc = 0;
530            uint sc = 0;
531          RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();          RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
532          RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();          RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
533          while (iuiKey != end) { // iterate through all active keys          while (iuiKey != end) { // iterate through all active keys
# Line 493  namespace LinuxSampler { namespace gig { Line 539  namespace LinuxSampler { namespace gig {
539              for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key              for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
540                  // now render current voice                  // now render current voice
541                  itVoice->Render(Samples);                  itVoice->Render(Samples);
542                  if (itVoice->IsActive()) ActiveVoiceCountTemp++; // still active                  if (itVoice->IsActive()) { // still active
543                  else { // voice reached end, is now inactive                      ActiveVoiceCountTemp++;
544                        vc++;
545    
546                        if (itVoice->PlaybackState == Voice::playback_state_disk) {
547                            if ((itVoice->DiskStreamRef).State == Stream::state_active) sc++;
548                        }
549                    }  else { // voice reached end, is now inactive
550                      FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices                      FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
551                  }                  }
552              }              }
553          }          }
554            
555            pEngineChannel->SetVoiceCount(vc);
556            pEngineChannel->SetDiskStreamCount(sc);
557      }      }
558    
559      /**      /**
# Line 519  namespace LinuxSampler { namespace gig { Line 574  namespace LinuxSampler { namespace gig {
574          RTList<Event>::Iterator end               = pVoiceStealingQueue->end();          RTList<Event>::Iterator end               = pVoiceStealingQueue->end();
575          for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {          for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
576              EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;              EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
577                if (!pEngineChannel->pInstrument) continue; // ignore if no instrument loaded
578              Pool<Voice>::Iterator itNewVoice =              Pool<Voice>::Iterator itNewVoice =
579                  LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);                  LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
580              if (itNewVoice) {              if (itNewVoice) {
581                  itNewVoice->Render(Samples);                  itNewVoice->Render(Samples);
582                  if (itNewVoice->IsActive()) ActiveVoiceCountTemp++; // still active                  if (itNewVoice->IsActive()) { // still active
583                  else { // voice reached end, is now inactive                      ActiveVoiceCountTemp++;
584                        pEngineChannel->SetVoiceCount(pEngineChannel->GetVoiceCount() + 1);
585    
586                        if (itNewVoice->PlaybackState == Voice::playback_state_disk) {
587                            if (itNewVoice->DiskStreamRef.State == Stream::state_active) {
588                                pEngineChannel->SetDiskStreamCount(pEngineChannel->GetDiskStreamCount() + 1);
589                            }
590                        }
591                    } else { // voice reached end, is now inactive
592                      FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices                      FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
593                  }                  }
594              }              }
# Line 555  namespace LinuxSampler { namespace gig { Line 619  namespace LinuxSampler { namespace gig {
619          {          {
620              AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);              AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);
621              AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);              AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);
622              pEngineChannel->pChannelLeft->CopyTo(pDstL, Samples);              pEngineChannel->pChannelLeft->MixTo(pDstL, Samples);
623              pEngineChannel->pChannelRight->CopyTo(pDstR, Samples);              pEngineChannel->pChannelRight->MixTo(pDstR, Samples);
624          }          }
625          // route FX send signal          // route FX send signal
626          {          {
# Line 570  namespace LinuxSampler { namespace gig { Line 634  namespace LinuxSampler { namespace gig {
634                      AudioChannel* pDstL = pAudioOutputDevice->Channel(iDstL);                      AudioChannel* pDstL = pAudioOutputDevice->Channel(iDstL);
635                      if (!pDstL) {                      if (!pDstL) {
636                          dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));                          dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
637                      } else pEngineChannel->pChannelLeft->CopyTo(pDstL, Samples, pFxSend->Level());                      } else pEngineChannel->pChannelLeft->MixTo(pDstL, Samples, pFxSend->Level());
638                  }                  }
639                  // right channel                  // right channel
640                  const int iDstR = pFxSend->DestinationChannel(1);                  const int iDstR = pFxSend->DestinationChannel(1);
# Line 580  namespace LinuxSampler { namespace gig { Line 644  namespace LinuxSampler { namespace gig {
644                      AudioChannel* pDstR = pAudioOutputDevice->Channel(iDstR);                      AudioChannel* pDstR = pAudioOutputDevice->Channel(iDstR);
645                      if (!pDstR) {                      if (!pDstR) {
646                          dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));                          dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
647                      } else pEngineChannel->pChannelRight->CopyTo(pDstR, Samples, pFxSend->Level());                      } else pEngineChannel->pChannelRight->MixTo(pDstR, Samples, pFxSend->Level());
648                  }                  }
649              }              }
650          }          }
# Line 666  namespace LinuxSampler { namespace gig { Line 730  namespace LinuxSampler { namespace gig {
730          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
731          #endif          #endif
732    
733            if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded
734    
735            //HACK: we should better add the transpose value only to the most mandatory places (like for retrieving the region and calculating the tuning), because otherwise voices will unintendedly survive when changing transpose while playing
736            itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
737    
738          const int key = itNoteOnEvent->Param.Note.Key;          const int key = itNoteOnEvent->Param.Note.Key;
739          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
740    
# Line 753  namespace LinuxSampler { namespace gig { Line 822  namespace LinuxSampler { namespace gig {
822          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
823          #endif          #endif
824    
825            //HACK: we should better add the transpose value only to the most mandatory places (like for retrieving the region and calculating the tuning), because otherwise voices will unintendedly survive when changing transpose while playing
826            itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
827    
828          const int iKey = itNoteOffEvent->Param.Note.Key;          const int iKey = itNoteOffEvent->Param.Note.Key;
829          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];
830          pKey->KeyPressed = false; // the MIDI key was now released          pKey->KeyPressed = false; // the MIDI key was now released
# Line 763  namespace LinuxSampler { namespace gig { Line 835  namespace LinuxSampler { namespace gig {
835          bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);          bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);
836    
837          // in case Solo Mode is enabled, kill all voices on this key and respawn a voice on the highest pressed key (if any)          // in case Solo Mode is enabled, kill all voices on this key and respawn a voice on the highest pressed key (if any)
838          if (pEngineChannel->SoloMode) { //TODO: this feels like too much code just for handling solo mode :P          if (pEngineChannel->SoloMode && pEngineChannel->pInstrument) { //TODO: this feels like too much code just for handling solo mode :P
839              bool bOtherKeysPressed = false;              bool bOtherKeysPressed = false;
840              if (iKey == pEngineChannel->SoloKey) {              if (iKey == pEngineChannel->SoloKey) {
841                  pEngineChannel->SoloKey = -1;                  pEngineChannel->SoloKey = -1;
# Line 826  namespace LinuxSampler { namespace gig { Line 898  namespace LinuxSampler { namespace gig {
898              itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type              itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type
899    
900              // spawn release triggered voice(s) if needed              // spawn release triggered voice(s) if needed
901              if (pKey->ReleaseTrigger) {              if (pKey->ReleaseTrigger && pEngineChannel->pInstrument) {
902                  // first, get total amount of required voices (dependant on amount of layers)                  // first, get total amount of required voices (dependant on amount of layers)
903                  ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);                  ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
904                  if (pRegion) {                  if (pRegion) {
# Line 1021  namespace LinuxSampler { namespace gig { Line 1093  namespace LinuxSampler { namespace gig {
1093                      std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;                      std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
1094              }              }
1095          }          }
1096    
1097            // return if this is a release triggered voice and there is no
1098            // releasetrigger dimension (could happen if an instrument
1099            // change has occured between note on and off)
1100            if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
1101    
1102          ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);          ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
1103    
1104          // no need to continue if sample is silent          // no need to continue if sample is silent
# Line 1250  namespace LinuxSampler { namespace gig { Line 1328  namespace LinuxSampler { namespace gig {
1328    
1329              uint keygroup = itVoice->KeyGroup;              uint keygroup = itVoice->KeyGroup;
1330    
1331                // if the sample and dimension region belong to an
1332                // instrument that is unloaded, tell the disk thread to
1333                // release them
1334                if (itVoice->Orphan) {
1335                    pDiskThread->OrderDeletionOfDimreg(itVoice->pDimRgn);
1336                }
1337    
1338              // free the voice object              // free the voice object
1339              pVoicePool->free(itVoice);              pVoicePool->free(itVoice);
1340    
# Line 1300  namespace LinuxSampler { namespace gig { Line 1385  namespace LinuxSampler { namespace gig {
1385                  pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;                  pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1386                  break;                  break;
1387              }              }
1388                case 6: { // data entry (currently only used for RPN controllers)
1389                    if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones
1390                        int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;
1391                        // limit to +- two octaves for now
1392                        transpose = RTMath::Min(transpose,  24);
1393                        transpose = RTMath::Max(transpose, -24);
1394                        pEngineChannel->GlobalTranspose = transpose;
1395                        // workaround, so we won't have hanging notes
1396                        ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1397                    }
1398                    // to avoid other MIDI CC #6 messages to be misenterpreted as RPN controller data
1399                    pEngineChannel->ResetMidiRpnController();
1400                    break;
1401                }
1402              case 7: { // volume              case 7: { // volume
1403                  //TODO: not sample accurate yet                  //TODO: not sample accurate yet
1404                  pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];                  pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];
# Line 1404  namespace LinuxSampler { namespace gig { Line 1503  namespace LinuxSampler { namespace gig {
1503                  }                  }
1504                  break;                  break;
1505              }              }
1506                case 100: { // RPN controller LSB
1507                    pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);
1508                    break;
1509                }
1510                case 101: { // RPN controller MSB
1511                    pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);
1512                    break;
1513                }
1514    
1515    
1516              // Channel Mode Messages              // Channel Mode Messages
# Line 1440  namespace LinuxSampler { namespace gig { Line 1547  namespace LinuxSampler { namespace gig {
1547                  FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);                  FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
1548                  if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller)                  if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller)
1549                      pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);                      pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);
1550                        pFxSend->SetInfoChanged(true);
1551              }              }
1552          }          }
1553      }      }
# Line 1636  namespace LinuxSampler { namespace gig { Line 1744  namespace LinuxSampler { namespace gig {
1744      }      }
1745    
1746      String Engine::Version() {      String Engine::Version() {
1747          String s = "$Revision: 1.69 $";          String s = "$Revision: 1.78 $";
1748          return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword          return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
1749      }      }
1750    
# Line 1686  namespace LinuxSampler { namespace gig { Line 1794  namespace LinuxSampler { namespace gig {
1794          return y;          return y;
1795      }      }
1796    
1797        /**
1798         * Changes the instrument for an engine channel.
1799         *
1800         * @param pEngineChannel - engine channel on which the instrument
1801         *                         should be changed
1802         * @param pInstrument - new instrument
1803         * @returns a list of dimension regions from the old instrument
1804         *          that are still in use
1805         */
1806        ::gig::DimensionRegion** Engine::ChangeInstrument(EngineChannel* pEngineChannel, ::gig::Instrument* pInstrument) {
1807            instrument_change_command_t command;
1808            command.pEngineChannel = pEngineChannel;
1809            command.pInstrument = pInstrument;
1810            InstrumentChangeQueue->push(&command);
1811    
1812            // wait for the audio thread to confirm that the instrument
1813            // change has been done
1814            instrument_change_reply_t reply;
1815            while (InstrumentChangeReplyQueue->pop(&reply) == 0) {
1816                usleep(10000);
1817            }
1818            return pDimRegionsInUse;
1819        }
1820    
1821  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.1012  
changed lines
  Added in v.1297

  ViewVC Help
Powered by ViewVC