/[svn]/linuxsampler/trunk/src/engines/AbstractEngineChannel.h
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/AbstractEngineChannel.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2598 - (hide annotations) (download) (as text)
Fri Jun 6 12:38:54 2014 UTC (9 years, 10 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 15172 byte(s)
* ScriptVM (WIP): Built-in script function "play_note()" now returns the
  event ID of the triggered note.
* ScriptVM (WIP): Implemented built-in script int variable $EVENT_ID.
* ScriptVM (WIP): Implemented built-in script function "ignore_event()".
* ScriptVM (WIP): Implemented built-in script function
  "ignore_controller()" (accepts one and no argument).
* Bumped version (1.0.0.svn44).

1 iliev 2012 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6 persson 2114 * Copyright (C) 2005-2008 Christian Schoenebeck *
7 persson 2317 * Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev *
8 schoenebeck 2500 * Copyright (C) 2013-2014 Christian Schoenebeck and Andreas Persson *
9 iliev 2012 * *
10     * This program is free software; you can redistribute it and/or modify *
11     * it under the terms of the GNU General Public License as published by *
12     * the Free Software Foundation; either version 2 of the License, or *
13     * (at your option) any later version. *
14     * *
15     * This program is distributed in the hope that it will be useful, *
16     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18     * GNU General Public License for more details. *
19     * *
20     * You should have received a copy of the GNU General Public License *
21     * along with this program; if not, write to the Free Software *
22     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
23     * MA 02111-1307 USA *
24     ***************************************************************************/
25    
26     #ifndef __LS_ABSTRACTENGINECHANNEL_H__
27 persson 2114 #define __LS_ABSTRACTENGINECHANNEL_H__
28 iliev 2012
29     #include "EngineChannel.h"
30     #include "AbstractEngine.h"
31    
32     #include "../common/Pool.h"
33     #include "../common/RingBuffer.h"
34    
35 schoenebeck 2594 #define CTRL_TABLE_IDX_AFTERTOUCH 128
36     #define CTRL_TABLE_IDX_PITCHBEND 129
37    
38 iliev 2012 namespace LinuxSampler {
39    
40 schoenebeck 2594 class AbstractEngineChannel: public EngineChannel, public AbstractEngine::ScriptConsumer {
41 iliev 2012 public:
42     // implementation of abstract methods derived from interface class 'LinuxSampler::EngineChannel'
43 schoenebeck 2434 virtual void PrepareLoadInstrument(const char* FileName, uint Instrument) OVERRIDE;
44     virtual void Reset() OVERRIDE;
45     virtual void SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) OVERRIDE;
46     virtual void SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel, int32_t FragmentPos) OVERRIDE;
47     virtual void SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) OVERRIDE;
48     virtual void SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel, int32_t FragmentPos) OVERRIDE;
49     virtual void SendPitchbend(int Pitch, uint8_t MidiChannel) OVERRIDE;
50     virtual void SendPitchbend(int Pitch, uint8_t MidiChannel, int32_t FragmentPos) OVERRIDE;
51     virtual void SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) OVERRIDE;
52 schoenebeck 2559 virtual void SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) OVERRIDE;
53     virtual void SendChannelPressure(uint8_t Value, uint8_t MidiChannel) OVERRIDE;
54     virtual void SendChannelPressure(uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) OVERRIDE;
55     virtual void SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel) OVERRIDE;
56     virtual void SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) OVERRIDE;
57 schoenebeck 2434 virtual bool StatusChanged(bool bNewStatus = false) OVERRIDE;
58     virtual float Volume() OVERRIDE;
59     virtual void Volume(float f) OVERRIDE;
60     virtual float Pan() OVERRIDE;
61     virtual void Pan(float f) OVERRIDE;
62     virtual uint Channels() OVERRIDE;
63     virtual AudioOutputDevice* GetAudioOutputDevice() OVERRIDE;
64     virtual void SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) OVERRIDE;
65     virtual int OutputChannel(uint EngineAudioChannel) OVERRIDE;
66 schoenebeck 2500 virtual void Connect(MidiInputPort* pMidiPort) OVERRIDE;
67     virtual void Disconnect(MidiInputPort* pMidiPort) OVERRIDE;
68     virtual void DisconnectAllMidiInputPorts() OVERRIDE;
69     virtual uint GetMidiInputPortCount() OVERRIDE;
70     virtual MidiInputPort* GetMidiInputPort(uint index) OVERRIDE;
71 schoenebeck 2434 virtual midi_chan_t MidiChannel() OVERRIDE;
72 schoenebeck 2500 virtual void SetMidiChannel(midi_chan_t MidiChannel) OVERRIDE;
73     virtual void Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) OVERRIDE; // deprecated, may be removed
74     virtual void DisconnectMidiInputPort() OVERRIDE; // deprecated, may be removed
75     virtual MidiInputPort* GetMidiInputPort() OVERRIDE; // deprecated, may be removed
76 schoenebeck 2434 virtual String InstrumentFileName() OVERRIDE;
77     virtual String InstrumentName() OVERRIDE;
78     virtual int InstrumentIndex() OVERRIDE;
79     virtual int InstrumentStatus() OVERRIDE;
80     virtual Engine* GetEngine() OVERRIDE;
81     virtual String EngineName() OVERRIDE;
82     virtual FxSend* AddFxSend(uint8_t MidiCtrl, String Name = "") throw (Exception) OVERRIDE;
83     virtual FxSend* GetFxSend(uint FxSendIndex) OVERRIDE;
84     virtual uint GetFxSendCount() OVERRIDE;
85     virtual void RemoveFxSend(FxSend* pFxSend) OVERRIDE;
86     virtual void Connect(VirtualMidiDevice* pDevice) OVERRIDE;
87     virtual void Disconnect(VirtualMidiDevice* pDevice) OVERRIDE;
88 iliev 2012
89 schoenebeck 2594 // implementation of abstract methods derived from AbstractEngine::ScriptConsumer
90     virtual void ResourceToBeUpdated(VMParserContext* pResource, void*& pUpdateArg) OVERRIDE {}
91     virtual void ResourceUpdated(VMParserContext* pOldResource, VMParserContext* pNewResource, void* pUpdateArg) OVERRIDE {}
92     virtual void OnResourceProgress(float fProgress) OVERRIDE {}
93 iliev 2012
94     virtual AbstractEngine::Format GetEngineFormat() = 0;
95    
96 persson 2326 AudioOutputDevice* GetAudioOutputDeviceSafe();
97 schoenebeck 2594 void loadInstrumentScript(const String& text);
98     void unloadCurrentInstrumentScript();
99 persson 2326
100 iliev 2015 friend class AbstractVoice;
101 iliev 2012 friend class AbstractEngine;
102     template<class TV, class TRR, class TR, class TD, class TIM, class TI> friend class EngineBase;
103 iliev 2015 template<class EC, class R, class S, class D> friend class VoiceBase;
104 iliev 2012
105 schoenebeck 2594 //protected:
106 iliev 2012 AbstractEngineChannel();
107     virtual ~AbstractEngineChannel();
108    
109     AbstractEngine* pEngine;
110 persson 2326 Mutex EngineMutex; ///< protects the Engine from access by the instrument loader thread when lscp is disconnecting
111 schoenebeck 2500 Mutex MidiInputMutex; ///< Introduced when support for multiple MIDI inputs per engine channel was added: protects the MIDI event input ringbuffer on this engine channel to be accessed concurrently by multiple midi input threads. As alternative one might also move the ringbuffer from this engine channel to the individual MIDI ports/devices and let the sampler engine read the events from there instead of receiving them here.
112 persson 2326
113 schoenebeck 2594 //protected:
114 iliev 2012 AudioChannel* pChannelLeft; ///< encapsulates the audio rendering buffer (left)
115     AudioChannel* pChannelRight; ///< encapsulates the audio rendering buffer (right)
116     int AudioDeviceChannelLeft; ///< audio device channel number to which the left channel is connected to
117     int AudioDeviceChannelRight; ///< audio device channel number to which the right channel is connected to
118 schoenebeck 2500 DoubleBuffer< ArrayList<MidiInputPort*> > midiInputs; ///< MIDI input ports on which this sampler engine channel shall listen to.
119     midi_chan_t midiChannel; ///< MIDI channel(s) on which this engine channel listens to (on all MIDI input ports).
120 iliev 2012 RingBuffer<Event,false>* pEventQueue; ///< Input event queue.
121     RTList<Event>* pEvents; ///< All engine channel specific events for the current audio fragment.
122 schoenebeck 2594 uint8_t ControllerTable[130]; ///< Reflects the current values (0-127) of all MIDI controllers for this engine / sampler channel. Number 128 is for channel pressure (mono aftertouch), 129 for pitch bend.
123 iliev 2012 String InstrumentFile;
124     int InstrumentIdx;
125     String InstrumentIdxName;
126     int InstrumentStat;
127     double GlobalVolume; ///< Master volume factor set through the C++ API / LSCP (a value < 1.0 means attenuation, a value > 1.0 means amplification)
128     double MidiVolume; ///< Volume factor altered by MIDI CC#7 (a value < 1.0 means attenuation, a value > 1.0 means amplification)
129     int Pitch; ///< Current (absolute) MIDI pitch value.
130     float CurrentKeyDimension; ///< Current value (0-1.0) for the keyboard dimension, altered by pressing a keyswitching key.
131     bool PortamentoMode; ///< in Portamento Mode we slide the pitch from the last note to the current note.
132     float PortamentoTime; ///< How long it will take to glide from the previous note to the current (in seconds)
133     float PortamentoPos; ///< Current position on the keyboard, that is integer and fractional part (only used if PortamentoMode is on)
134     std::vector<FxSend*> fxSends;
135     int GlobalTranspose; ///< amount of semi tones all notes should be transposed
136     int iLastPanRequest; ///< just for the return value of Pan(), so we don't have to make an injective function
137     int iEngineIndexSelf; ///< Reflects the index of this EngineChannel in the Engine's ArrayList.
138     bool bStatusChanged; ///< true in case an engine parameter has changed (e.g. new instrument, another volumet)
139 persson 2043 uint32_t RoundRobinIndex; ///< counter for round robin sample selection, incremented for each note on
140 schoenebeck 2594 Pool<ScriptEvent>* pScriptEvents; ///< Pool of all available script execution instances. ScriptEvents available to be allocated from the Pool are currently unused / not executiong, whereas the ScriptEvents allocated on the list are currently suspended / have not finished execution yet.
141     struct _Script {
142     VMParserContext* parserContext; ///< VM represenation of the currently loaded script or NULL if not script was loaded. Note that it is also not NULL if parser errors occurred!
143     bool bHasValidScript; ///< True in case there is a valid script currently loaded, false if script processing shall be skipped.
144     VMEventHandler* handlerInit; ///< VM representation of script's initilization callback or NULL if current script did not define such an init handler.
145 schoenebeck 2596 VMEventHandler* handlerNote; ///< VM representation of script's MIDI note on callback or NULL if current script did not define such an event handler.
146     VMEventHandler* handlerRelease; ///< VM representation of script's MIDI note off callback or NULL if current script did not define such an event handler.
147 schoenebeck 2594 VMEventHandler* handlerController; ///< VM representation of script's MIDI controller callback or NULL if current script did not define such an event handler.
148     _Script() {
149     parserContext = NULL;
150     bHasValidScript = false;
151 schoenebeck 2596 handlerInit = NULL;
152     handlerNote = NULL;
153     handlerRelease = NULL;
154     handlerController = NULL;
155 schoenebeck 2594 }
156     } script;
157 iliev 2012
158     SynchronizedConfig< ArrayList<VirtualMidiDevice*> > virtualMidiDevices;
159     SynchronizedConfig< ArrayList<VirtualMidiDevice*> >::Reader virtualMidiDevicesReader_AudioThread;
160     SynchronizedConfig< ArrayList<VirtualMidiDevice*> >::Reader virtualMidiDevicesReader_MidiThread;
161    
162 persson 2127 // specialization of RTList that doesn't require the pool
163     // to be provided at construction time
164     template<typename T>
165     class LazyList : public RTList<T> {
166     public:
167     using RTList<T>::allocAppend;
168     using RTList<T>::pPool;
169 persson 2114
170 persson 2127 LazyList() : RTList<T>(0) { }
171     typename RTList<T>::Iterator allocAppend(Pool<T>* pool) {
172     pPool = pool;
173     return allocAppend();
174     }
175     };
176    
177     typedef std::map<uint, LazyList<Event>*> ActiveKeyGroupMap;
178     ActiveKeyGroupMap ActiveKeyGroups; ///< Contains event queues for key groups, ordered by key group ID.
179    
180 iliev 2012 virtual void ResetControllers();
181     virtual void ResetInternal();
182     virtual void RemoveAllFxSends();
183    
184     void ImportEvents(uint Samples);
185 schoenebeck 2598 int ScheduleEvent(const Event* pEvent, int delay); //TODO: delay not implemented yet
186     void IgnoreEvent(int id);
187 persson 2114
188     void AddGroup(uint group);
189     void HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent);
190     void ClearGroupEventLists();
191     void DeleteGroupEventLists();
192 schoenebeck 2500
193     private:
194     /**
195     * Returns @c true if there are 2 ore more MidiInputPorts connected
196     * to this engine channel.
197     *
198     * This method is currently only used to prevent unnecessary
199     * MidiInputMutex.Lock() if there is not more than 1 MIDI input on
200     * this engine channel.
201     */
202     inline bool hasMultipleMIDIInputs() const {
203     //FIXME: leaves tiny time frames open (shortly after 1->2 devices connected or 2->1 disconnected) which could lead to concurrency issue for the purpose described above, however in practice it "should" be acceptable
204     return midiInputs.unsafeBack().size() > 1;
205     }
206 iliev 2012 };
207    
208     } // namespace LinuxSampler
209    
210 persson 2114 #endif /* __LS_ABSTRACTENGINECHANNEL_H__ */
211 iliev 2012

  ViewVC Help
Powered by ViewVC