--- linuxsampler/trunk/src/engines/gig/Engine.h 2006/11/27 21:34:55 947 +++ linuxsampler/trunk/src/engines/gig/Engine.h 2008/01/19 16:55:03 1644 @@ -2,8 +2,8 @@ * * * LinuxSampler - modular, streaming capable sampler * * * - * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * - * Copyright (C) 2005, 2006 Christian Schoenebeck * + * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * + * Copyright (C) 2005-2008 Christian Schoenebeck * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -60,6 +60,11 @@ Engine(); virtual ~Engine(); void Connect(AudioOutputDevice* pAudioOut); + ::gig::DimensionRegion** ChangeInstrument(EngineChannel* pEngineChannel, ::gig::Instrument* pInstrument); + void SuspendAll(); + void ResumeAll(); + void Suspend(::gig::Region* pRegion); + void Resume(::gig::Region* pRegion); // implementation of abstract methods derived from class 'LinuxSampler::Engine' virtual int RenderAudio(uint Samples); @@ -79,9 +84,20 @@ virtual String EngineName(); virtual InstrumentManager* GetInstrumentManager(); - static const float* VolumeCurve; ///< Table that maps volume control change values 0..127 to amplitude. Unity gain is at 90. - static const float* PanCurve; ///< Table that maps pan control change values 0..128 to right channel amplitude. Unity gain is at 64 (center). - static const float* CrossfadeCurve; ///< Table that maps crossfade control change values 0..127 to amplitude. Unity gain is at 127. + // Simple array wrapper just to make sure memory is freed + // when liblinuxsampler is unloaded + class FloatTable { + private: + const float* array; + public: + FloatTable(const float* array) : array(array) { } + ~FloatTable() { delete[] array; } + const float& operator[](int i) const { return array[i]; } + }; + + static const FloatTable VolumeCurve; ///< Table that maps volume control change values 0..127 to amplitude. Unity gain is at 90. + static const FloatTable PanCurve; ///< Table that maps pan control change values 0..128 to right channel amplitude. Unity gain is at 64 (center). + static const FloatTable CrossfadeCurve; ///< Table that maps crossfade control change values 0..127 to amplitude. Unity gain is at 127. //protected: static InstrumentResourceManager instruments; @@ -90,13 +106,13 @@ uint SampleRate; ///< Sample rate of the engines output audio signal (in Hz) uint MaxSamplesPerCycle; ///< Size of each audio output buffer DiskThread* pDiskThread; - RingBuffer* pEventQueue; ///< Input event queue for engine global events (e.g. SysEx messages). + RingBuffer* pEventQueue; ///< Input event queue for engine global events (e.g. SysEx messages). Pool* pVoicePool; ///< Contains all voices that can be activated. EventGenerator* pEventGenerator; RTList* pVoiceStealingQueue; ///< All voice-launching events which had to be postponed due to free voice shortage. RTList* pGlobalEvents; ///< All engine global events for the current audio fragment (usually only SysEx messages). Pool* pEventPool; ///< Contains all Event objects that can be used. - RingBuffer* pSysexBuffer; ///< Input buffer for MIDI system exclusive messages. + RingBuffer* pSysexBuffer; ///< Input buffer for MIDI system exclusive messages. int ActiveVoiceCount; ///< number of currently active voices (this value will be returned for public calls) int ActiveVoiceCountTemp; ///< number of currently active voices (for internal usage, will be used for incrementation) int ActiveVoiceCountMax; ///< the maximum voice usage since application start @@ -116,6 +132,7 @@ void ProcessEvents(EngineChannel* pEngineChannel, uint Samples); void RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples); void RenderStolenVoices(uint Samples); + void RouteAudio(EngineChannel* pEngineChannel, uint Samples); void PostProcess(EngineChannel* pEngineChannel); void ClearEventLists(); void ImportEvents(uint Samples); @@ -124,12 +141,15 @@ void ProcessPitchbend(EngineChannel* pEngineChannel, Pool::Iterator& itPitchbendEvent); void ProcessControlChange(EngineChannel* pEngineChannel, Pool::Iterator& itControlChangeEvent); void ProcessSysex(Pool::Iterator& itSysexEvent); + void ProcessSuspensionsChanges(); + void ProcessPendingStreamDeletions(); Pool::Iterator LaunchVoice(EngineChannel* pEngineChannel, Pool::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts); int StealVoice(EngineChannel* pEngineChannel, Pool::Iterator& itNoteOnEvent); void FreeVoice(EngineChannel* pEngineChannel, Pool::Iterator& itVoice); void FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey); void ResetInternal(); void ResetScaleTuning(); + void ResetSuspendedRegions(); static Engine* AcquireEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice); static void FreeEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice); @@ -138,6 +158,27 @@ friend class Voice; private: + + /// Command used by the instrument loader thread to + /// request an instrument change on a channel. + struct instrument_change_command_t { + EngineChannel* pEngineChannel; + ::gig::Instrument* pInstrument; + }; + struct instrument_change_reply_t { + int dummy; + }; + RingBuffer* InstrumentChangeQueue; ///< Contains the instrument change command + RingBuffer* InstrumentChangeReplyQueue; ///< Contains the acknowledge of an instrument change + ::gig::DimensionRegion** pDimRegionsInUse; ///< After an instrument change, this contains a list of dimension regions that are still in use by playing voices + + Pool< ::gig::Region*> SuspendedRegions; + Mutex SuspendedRegionsMutex; + Condition SuspensionChangeOngoing; + ::gig::Region* pPendingRegionSuspension; + ::gig::Region* pPendingRegionResumption; + int iPendingStreamDeletions; + ArrayList engineChannels; ///< All engine channels of a gig::Engine instance. static std::map engines; ///< All instances of gig::Engine. @@ -145,11 +186,12 @@ int SostenutoKeys[128]; int SostenutoKeyCount; - uint8_t GSCheckSum(const RingBuffer::NonVolatileReader AddrReader, uint DataSize); + uint8_t GSCheckSum(const RingBuffer::NonVolatileReader AddrReader, uint DataSize); void AdjustScale(int8_t ScaleTunes[12]); void ReleaseAllVoices(EngineChannel* pEngineChannel, Pool::Iterator& itReleaseEvent); void KillAllVoices(EngineChannel* pEngineChannel, Pool::Iterator& itKillEvent); bool ShouldReleaseVoice(EngineChannel* pEngineChannel, int Key); + bool RegionSuspended(::gig::Region* pRegion); static float* InitVolumeCurve(); static float* InitPanCurve(); static float* InitCrossfadeCurve();