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

Diff of /linuxsampler/trunk/src/engines/common/InstrumentScriptVM.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2630 by schoenebeck, Fri Jun 13 15:01:06 2014 UTC revision 2935 by schoenebeck, Sun Jul 10 14:24:13 2016 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck   * Copyright (c) 2014-2016 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 17  Line 17 
17  #include "../../common/Pool.h"  #include "../../common/Pool.h"
18  #include "InstrumentScriptVMFunctions.h"  #include "InstrumentScriptVMFunctions.h"
19    
20    /**
21     * Amount of bits on the left hand side of all pool_element_id_t numbers (i.e.
22     * event_id_t, note_id_t) being reserved for script VM implementation internal
23     * purposes.
24     *
25     * Right now there is only one bit reserved, which allows the VM (and its
26     * built-in functions) to distinguish user supplied @c Event IDs (event_id_t)
27     * from @c Note IDs (note_id_t).
28     */
29    #define INSTR_SCRIPT_EVENT_ID_RESERVED_BITS 1
30    
31    /**
32     * Used to mark IDs (in script scope) to actually be a note ID.
33     */
34    #define INSTR_SCRIPT_NOTE_ID_FLAG   (1 << (sizeof(pool_element_id_t) * 8 - 1))
35    
36  #define INSTR_SCRIPT_EVENT_GROUPS 28  #define INSTR_SCRIPT_EVENT_GROUPS 28
37    
38    #define EVENT_STATUS_INACTIVE 0
39    #define EVENT_STATUS_NOTE_QUEUE 1
40    
41  namespace LinuxSampler {  namespace LinuxSampler {
42    
43      class AbstractEngineChannel;      class AbstractEngineChannel;
44      class InstrumentScript;      class InstrumentScript;
45    
46        /** @brief Convert IDs between script scope and engine internal scope.
47         *
48         * This class is used to translate unique IDs of events between script
49         * scope and sampler engine internal scope, that is:
50         * @code
51         * int (script scope) -> event_id_t (engine internal scope)
52         * int (script scope) -> note_id_t (engine internal scope)
53         * @endcode
54         * and vice versa:
55         * @code
56         * event_id_t (engine internal scope) -> int (script scope)
57         * note_id_t (engine internal scope)  -> int (script scope)
58         * @endcode
59         * This is required because engine internally notes and regular events are
60         * using their own, separate ID generating pool, and their ID number set
61         * may thus overlap.
62         *
63         * @see INSTR_SCRIPT_EVENT_ID_RESERVED_BITS
64         */
65        class ScriptID {
66        public:
67            enum type_t {
68                EVENT, ///< ID is actually an event ID
69                NOTE, ///< ID is actually a note ID
70            };
71    
72            /**
73             * Construct a ScriptID object with an ID from script scope.
74             */
75            ScriptID(uint id) : m_id(id) {}
76    
77            /**
78             * Returns a ScriptID object constructed with an event ID from engine
79             * internal scope.
80             */
81            inline static ScriptID fromEventID(event_id_t id) {
82                return ScriptID(id);
83            }
84    
85            /**
86             * Returns a ScriptID object constructed with a note ID from engine
87             * internal scope.
88             */
89            inline static ScriptID fromNoteID(note_id_t id) {
90                return ScriptID(INSTR_SCRIPT_NOTE_ID_FLAG | id);
91            }
92    
93            /**
94             * Whether the ID reflected by this ScriptID object is actually a note
95             * ID or rather an event ID.
96             */
97            inline type_t type() const {
98                return (m_id & INSTR_SCRIPT_NOTE_ID_FLAG) ? NOTE : EVENT;
99            }
100    
101            inline bool isNoteID() const {
102                return type() == NOTE;
103            }
104    
105            inline bool isEventID() const {
106                return type() == EVENT;
107            }
108    
109            /**
110             * Returns event ID (for engine internal scope) of the ID reflected by
111             * this ScriptID object, it returns 0 (being an invalid ID) if the ID
112             * reflected by this ScriptID object is not an event ID.
113             */
114            inline event_id_t eventID() const {
115                switch (type()) {
116                    case EVENT: return m_id;
117                    default:    return 0; // not an event id, return invalid ID
118                }
119            }
120    
121            /**
122             * Returns note ID (for engine internal scope) of the ID reflected by
123             * this ScriptID object, it returns 0 (being an invalid ID) if the ID
124             * reflected by this ScriptID object is not a note ID.
125             */
126            inline note_id_t noteID() const {
127                switch (type()) {
128                    case NOTE: return ~INSTR_SCRIPT_NOTE_ID_FLAG & m_id;
129                    default:   return 0; // not a note id, return invalid ID
130                }
131            }
132    
133            /**
134             * Integer cast operator, which returns an ID number of this ScripID
135             * object intended for script scope.
136             */
137            inline operator uint() const {
138                return m_id;
139            }
140    
141        private:
142            uint m_id;
143        };
144    
145      /** @brief List of Event IDs.      /** @brief List of Event IDs.
146       *       *
147       * Used for built-in script functions:       * Used for built-in script functions:
# Line 36  namespace LinuxSampler { Line 154  namespace LinuxSampler {
154          void erase(int eventID);          void erase(int eventID);
155          void setScript(InstrumentScript* pScript) { m_script = pScript; }          void setScript(InstrumentScript* pScript) { m_script = pScript; }
156          inline int size() const { return ConstCapacityArray<int>::size(); }          inline int size() const { return ConstCapacityArray<int>::size(); }
157            inline void clear() { ConstCapacityArray<int>::clear(); }
158          inline int& operator[](uint index) { return ConstCapacityArray<int>::operator[](index); }          inline int& operator[](uint index) { return ConstCapacityArray<int>::operator[](index); }
159          inline const int& operator[](uint index) const { return ConstCapacityArray<int>::operator[](index); }          inline const int& operator[](uint index) const { return ConstCapacityArray<int>::operator[](index); }
160      protected:      protected:
161          InstrumentScript* m_script;          InstrumentScript* m_script;
         StmtFlags_t flags;  
162      };      };
163    
164      /** @brief Real-time instrument script VM representation.      /** @brief Real-time instrument script VM representation.
165       *       *
166       * Holds the VM representation of all event handlers of the currently loaded       * Holds the VM representation of all event handlers of the currently loaded
167       * script, ready to be executed by the sampler engine.       * script, ready to be executed by the sampler engine.
168         *
169         * Even thought scripts (or to be more specific their event handler objects)
170         * are shared between sampler engine channels, the InstrumentScript struct
171         * instances though are not shared. Each sampler engine channel has its own
172         * instance of a InstrumentScript struct. That's important, because this
173         * struct also holds engine channel local informations, for example the
174         * events that occured on the respective engine channel.
175       */       */
176      struct InstrumentScript {      struct InstrumentScript {
177          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!          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!
# Line 55  namespace LinuxSampler { Line 180  namespace LinuxSampler {
180          VMEventHandler*       handlerNote; ///< VM representation of script's MIDI note on callback or NULL if current script did not define such an event handler.          VMEventHandler*       handlerNote; ///< VM representation of script's MIDI note on callback or NULL if current script did not define such an event handler.
181          VMEventHandler*       handlerRelease; ///< VM representation of script's MIDI note off callback or NULL if current script did not define such an event handler.          VMEventHandler*       handlerRelease; ///< VM representation of script's MIDI note off callback or NULL if current script did not define such an event handler.
182          VMEventHandler*       handlerController; ///< VM representation of script's MIDI controller callback or NULL if current script did not define such an event handler.          VMEventHandler*       handlerController; ///< VM representation of script's MIDI controller callback or NULL if current script did not define such an event handler.
183          Pool<ScriptEvent>*    pEvents; ///< 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.          Pool<ScriptEvent>*    pEvents; ///< 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 (@see pKeyEvents).
184            RTList<ScriptEvent>*  pKeyEvents[128]; ///< Stores previously finished executed "note on" script events for the respective active note/key as long as the key/note is active. This is however only done if there is a "note" script event handler and a "release" script event handler defined in the script and both handlers use (reference) polyphonic variables. If that is not the case, then this list is not used at all. So the purpose of pKeyEvents is only to implement preserving/passing polyphonic variable data from "on note .. end on" script block to the respective "on release .. end on" script block.
185            RTAVLTree<ScriptEvent> suspendedEvents; ///< Contains pointers to all suspended events, sorted by time when those script events are to be resumed next.
186          AbstractEngineChannel* pEngineChannel;          AbstractEngineChannel* pEngineChannel;
187          String                code; ///< Source code of the instrument script. Used in case the sampler engine is changed, in that case a new ScriptVM object is created for the engine and VMParserContext object for this script needs to be recreated as well. Thus the script is then parsed again by passing the source code to recreate the parser context.          String                code; ///< Source code of the instrument script. Used in case the sampler engine is changed, in that case a new ScriptVM object is created for the engine and VMParserContext object for this script needs to be recreated as well. Thus the script is then parsed again by passing the source code to recreate the parser context.
188          EventGroup            eventGroups[INSTR_SCRIPT_EVENT_GROUPS]; ///< Used for built-in script functions: by_event_marks(), set_event_mark(), delete_event_mark().          EventGroup            eventGroups[INSTR_SCRIPT_EVENT_GROUPS]; ///< Used for built-in script functions: by_event_marks(), set_event_mark(), delete_event_mark().
189    
190          InstrumentScript(AbstractEngineChannel* pEngineChannel);          InstrumentScript(AbstractEngineChannel* pEngineChannel);
191            ~InstrumentScript();
         ~InstrumentScript() {  
             resetAll();  
         }  
192    
193          void load(const String& text);          void load(const String& text);
194          void unload();          void unload();
195          void resetAll();          void resetAll();
196            void resetEvents();
197      };      };
198    
199      /** @brief Real-time instrument script virtual machine.      /** @brief Real-time instrument script virtual machine.
# Line 111  namespace LinuxSampler { Line 236  namespace LinuxSampler {
236          InstrumentScriptVMFunction_set_event_mark m_fnSetEventMark;          InstrumentScriptVMFunction_set_event_mark m_fnSetEventMark;
237          InstrumentScriptVMFunction_delete_event_mark m_fnDeleteEventMark;          InstrumentScriptVMFunction_delete_event_mark m_fnDeleteEventMark;
238          InstrumentScriptVMFunction_by_marks m_fnByMarks;          InstrumentScriptVMFunction_by_marks m_fnByMarks;
239            InstrumentScriptVMFunction_change_vol m_fnChangeVol;
240            InstrumentScriptVMFunction_change_tune m_fnChangeTune;
241            InstrumentScriptVMFunction_change_pan m_fnChangePan;
242            InstrumentScriptVMFunction_change_cutoff m_fnChangeCutoff;
243            InstrumentScriptVMFunction_change_reso m_fnChangeReso;
244            InstrumentScriptVMFunction_event_status m_fnEventStatus;
245    
246          friend class InstrumentScriptVMFunction_play_note;          friend class InstrumentScriptVMFunction_play_note;
247          friend class InstrumentScriptVMFunction_set_controller;          friend class InstrumentScriptVMFunction_set_controller;
# Line 120  namespace LinuxSampler { Line 251  namespace LinuxSampler {
251          friend class InstrumentScriptVMFunction_set_event_mark;          friend class InstrumentScriptVMFunction_set_event_mark;
252          friend class InstrumentScriptVMFunction_delete_event_mark;          friend class InstrumentScriptVMFunction_delete_event_mark;
253          friend class InstrumentScriptVMFunction_by_marks;          friend class InstrumentScriptVMFunction_by_marks;
254            friend class InstrumentScriptVMFunction_change_vol;
255            friend class InstrumentScriptVMFunction_change_tune;
256            friend class InstrumentScriptVMFunction_change_pan;
257            friend class InstrumentScriptVMFunction_change_cutoff;
258            friend class InstrumentScriptVMFunction_change_reso;
259            friend class InstrumentScriptVMFunction_event_status;
260      };      };
261    
262  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2630  
changed lines
  Added in v.2935

  ViewVC Help
Powered by ViewVC