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

Annotation of /linuxsampler/trunk/src/engines/common/Event.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3845 - (hide annotations) (download) (as text)
Tue Jan 5 20:42:32 2021 UTC (3 years, 3 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 27218 byte(s)
* ScriptVM: Fixed incorrect polyphonic data transfer from wrong "note"
  handler to "release" handler; which also fixes no "release" handler
  being executed sometimes, and due to the latter it also fixes potential
  crashes as some polyphonic script events were never released and the
  engine hence was running out of free script events.

* Bumped version (2.1.1.svn68).

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 3845 * Copyright (C) 2005 - 2021 Christian Schoenebeck *
7 schoenebeck 53 * *
8     * This program is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this program; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #ifndef __LS_EVENT_H__
25     #define __LS_EVENT_H__
26    
27     #include "../../common/global.h"
28 schoenebeck 328 #include "../../common/RTMath.h"
29 schoenebeck 2871 #include "../../common/RTAVLTree.h"
30     #include "../../common/Pool.h"
31 schoenebeck 890 #include "../EngineChannel.h"
32 schoenebeck 2948 #include "../../scriptvm/common.h"
33 schoenebeck 53
34 schoenebeck 3565 // On Windows RELATIVE might be defined as macro in wingdi.h, which would
35     // cause a compiler error of the same token used in this header file below.
36     // So we undefine that macro here for now (if present).
37     #ifdef RELATIVE
38     # warning Preprocessor conflict detected: Macro RELATIVE was declared by system headers; undefining it here.
39     # undef RELATIVE
40     #endif
41    
42 schoenebeck 53 namespace LinuxSampler {
43    
44     // just symbol prototyping
45     class Event;
46 schoenebeck 2871 class SchedulerNode;
47     class ScriptEvent;
48     class ScheduledEvent;
49 schoenebeck 53
50     /**
51 schoenebeck 2871 * Data type used to schedule events sample point accurately both within, as
52     * well as beyond the scope of the current audio fragment cycle. The timing
53     * reflected by this data type is consecutively running for a very long
54     * time. Even with a sample rate of 96 kHz a scheduler time of this data
55     * type will not wrap before 6 million years. So in practice such time
56     * stamps are unique and will not repeat (unless the EventGenerator is
57     * reset).
58     */
59     typedef uint64_t sched_time_t;
60    
61     /**
62 schoenebeck 53 * Generates Event objects and is responsible for resolving the position
63     * in the current audio fragment each Event actually belongs to.
64     */
65     class EventGenerator {
66     public:
67     EventGenerator(uint SampleRate);
68     void UpdateFragmentTime(uint SamplesToProcess);
69 schoenebeck 3283 void SetSampleRate(uint SampleRate);
70 schoenebeck 53 Event CreateEvent();
71 schoenebeck 906 Event CreateEvent(int32_t FragmentPos);
72 schoenebeck 2871
73     template<typename T>
74     void scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds);
75    
76     RTList<ScheduledEvent>::Iterator popNextScheduledEvent(RTAVLTree<ScheduledEvent>& queue, Pool<ScheduledEvent>& pool, sched_time_t end);
77     RTList<ScriptEvent>::Iterator popNextScheduledScriptEvent(RTAVLTree<ScriptEvent>& queue, Pool<ScriptEvent>& pool, sched_time_t end);
78    
79     /**
80 schoenebeck 2948 * Returns the scheduler time for the first sample point of the
81     * current audio fragment cycle.
82     */
83     sched_time_t schedTimeAtCurrentFragmentStart() const {
84     return uiTotalSamplesProcessed;
85     }
86    
87     /**
88 schoenebeck 2871 * Returns the scheduler time for the first sample point of the next
89     * audio fragment cycle.
90     */
91     sched_time_t schedTimeAtCurrentFragmentEnd() const {
92     return uiTotalSamplesProcessed + uiSamplesProcessed;
93     }
94    
95 schoenebeck 53 protected:
96 schoenebeck 328 typedef RTMath::time_stamp_t time_stamp_t;
97 schoenebeck 293 inline int32_t ToFragmentPos(time_stamp_t TimeStamp) {
98     return int32_t (int32_t(TimeStamp - FragmentTime.begin) * FragmentTime.sample_ratio);
99 schoenebeck 53 }
100     friend class Event;
101     private:
102     uint uiSampleRate;
103     uint uiSamplesProcessed;
104     struct __FragmentTime__ {
105     time_stamp_t begin; ///< Real time stamp of the beginning of this audio fragment cycle.
106     time_stamp_t end; ///< Real time stamp of the end of this audio fragment cycle.
107     float sample_ratio; ///< (Samples per cycle) / (Real time duration of cycle)
108     } FragmentTime;
109 schoenebeck 2871 sched_time_t uiTotalSamplesProcessed; ///< Total amount of sample points that have been processed since this EventGenerator object has been created. This is used to schedule instrument script events long time ahead in future (that is beyond the scope of the current audio fragment).
110 schoenebeck 53 };
111    
112     /**
113 schoenebeck 2879 * Unique numeric ID of an event which can be used to retrieve access to
114     * the actual @c Event object. Once the event associated with a certain ID
115     * was released (back to its event pool), this numeric ID becomes invalid
116     * and Pool< Event >::fromID() will detect this circumstance and will
117     * return an invalid Iterator, and thus will prevent you from misusing an
118     * event which no longer "exists".
119     *
120 schoenebeck 3689 * Note that an @c Event object usually just "exists" for exactly one audio
121 schoenebeck 2879 * fragment cycle: that is it exists right from the beginning of the audio
122     * fragment cycle where it was caused (i.e. where its MIDI data was
123     * received by the respective engine channel) and will disappear
124     * automatically at the end of that audio fragment cycle.
125     */
126     typedef pool_element_id_t event_id_t;
127    
128     /**
129     * Unique numeric ID of a note which can be used to retrieve access to the
130     * actual @c Note object. Once the note associated with a certain ID was
131     * released (back to its note pool), this numeric ID becomes invalid and
132     * Pool< Note >::fromID() will detect this circumstance and will return
133     * an invalid Iterator, and thus will prevent you from misusing a note
134     * which no longer is "alive".
135     *
136     * A @c Note object exists right when the respective MIDI note-on event
137     * was received by the respective engine channel, and remains existent
138     * until the caused note and all its voices were finally freed (which might
139     * even be long time after the respective note-off event was received,
140     * depending on the duration of the voice's release stages etc.).
141     */
142     typedef pool_element_id_t note_id_t;
143    
144     /**
145 schoenebeck 2948 * Unique numeric ID of a script callback ID instance which can be used to
146     * retrieve access to the actual @c ScriptEvent object. Once the script
147     * callback instance associated with a certain ID stopped its execution
148     * (that is completely stopped, not just suspended) then this numeric ID
149     * becomes invalid and Pool< ScriptEvent >::fromID() will detect this
150     * circumstance and will return an invalid Iterator, and thus will prevent
151     * you from misusing a script callback instance which no longer "exists".
152     */
153     typedef pool_element_id_t script_callback_id_t;
154    
155     /**
156 schoenebeck 53 * Events are usually caused by a MIDI source or an internal modulation
157 schoenebeck 906 * controller like LFO or EG. An event should only be created by an
158     * EventGenerator!
159 schoenebeck 53 *
160 schoenebeck 2594 * @see EventGenerator, ScriptEvent
161 schoenebeck 53 */
162     class Event {
163     public:
164     Event(){}
165     enum type_t {
166 schoenebeck 2938 type_note_on, ///< (real) MIDI note-on event
167     type_note_off, ///< (real) MIDI note-off event
168     type_pitchbend, ///< MIDI pitch bend wheel change event
169     type_control_change, ///< MIDI CC event
170 schoenebeck 3688 type_rpn, ///< Transformed from a raw RPN CC MIDI event.
171     type_nrpn, ///< Transformed from a raw NRPN CC MIDI event.
172 schoenebeck 244 type_sysex, ///< MIDI system exclusive message
173 schoenebeck 2938 type_cancel_release_key, ///< transformed either from a (real) MIDI note-on or sustain-pedal-down event
174     type_release_key, ///< transformed either from a (real) MIDI note-off or sustain-pedal-up event
175     type_release_note, ///< transformed from a type_stop_note event
176 schoenebeck 2559 type_channel_pressure, ///< a.k.a. aftertouch
177     type_note_pressure, ///< polyphonic key pressure (aftertouch)
178 schoenebeck 2938 type_play_note, ///< caused by a call to built-in instrument script function play_note()
179     type_stop_note, ///< caused by a call to built-in instrument script function note_off()
180 schoenebeck 3188 type_kill_note, ///< caused by a call to built-in instrument script function fade_out()
181 schoenebeck 2938 type_note_synth_param, ///< change a note's synthesis parameters (upon real-time instrument script function calls, i.e. change_vol(), change_tune(), change_pan(), etc.)
182 schoenebeck 53 } Type;
183 schoenebeck 2931 enum synth_param_t {
184     synth_param_volume,
185 schoenebeck 3188 synth_param_volume_time,
186 schoenebeck 3246 synth_param_volume_curve,
187 schoenebeck 2931 synth_param_pitch,
188 schoenebeck 3188 synth_param_pitch_time,
189 schoenebeck 3246 synth_param_pitch_curve,
190 schoenebeck 2931 synth_param_pan,
191 schoenebeck 3335 synth_param_pan_time,
192     synth_param_pan_curve,
193 schoenebeck 2935 synth_param_cutoff,
194     synth_param_resonance,
195 schoenebeck 2953 synth_param_attack,
196     synth_param_decay,
197 schoenebeck 3316 synth_param_sustain,
198 schoenebeck 2953 synth_param_release,
199 schoenebeck 3360 synth_param_cutoff_attack,
200     synth_param_cutoff_decay,
201     synth_param_cutoff_sustain,
202     synth_param_cutoff_release,
203 schoenebeck 3118 synth_param_amp_lfo_depth,
204     synth_param_amp_lfo_freq,
205 schoenebeck 3360 synth_param_cutoff_lfo_depth,
206     synth_param_cutoff_lfo_freq,
207 schoenebeck 3118 synth_param_pitch_lfo_depth,
208     synth_param_pitch_lfo_freq,
209 schoenebeck 2931 };
210 schoenebeck 3561 enum class ValueScope : unsigned char {
211     /**
212     * The new synthesis parameter value should be applied
213     * relatively to itself (as normalized value range), and then
214     * applied relatively against other sources (i.e. LFOs, EGs)
215     * for the same synthesis parameter.
216     */
217 schoenebeck 3563 SELF_RELATIVE = 1,
218 schoenebeck 3561 /**
219     * The new synthesis paramater value of itself should be
220     * replaced, and then applied relatively to other sources
221     * (i.e. LFOs, EGs) for the same synthesis parameter.
222     */
223 schoenebeck 3563 RELATIVE = 0, //IMPORANT: must remain 0 because of the union structure below which would otherwise i.e. assign invalid pointers/IDs to Param.Note structure in Init()
224 schoenebeck 3561 /**
225     * The new synthesis parameter value should be applied
226     * relatively to itself (as normalized value range), and then
227     * applied directly (as normalized value range) as final value
228     * of this synthesis chain, thus all other sources (i.e. LFOs,
229     * EGs) should entirely be ignored.
230     */
231 schoenebeck 3563 FINAL_SELF_RELATIVE = 2,
232 schoenebeck 3561 /**
233     * The new synthesis parameter value of itself should be
234     * replaced, and then applied directly (as normalized value
235     * range) as final value of this synthesis chain, thus all other
236     * sources (i.e. LFOs, EGs) should entirely be ignored.
237     */
238 schoenebeck 3563 FINAL_NORM = 3,
239 schoenebeck 3561 /**
240     * Same as @c FINAL_NORM, but this one is already in the native
241     * unit (i.e. seconds, Hz) of this synthesis parameter.
242     */
243 schoenebeck 3563 FINAL_NATIVE = 4,
244 schoenebeck 3561 };
245 schoenebeck 53 union {
246 schoenebeck 246 /// Note-on and note-off event specifics
247     struct _Note {
248 schoenebeck 2600 uint8_t Channel; ///< MIDI channel (0..15)
249 schoenebeck 246 uint8_t Key; ///< MIDI key number of note-on / note-off event.
250     uint8_t Velocity; ///< Trigger or release velocity of note-on / note-off event.
251 schoenebeck 250 int8_t Layer; ///< Layer index (usually only used if a note-on event has to be postponed, e.g. due to shortage of free voices).
252     int8_t ReleaseTrigger; ///< If new voice should be a release triggered voice (actually boolean field and usually only used if a note-on event has to be postponed, e.g. due to shortage of free voices).
253 schoenebeck 2938 note_id_t ID; ///< Unique numeric ID of the @c Note object associated with this note event.
254 schoenebeck 2879 note_id_t ParentNoteID; ///< If not zero: Unique numeric ID of the parent @c Note object that shall become parent of resulting new Note object of this Event. So this is used to associate a new note with a previous note, i.e. to release the new note once the parent note was released.
255 persson 2101 void* pRegion; ///< Engine specific pointer to instrument region
256 schoenebeck 246 } Note;
257     /// Control change event specifics
258     struct _CC {
259 schoenebeck 2600 uint8_t Channel; ///< MIDI channel (0..15)
260 schoenebeck 246 uint8_t Controller; ///< MIDI controller number of control change event.
261     uint8_t Value; ///< Controller Value of control change event.
262     } CC;
263 schoenebeck 3688 /// Used for both RPN & NRPN events
264     struct _RPN {
265     uint8_t Channel; ///< MIDI channel (0..15)
266     uint16_t Parameter; ///< Merged 14 bit representation of parameter number (that is MSB and LSB combined).
267     uint16_t Value; ///< Merged 14 bit representation of new (N)RPN value (that is MSB and LSB combined).
268     uint8_t ParameterMSB() const { return Parameter >> 7; }
269     uint8_t ParameterLSB() const { return Parameter & 127; }
270     uint8_t ValueMSB() const { return Value >> 7; }
271     uint8_t ValueLSB() const { return Value & 127; }
272     } RPN, NRPN;
273 schoenebeck 246 /// Pitchbend event specifics
274     struct _Pitch {
275 schoenebeck 2600 uint8_t Channel; ///< MIDI channel (0..15)
276 schoenebeck 246 int16_t Pitch; ///< Pitch value of pitchbend event.
277     } Pitch;
278     /// MIDI system exclusive event specifics
279     struct _Sysex {
280     uint Size; ///< Data length (in bytes) of MIDI system exclusive message.
281     } Sysex;
282 schoenebeck 2559 /// Channel Pressure (aftertouch) event specifics
283     struct _ChannelPressure {
284 schoenebeck 2600 uint8_t Channel; ///< MIDI channel (0..15)
285 schoenebeck 2611 uint8_t Controller; ///< Should always be assigned to CTRL_TABLE_IDX_AFTERTOUCH.
286 schoenebeck 2559 uint8_t Value; ///< New aftertouch / pressure value for keys on that channel.
287     } ChannelPressure;
288     /// Polyphonic Note Pressure (aftertouch) event specifics
289     struct _NotePressure {
290 schoenebeck 2600 uint8_t Channel; ///< MIDI channel (0..15)
291 schoenebeck 2559 uint8_t Key; ///< MIDI note number where key pressure (polyphonic aftertouch) changed.
292     uint8_t Value; ///< New pressure value for note.
293     } NotePressure;
294 schoenebeck 2931 ///< Note synthesis parameter change event's specifics (used for real-time instrument script built-in functions which may alter synthesis parameters on note level).
295     struct _NoteSynthParam {
296     note_id_t NoteID; ///< ID of Note whose voices shall be modified.
297     synth_param_t Type; ///< Synthesis parameter which is to be changed.
298     float Delta; ///< The value change that should be applied against the note's current synthesis parameter value.
299     float AbsValue; ///< New current absolute value of synthesis parameter (that is after @c Delta being applied).
300 schoenebeck 3561 ValueScope Scope; ///< How @c Delta should be applied against @c AbsValue, and how @c AbsValue should then actually be applied to the synthesis chain.
301    
302     inline bool isFinal() const { return Scope >= ValueScope::FINAL_SELF_RELATIVE; }
303 schoenebeck 2931 } NoteSynthParam;
304 schoenebeck 246 } Param;
305 schoenebeck 412 EngineChannel* pEngineChannel; ///< Pointer to the EngineChannel where this event occured on, NULL means Engine global event (e.g. SysEx message).
306 schoenebeck 1751 MidiInputPort* pMidiInputPort; ///< Pointer to the MIDI input port on which this event occured (NOTE: currently only for global events, that is SysEx messages)
307 schoenebeck 53
308 schoenebeck 2879 inline void Init() {
309 schoenebeck 3686 memset(&Param, 0, sizeof(Param));
310 schoenebeck 2879 }
311 schoenebeck 293 inline int32_t FragmentPos() {
312     if (iFragmentPos >= 0) return iFragmentPos;
313     iFragmentPos = pEventGenerator->ToFragmentPos(TimeStamp);
314     if (iFragmentPos < 0) iFragmentPos = 0; // if event arrived shortly before the beginning of current fragment
315     return iFragmentPos;
316 schoenebeck 53 }
317 schoenebeck 293 inline void ResetFragmentPos() {
318     iFragmentPos = -1;
319     }
320 schoenebeck 2879 inline void CopyTimeFrom(const Event& other) {
321     TimeStamp = other.TimeStamp;
322     iFragmentPos = other.iFragmentPos;
323     }
324 schoenebeck 2948 inline sched_time_t SchedTime() {
325     return pEventGenerator->schedTimeAtCurrentFragmentStart() + FragmentPos();
326     }
327 schoenebeck 3561 inline static ValueScope scopeBy_FinalRelativeUnit(bool bFinal, bool bRelative, bool bNativeUnit) {
328     if (!bFinal && bRelative)
329     return ValueScope::SELF_RELATIVE;
330     if (!bFinal)
331     return ValueScope::RELATIVE;
332     if (bRelative)
333     return ValueScope::FINAL_SELF_RELATIVE;
334     if (bNativeUnit)
335     return ValueScope::FINAL_NATIVE;
336     return ValueScope::FINAL_NORM;
337     }
338 schoenebeck 53 protected:
339     typedef EventGenerator::time_stamp_t time_stamp_t;
340     Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);
341 schoenebeck 906 Event(EventGenerator* pGenerator, int32_t FragmentPos);
342 schoenebeck 53 friend class EventGenerator;
343     private:
344     EventGenerator* pEventGenerator; ///< Creator of the event.
345     time_stamp_t TimeStamp; ///< Time stamp of the event's occurence.
346 schoenebeck 293 int32_t iFragmentPos; ///< Position in the current fragment this event refers to.
347 schoenebeck 53 };
348    
349 schoenebeck 3688 inline Pool<Event>::Iterator prevEventOf(const Pool<Event>::Iterator& itEvent) {
350     if (!itEvent) return Pool<Event>::Iterator();
351     Pool<Event>::Iterator itPrev = itEvent;
352     return --itPrev;
353     }
354    
355     inline Pool<Event>::Iterator nextEventOf(const Pool<Event>::Iterator& itEvent) {
356     if (!itEvent) return Pool<Event>::Iterator();
357     Pool<Event>::Iterator itNext = itEvent;
358     return ++itNext;
359     }
360    
361     inline bool isPrevEventCCNr(const Pool<Event>::Iterator& itEvent, uint8_t CCNr) {
362     Pool<Event>::Iterator itPrev = prevEventOf(itEvent);
363     if (!itPrev) return false;
364     return itPrev->Type == Event::type_control_change &&
365     itPrev->Param.CC.Controller == CCNr;
366     }
367    
368     inline bool isNextEventCCNr(const Pool<Event>::Iterator& itEvent, uint8_t CCNr) {
369     Pool<Event>::Iterator itNext = nextEventOf(itEvent);
370     if (!itNext) return false;
371     return itNext->Type == Event::type_control_change &&
372     itNext->Param.CC.Controller == CCNr;
373     }
374    
375 schoenebeck 2871 /**
376     * Used to sort timing relevant objects (i.e. events) into timing/scheduler
377     * queue. This class is just intended as base class and should be derived
378     * for its actual purpose (for the precise data type being scheduled).
379     */
380     class SchedulerNode : public RTAVLNode {
381     public:
382 schoenebeck 2948 using RTAVLNode::reset; // make reset() method public
383    
384 schoenebeck 2871 sched_time_t scheduleTime; ///< Time ahead in future (in sample points) when this object shall be processed. This value is compared with EventGenerator's uiTotalSamplesProcessed member variable.
385    
386     /// Required operator implementation for RTAVLTree class.
387     inline bool operator==(const SchedulerNode& other) const {
388     return this->scheduleTime == other.scheduleTime;
389     }
390    
391     /// Required operator implementation for RTAVLTree class.
392     inline bool operator<(const SchedulerNode& other) const {
393     return this->scheduleTime < other.scheduleTime;
394     }
395 schoenebeck 2948
396     /// This is actually just for code readability.
397     inline RTAVLTreeBase* currentSchedulerQueue() const { return rtavlTree(); }
398 schoenebeck 2871 };
399    
400     /**
401     * Used to sort delayed MIDI events into a timing/scheduler queue. This
402     * object just contains the timing informations, the actual MIDI event is
403     * pointed by member variable @c itEvent.
404     */
405     class ScheduledEvent : public SchedulerNode {
406     public:
407     Pool<Event>::Iterator itEvent; ///< Points to the actual Event object being scheduled.
408     };
409    
410 schoenebeck 2594 class VMEventHandler;
411     class VMExecContext;
412    
413 schoenebeck 3293 /**
414     * Maximum amount of child script handler instances one script handler is
415     * allowed to create by calling built-in script function fork().
416     */
417     #define MAX_FORK_PER_SCRIPT_HANDLER 8
418    
419 schoenebeck 2594 /** @brief Real-time instrument script event.
420     *
421     * Encapsulates one execution instance of a real-time instrument script for
422     * exactly one script event handler (script event callback).
423 schoenebeck 2871 *
424     * This class derives from SchedulerNode for being able to be sorted efficiently
425     * by the script scheduler if the script was either a) calling the wait()
426     * script function or b) the script was auto suspended by the ScriptVM
427     * because the script was executing for too long. In both cases the
428     * scheduler has to sort the ScriptEvents in its execution queue according
429     * to the precise time the respective script execution instance needs to be
430     * resumed.
431 schoenebeck 2594 */
432 schoenebeck 2871 class ScriptEvent : public SchedulerNode {
433 schoenebeck 2594 public:
434 schoenebeck 2879 Event cause; ///< Copy of original external @c Event that triggered this script event (i.e. MIDI note on event, MIDI CC event, etc.).
435     pool_element_id_t id; ///< Native representation of built-in script variable $EVENT_ID. For scripts' "note" event handler this will reflect the unique ID of the @c Note object, for all other event handlers the unique ID of the original external @c Event object that triggered this script event.
436 schoenebeck 2594 VMEventHandler** handlers; ///< The script's event handlers (callbacks) to be processed (NULL terminated list).
437     VMExecContext* execCtx; ///< Script's current execution state (polyphonic variables and execution stack).
438     int currentHandler; ///< Current index in 'handlers' list above.
439     int executionSlices; ///< Amount of times this script event has been executed by the ScriptVM runner class.
440 schoenebeck 2948 bool ignoreAllWaitCalls; ///< If true: calling any built-in wait*() script function should be ignored (this variable may be set with the 2nd argument of built-in script function stop_wait()).
441 schoenebeck 3845 bool releaseMatched; ///< Only for note handlers with polyphonic data: whether a corresponding release handler has already been triggered subsequently for this note handler.
442 schoenebeck 2948 VMEventHandlerType_t handlerType; ///< Native representation of built-in script variable $NI_CALLBACK_TYPE, reflecting the script event type of this script event.
443 schoenebeck 3293 script_callback_id_t parentHandlerID; ///< Only in case this script handler instance was created by calling built-in script function fork(): callback ID of the parent event handler instance which created this child. For regular event handler instances which were not created by fork(), this variable reflects 0 (which is always considered an invalid handler ID).
444     script_callback_id_t childHandlerID[MAX_FORK_PER_SCRIPT_HANDLER+1]; ///< In case built-in script function fork() was called by this script handler instance: A zero terminated ID list of all child event handler instances (note: children will not vanish from this list after they terminated).
445     bool autoAbortByParent; ///< Only if this is a child event handler created by calling fork(): if this is true then this child will automatically aborted if the parent event handler terminates.
446     int forkIndex; ///< Only for fork() calls: distinguishment feature which is 0 for parent, 1 for 1st child, 2 for 2nd child, etc.
447    
448     void forkTo(ScriptEvent* e, bool bAutoAbort) const;
449     int countChildHandlers() const;
450     void addChildHandlerID(script_callback_id_t childID);
451 schoenebeck 2594 };
452    
453 schoenebeck 2871 /**
454     * Insert given @a node into the supplied timing @a queue with a scheduled
455     * timing position given by @a fragmentPosBase and @a microseconds, where
456 schoenebeck 2879 * @a microseconds reflects the amount of microseconds in future from "now"
457 schoenebeck 2871 * where the node shall be scheduled, and @a fragmentPos identifies the
458     * sample point within the current audio fragment cycle which shall be
459     * interpreted by this method to be "now".
460     *
461     * The meaning of @a fragmentPosBase becomes more important the larger
462 schoenebeck 3293 * the audio fragment size, and vice versa it becomes less important the
463 schoenebeck 2871 * smaller the audio fragment size.
464     *
465     * @param queue - destination scheduler queue
466     * @param node - node (i.e. event) to be inserted into the queue
467     * @param fragmentPosBase - sample point in current audio fragment to be "now"
468     * @param microseconds - timing of node from "now" (in microseconds)
469     */
470     template<typename T>
471     void EventGenerator::scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds) {
472 schoenebeck 3205 // round up (+1) if microseconds is not zero (i.e. because 44.1 kHz and
473     // 1 us would yield in < 1 and thus would be offset == 0)
474     const sched_time_t offset =
475     (microseconds != 0LL) ?
476     1.f + (float(uiSampleRate) * (float(microseconds) / 1000000.f))
477     : 0.f;
478     node.scheduleTime = uiTotalSamplesProcessed + fragmentPosBase + offset;
479 schoenebeck 2871 queue.insert(node);
480     }
481    
482 schoenebeck 53 } // namespace LinuxSampler
483    
484     #endif // __LS_EVENT_H__

  ViewVC Help
Powered by ViewVC