--- linuxsampler/trunk/src/engines/gig/EngineChannel.h 2005/02/26 22:44:51 412 +++ linuxsampler/trunk/src/engines/gig/EngineChannel.h 2008/04/20 08:53:39 1723 @@ -3,7 +3,7 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * - * Copyright (C) 2005 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 * @@ -24,12 +24,11 @@ #ifndef __LS_GIG_ENGINECHANNEL_H__ #define __LS_GIG_ENGINECHANNEL_H__ -#if DEBUG_HEADERS -# warning EngineChannel.h included -#endif // DEBUG_HEADERS - #include "../common/Event.h" -#include "../common/EngineChannel.h" +#include "../EngineChannel.h" +#include "../../common/RingBuffer.h" +#include "../../common/ArrayList.h" +#include "../../drivers/audio/AudioChannel.h" #include "EngineGlobals.h" #include "Engine.h" #include "Voice.h" @@ -41,64 +40,127 @@ class midi_key_info_t; class Voice; + /** @brief Engine Channel of a gig::Engine + * + * Encapsulates a engine channel for the Gigasampler format capable + * sampler engine. + */ class EngineChannel : public LinuxSampler::EngineChannel, public InstrumentConsumer { public: EngineChannel(); - virtual ~EngineChannel(); - + virtual ~EngineChannel(); + // implementation of abstract methods derived from interface class 'LinuxSampler::EngineChannel' virtual void PrepareLoadInstrument(const char* FileName, uint Instrument); virtual void LoadInstrument(); + virtual void Reset(); virtual void SendNoteOn(uint8_t Key, uint8_t Velocity); + virtual void SendNoteOn(uint8_t Key, uint8_t Velocity, int32_t FragmentPos); virtual void SendNoteOff(uint8_t Key, uint8_t Velocity); + virtual void SendNoteOff(uint8_t Key, uint8_t Velocity, int32_t FragmentPos); virtual void SendPitchbend(int Pitch); - virtual void SendControlChange(uint8_t Controller, uint8_t Value); + virtual void SendPitchbend(int Pitch, int32_t FragmentPos); + virtual void SendControlChange(uint8_t Controller, uint8_t Value); + virtual void SendControlChange(uint8_t Controller, uint8_t Value, int32_t FragmentPos); + virtual bool StatusChanged(bool bNewStatus = false); virtual float Volume(); virtual void Volume(float f); + virtual float Pan(); + virtual void Pan(float f); virtual uint Channels(); virtual void Connect(AudioOutputDevice* pAudioOut); virtual void DisconnectAudioOutputDevice(); + virtual AudioOutputDevice* GetAudioOutputDevice(); virtual void SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel); virtual int OutputChannel(uint EngineAudioChannel); + virtual void Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel); + virtual void DisconnectMidiInputPort(); + virtual MidiInputPort* GetMidiInputPort(); + virtual midi_chan_t MidiChannel(); virtual String InstrumentFileName(); virtual String InstrumentName(); virtual int InstrumentIndex(); virtual int InstrumentStatus(); - virtual LinuxSampler::Engine* GetEngine(); + virtual LinuxSampler::Engine* GetEngine(); + virtual String EngineName(); + virtual FxSend* AddFxSend(uint8_t MidiCtrl, String Name = "") throw (Exception); + virtual FxSend* GetFxSend(uint FxSendIndex); + virtual uint GetFxSendCount(); + virtual void RemoveFxSend(FxSend* pFxSend); + virtual void Connect(VirtualMidiDevice* pDevice); + virtual void Disconnect(VirtualMidiDevice* pDevice); // implementation of abstract methods derived from interface class 'InstrumentConsumer' virtual void ResourceToBeUpdated(::gig::Instrument* pResource, void*& pUpdateArg); virtual void ResourceUpdated(::gig::Instrument* pOldResource, ::gig::Instrument* pNewResource, void* pUpdateArg); - - //protected: + virtual void OnResourceProgress(float fProgress); + + //protected: Engine* pEngine; - float* pOutputLeft; ///< Audio output channel buffer (left) - float* pOutputRight; ///< Audio output channel buffer (right) + AudioChannel* pChannelLeft; ///< encapsulates the audio rendering buffer (left) + AudioChannel* pChannelRight; ///< encapsulates the audio rendering buffer (right) int AudioDeviceChannelLeft; ///< audio device channel number to which the left channel is connected to int AudioDeviceChannelRight; ///< audio device channel number to which the right channel is connected to - RingBuffer* pEventQueue; ///< Input event queue. - uint8_t ControllerTable[128]; ///< Reflects the current values (0-127) of all MIDI controllers for this engine / sampler channel. + MidiInputPort* pMidiInputPort; ///< Points to the connected MIDI input port or NULL if none assigned. + midi_chan_t midiChannel; ///< MIDI channel(s) on which this engine channel listens to. + RingBuffer* pEventQueue; ///< Input event queue. + RTList* pEvents; ///< All engine channel specific events for the current audio fragment. + uint8_t ControllerTable[129]; ///< Reflects the current values (0-127) of all MIDI controllers for this engine / sampler channel. Number 128 is for channel pressure (mono aftertouch). midi_key_info_t* pMIDIKeyInfo; ///< Contains all active voices sorted by MIDI key number and other informations to the respective MIDI key - Pool* pActiveKeys; ///< Holds all keys in it's allocation list with active voices. + Pool* pActiveKeys; ///< Holds all keys in it's allocation list with active voices. std::map ActiveKeyGroups; ///< Contains active keys (in case they belong to a key group) ordered by key group ID. ::gig::Instrument* pInstrument; bool SustainPedal; ///< true if sustain pedal is down - double GlobalVolume; ///< overall volume (a value < 1.0 means attenuation, a value > 1.0 means amplification) + bool SostenutoPedal; ///< true if sostenuto pedal is down + bool SoloMode; ///< in Solo Mode we only play one voice (group) at a time + int SoloKey; ///< Currently 'active' solo key, that is the key to which the currently sounding voice belongs to (only if SoloMode is enabled) + bool PortamentoMode; ///< in Portamento Mode we slide the pitch from the last note to the current note. + float PortamentoTime; ///< How long it will take to glide from the previous note to the current (in seconds) + float PortamentoPos; ///< Current position on the keyboard, that is integer and fractional part (only used if PortamentoMode is on) + double GlobalVolume; ///< Master volume factor set through the C++ API / LSCP (a value < 1.0 means attenuation, a value > 1.0 means amplification) + double MidiVolume; ///< Volume factor altered by MIDI CC#7 (a value < 1.0 means attenuation, a value > 1.0 means amplification) + float GlobalPanLeft; + float GlobalPanRight; int Pitch; ///< Current (absolute) MIDI pitch value. - int CurrentKeyDimension; ///< Current value (0-127) for the keyboard dimension, altered by pressing a keyswitching key. + float CurrentKeyDimension; ///< Current value (0-1.0) for the keyboard dimension, altered by pressing a keyswitching key. String InstrumentFile; int InstrumentIdx; String InstrumentIdxName; int InstrumentStat; - 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. + int iEngineIndexSelf; ///< Reflects the index of this EngineChannel in the Engine's ArrayList. + bool bStatusChanged; ///< true in case an engine parameter has changed (e.g. new instrument, another volumet) + std::vector fxSends; + int GlobalTranspose; ///< amount of semi tones all notes should be transposed + int iLastPanRequest; ///< just for the return value of Pan(), so we don't have to make an injective function + + /// Command used by the instrument loader thread to + /// request an instrument change on a channel. + struct instrument_change_command_t { + bool bChangeInstrument; ///< Set to true by the loader when the channel should change instrument. + ::gig::Instrument* pInstrument; ///< The new instrument. Also used by the loader to read the previously loaded instrument. + RTList< ::gig::DimensionRegion*>* pDimRegionsInUse; ///< List of dimension regions in use by the currently loaded instrument. Continuously updated by the audio thread. + }; + SynchronizedConfig InstrumentChangeCommand; + SynchronizedConfig::Reader InstrumentChangeCommandReader; + + RTList< ::gig::DimensionRegion*>* pDimRegionsInUse; ///< temporary pointer into the instrument change command, used by the audio thread + + SynchronizedConfig< ArrayList > virtualMidiDevices; + SynchronizedConfig< ArrayList >::Reader virtualMidiDevicesReader_AudioThread; + SynchronizedConfig< ArrayList >::Reader virtualMidiDevicesReader_MidiThread; + + void ResetControllers(); + void ClearEventLists(); + void ImportEvents(uint Samples); friend class Engine; friend class Voice; friend class InstrumentResourceManager; - + private: void ResetInternal(); + void RemoveAllFxSends(); + instrument_change_command_t& ChangeInstrument(::gig::Instrument* pInstrument); }; }} // namespace LinuxSampler::gig