--- linuxsampler/trunk/src/engines/gig/Engine.h 2004/08/22 14:46:47 225 +++ linuxsampler/trunk/src/engines/gig/Engine.h 2004/10/08 20:51:39 271 @@ -29,8 +29,10 @@ # warning Engine.h included #endif // DEBUG_HEADERS +#include + #include "../../common/RingBuffer.h" -#include "../../common/RTELMemoryPool.h" +#include "../../common/Pool.h" #include "../../common/ConditionServer.h" #include "../common/Engine.h" #include "../common/Event.h" @@ -41,9 +43,13 @@ #define PITCHBEND_SEMITONES 12 #define MAX_AUDIO_VOICES 128 +#define SYSEX_BUFFER_SIZE 2048 // 2kB +#define VOICE_STEAL_ALGORITHM voice_steal_algo_oldestkey ///< @see voice_steal_algo_t for available voice stealing algorithms namespace LinuxSampler { namespace gig { + using std::map; + // just symbol prototyping class Voice; class DiskThread; @@ -52,8 +58,15 @@ /** * Sampler engine for the Gigasampler format. */ - class gig::Engine : public LinuxSampler::Engine, public InstrumentConsumer { + class Engine : public LinuxSampler::Engine, public InstrumentConsumer { public: + // types + enum voice_steal_algo_t { + voice_steal_algo_none, + voice_steal_algo_keymask, + voice_steal_algo_oldestkey + }; + // methods Engine(); ~Engine(); @@ -67,6 +80,7 @@ virtual void SendNoteOff(uint8_t Key, uint8_t Velocity); virtual void SendPitchbend(int Pitch); virtual void SendControlChange(uint8_t Controller, uint8_t Value); + virtual void SendSysex(void* pData, uint Size); virtual float Volume(); virtual void Volume(float f); virtual uint Channels(); @@ -94,11 +108,12 @@ virtual void ResourceUpdated(::gig::Instrument* pOldResource, ::gig::Instrument* pNewResource, void* pUpdateArg); protected: struct midi_key_info_t { - RTEList* pActiveVoices; ///< Contains the active voices associated with the MIDI key. - bool KeyPressed; ///< Is true if the respective MIDI key is currently pressed. - bool Active; ///< If the key contains active voices. - uint* pSelf; ///< hack to allow fast deallocation of the key from the list of active keys - RTEList* pEvents; ///< Key specific events (only Note-on, Note-off and sustain pedal currently) + RTList* pActiveVoices; ///< Contains the active voices associated with the MIDI key. + bool KeyPressed; ///< Is true if the respective MIDI key is currently pressed. + bool Active; ///< If the key contains active voices. + bool ReleaseTrigger; ///< If we have to launch release triggered voice(s) when the key is released + Pool::Iterator itSelf; ///< hack to allow fast deallocation of the key from the list of active keys + RTList* pEvents; ///< Key specific events (only Note-on, Note-off and sustain pedal currently) }; static InstrumentResourceManager Instruments; @@ -113,17 +128,20 @@ DiskThread* pDiskThread; uint8_t ControllerTable[128]; ///< Reflects the current values (0-127) of all MIDI controllers for this engine / sampler channel. RingBuffer* pEventQueue; ///< Input event queue. + RingBuffer* pSysexBuffer; ///< Input buffer for MIDI system exclusive messages. midi_key_info_t pMIDIKeyInfo[128]; ///< Contains all active voices sorted by MIDI key number and other informations to the respective MIDI key - RTELMemoryPool* pVoicePool; ///< Contains all voices that can be activated. - RTELMemoryPool* pActiveKeys; ///< Holds all keys in it's allocation list with active voices. - RTELMemoryPool* pEventPool; ///< Contains all Event objects that can be used. + Pool* pVoicePool; ///< Contains all voices that can be activated. + Pool* pActiveKeys; ///< Holds all keys in it's allocation list with active voices. + Pool* pEventPool; ///< Contains all Event objects that can be used. EventGenerator* pEventGenerator; - RTEList* pEvents; ///< All events for the current audio fragment. - RTEList* pCCEvents; ///< All control change events for the current audio fragment. - RTEList* pSynthesisEvents[Event::destination_count]; ///< Events directly affecting synthesis parameter (like pitch, volume and filter). + RTList* pVoiceStealingQueue; ///< All voice-launching events which had to be postponed due to free voice shortage. + RTList* pEvents; ///< All events for the current audio fragment. + RTList* pCCEvents; ///< All control change events for the current audio fragment. + RTList* pSynthesisEvents[Event::destination_count]; ///< Events directly affecting synthesis parameter (like pitch, volume and filter). float* pSynthesisParameters[Event::destination_count]; ///< Matrix with final synthesis parameters for the current audio fragment which will be used in the main synthesis loop. biquad_param_t* pBasicFilterParameters; ///< Biquad parameters of the basic bandpass filter. biquad_param_t* pMainFilterParameters; ///< Main biquad parameters of the individual filter (lowpass / bandpass / highpass). + map ActiveKeyGroups; ///< Contains active keys (in case they belong to a key group) ordered by key group ID. RIFF::File* pRIFF; ::gig::File* pGig; ::gig::Instrument* pInstrument; @@ -137,12 +155,18 @@ String InstrumentFile; int InstrumentIdx; int InstrumentStat; - - void ProcessNoteOn(Event* pNoteOnEvent); - void ProcessNoteOff(Event* pNoteOffEvent); - void ProcessPitchbend(Event* pPitchbendEvent); - void ProcessControlChange(Event* pControlChangeEvent); - void KillVoice(Voice* pVoice); + int8_t ScaleTuning[12]; ///< contains optional detune factors (-64..+63 cents) for all 12 semitones of an octave + RTList::Iterator itLastStolenVoice; ///< Only for voice stealing: points to the last voice which was theft in current audio fragment, NULL otherwise. + RTList::Iterator iuiLastStolenKey; ///< Only for voice stealing: key number of last key on which the last voice was theft in current audio fragment, NULL otherwise. + + void ProcessNoteOn(Pool::Iterator& itNoteOnEvent); + void ProcessNoteOff(Pool::Iterator& itNoteOffEvent); + void ProcessPitchbend(Pool::Iterator& itPitchbendEvent); + void ProcessControlChange(Pool::Iterator& itControlChangeEvent); + void ProcessSysex(Pool::Iterator& itSysexEvent); + Pool::Iterator LaunchVoice(Pool::Iterator& itNoteOnEvent, int iLayer = 0, bool ReleaseTriggerVoice = false, bool VoiceStealing = true); + void StealVoice(Pool::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice); + void KillVoiceImmediately(Pool::Iterator& itVoice); void ResetSynthesisParameters(Event::destination_t dst, float val); void ResetInternal(); @@ -154,7 +178,9 @@ friend class VCOManipulator; friend class InstrumentResourceManager; private: - void DisableAndLock(); + void DisableAndLock(); + uint8_t GSCheckSum(const RingBuffer::NonVolatileReader AddrReader, uint DataSize); + void AdjustScale(int8_t ScaleTunes[12]); }; }} // namespace LinuxSampler::gig