--- linuxsampler/trunk/src/engines/AbstractEngine.h 2009/10/23 17:53:17 2012 +++ linuxsampler/trunk/src/engines/AbstractEngine.h 2016/07/17 17:54:04 2962 @@ -3,8 +3,8 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * - * Copyright (C) 2005-2009 Christian Schoenebeck * - * Copyright (C) 2009 Grigor Iliev * + * Copyright (C) 2005-2008 Christian Schoenebeck * + * Copyright (C) 2009-2013 Christian Schoenebeck and Grigor Iliev * * * * 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 * @@ -31,8 +31,13 @@ #include "../common/ConditionServer.h" #include "../common/Pool.h" #include "../common/RingBuffer.h" +#include "../common/ChangeFlagRelaxed.h" +#include "../common/ResourceManager.h" #include "../drivers/audio/AudioOutputDevice.h" #include "common/Event.h" +#include "common/Note.h" +#include "common/SignalUnitRack.h" +#include "common/InstrumentScriptVM.h" namespace LinuxSampler { @@ -50,19 +55,38 @@ virtual ~AbstractEngine(); // implementation of abstract methods derived from class 'LinuxSampler::Engine' - virtual void SendSysex(void* pData, uint Size, MidiInputPort* pSender); - virtual void Reset(); - virtual void Enable(); - virtual void Disable(); - virtual uint VoiceCount(); - virtual uint VoiceCountMax(); - virtual String EngineName(); + virtual void SendSysex(void* pData, uint Size, MidiInputPort* pSender) OVERRIDE; + virtual void Reset() OVERRIDE; + virtual void Enable() OVERRIDE; + virtual void Disable() OVERRIDE; + virtual uint VoiceCount() OVERRIDE; + virtual uint VoiceCountMax() OVERRIDE; + virtual String EngineName() OVERRIDE; + virtual void AdjustScaleTuning(const int8_t ScaleTunes[12]) OVERRIDE; + virtual void GetScaleTuning(int8_t* pScaleTunes) OVERRIDE; + virtual void ResetScaleTuning() OVERRIDE; virtual Format GetEngineFormat() = 0; virtual void Connect(AudioOutputDevice* pAudioOut) = 0; virtual void DisableAndLock(); - void SetVoiceCount(uint Count);// Simple array wrapper just to make sure memory is freed + void SetVoiceCount(uint Count); + + /** + * Returns event with the given event ID. + */ + RTList::Iterator EventByID(event_id_t id) { + return pEventPool->fromID(id); + } + + virtual NoteBase* NoteByID(note_id_t id) = 0; + + float Random() { + RandomSeed = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator + return RandomSeed / 4294967296.0f; + } + + // Simple array wrapper just to make sure memory is freed // when liblinuxsampler is unloaded class FloatTable { private: @@ -77,31 +101,42 @@ 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. + static float PanCurveValueNorm(float pan, int channel); + AudioOutputDevice* pAudioOutputDevice; + + //TODO: should be protected + AudioChannel* pDedicatedVoiceChannelLeft; ///< encapsulates a special audio rendering buffer (left) for rendering and routing audio on a per voice basis (this is a very special case and only used for voices which lie on a note which was set with individual, dedicated FX send level) + AudioChannel* pDedicatedVoiceChannelRight; ///< encapsulates a special audio rendering buffer (right) for rendering and routing audio on a per voice basis (this is a very special case and only used for voices which lie on a note which was set with individual, dedicated FX send level) + friend class AbstractVoice; friend class AbstractEngineChannel; template friend class EngineChannelBase; + template friend class VoiceBase; - protected: + //protected: ArrayList engineChannels; ///< All engine channels of a Engine instance. ConditionServer EngineDisabled; int8_t ScaleTuning[12]; ///< contains optional detune factors (-64..+63 cents) for all 12 semitones of an octave + ChangeFlagRelaxed ScaleTuningChanged; ///< Boolean flag indicating whenever ScaleTuning has been modified by a foreign thread (i.e. by API). RingBuffer* pEventQueue; ///< Input event queue for engine global events (e.g. SysEx messages). EventGenerator* pEventGenerator; 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. uint SampleRate; ///< Sample rate of the engines output audio signal (in Hz) uint MaxSamplesPerCycle; ///< Size of each audio output buffer - unsigned long FrameTime; ///< Time in frames of the start of the current audio fragment + sched_time_t FrameTime; ///< Scheduler time of the 1st sample point of the current audio fragment cycle. This is a consecutive sample point counter for the engine which proceeds (beyond fragment boundaries) until the engine is explicitly reset for some reason. int ActiveVoiceCountMax; ///< the maximum voice usage since application start - atomic_t ActiveVoiceCount; ///< number of currently active voices + atomic_t ActiveVoiceCount; ///< number of currently active voices + int VoiceSpawnsLeft; ///< We only allow CONFIG_MAX_VOICES voices to be spawned per audio fragment, we use this variable to ensure this limit. + InstrumentScriptVM* pScriptVM; ///< Real-time instrument script virtual machine runner for this engine. void RouteAudio(EngineChannel* pEngineChannel, uint Samples); + void RouteDedicatedVoiceChannels(EngineChannel* pEngineChannel, optional FxSendLevels[2], uint Samples); void ClearEventLists(); void ImportEvents(uint Samples); void ProcessSysex(Pool::Iterator& itSysexEvent); - void ResetScaleTuning(); void ProcessPitchbend(AbstractEngineChannel* pEngineChannel, Pool::Iterator& itPitchbendEvent); void ProcessFxSendControllers ( @@ -116,16 +151,23 @@ virtual void ProcessNoteOn(EngineChannel* pEngineChannel, Pool::Iterator& itNoteOnEvent) = 0; virtual void ProcessNoteOff(EngineChannel* pEngineChannel, Pool::Iterator& itNoteOffEvent) = 0; virtual void ProcessControlChange(EngineChannel* pEngineChannel, Pool::Iterator& itControlChangeEvent) = 0; + virtual void ProcessChannelPressure(EngineChannel* pEngineChannel, Pool::Iterator& itChannelPressureEvent) = 0; + virtual void ProcessPolyphonicKeyPressure(EngineChannel* pEngineChannel, Pool::Iterator& itNotePressureEvent) = 0; + virtual void ProcessReleaseTrigger(EngineChannel* pEngineChannel, RTList::Iterator& itEvent) = 0; + virtual int GetMinFadeOutSamples() = 0; + virtual note_id_t LaunchNewNote(LinuxSampler::EngineChannel* pEngineChannel, Event* pNoteOnEvent) = 0; + virtual void CreateInstrumentScriptVM(); private: static std::map > engines; + uint32_t RandomSeed; ///< State of the random number generator used by the random dimension. static float* InitVolumeCurve(); static float* InitPanCurve(); static float* InitCrossfadeCurve(); static float* InitCurve(const float* segments, int size = 128); - void AdjustScale(int8_t ScaleTunes[12]); + bool RouteFxSend(FxSend* pFxSend, AudioChannel* ppSource[2], float FxSendLevel, uint Samples); }; } // namespace LinuxSampler