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

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

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

revision 2600 by schoenebeck, Sat Jun 7 00:16:03 2014 UTC revision 3565 by schoenebeck, Sat Aug 24 11:22:52 2019 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2014 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2019 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# Line 26  Line 26 
26    
27  #include "../../common/global.h"  #include "../../common/global.h"
28  #include "../../common/RTMath.h"  #include "../../common/RTMath.h"
29    #include "../../common/RTAVLTree.h"
30    #include "../../common/Pool.h"
31  #include "../EngineChannel.h"  #include "../EngineChannel.h"
32    #include "../../scriptvm/common.h"
33    
34    // 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  namespace LinuxSampler {  namespace LinuxSampler {
43    
44      // just symbol prototyping      // just symbol prototyping
45      class Event;      class Event;
46        class SchedulerNode;
47        class ScriptEvent;
48        class ScheduledEvent;
49    
50        /**
51         * 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       * Generates Event objects and is responsible for resolving the position       * Generates Event objects and is responsible for resolving the position
# Line 41  namespace LinuxSampler { Line 66  namespace LinuxSampler {
66          public:          public:
67              EventGenerator(uint SampleRate);              EventGenerator(uint SampleRate);
68              void UpdateFragmentTime(uint SamplesToProcess);              void UpdateFragmentTime(uint SamplesToProcess);
69                void SetSampleRate(uint SampleRate);
70              Event CreateEvent();              Event CreateEvent();
71              Event CreateEvent(int32_t FragmentPos);              Event CreateEvent(int32_t FragmentPos);
72    
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                 * 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                 * 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          protected:          protected:
96              typedef RTMath::time_stamp_t time_stamp_t;              typedef RTMath::time_stamp_t time_stamp_t;
97              inline int32_t ToFragmentPos(time_stamp_t TimeStamp) {              inline int32_t ToFragmentPos(time_stamp_t TimeStamp) {
# Line 57  namespace LinuxSampler { Line 106  namespace LinuxSampler {
106                  time_stamp_t end;          ///< Real time stamp of the end of this audio fragment cycle.                  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)                  float        sample_ratio; ///< (Samples per cycle) / (Real time duration of cycle)
108              } FragmentTime;              } FragmentTime;
109                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      };      };
111    
112      /**      /**
113         * 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         * Note that an @c Event object usually just "exists" for exactly on audio
121         * 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         * 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       * Events are usually caused by a MIDI source or an internal modulation       * Events are usually caused by a MIDI source or an internal modulation
157       * controller like LFO or EG. An event should only be created by an       * controller like LFO or EG. An event should only be created by an
158       * EventGenerator!       * EventGenerator!
# Line 70  namespace LinuxSampler { Line 163  namespace LinuxSampler {
163          public:          public:
164              Event(){}              Event(){}
165              enum type_t {              enum type_t {
166                  type_note_on,                  type_note_on, ///< (real) MIDI note-on event
167                  type_note_off,                  type_note_off, ///< (real) MIDI note-off event
168                  type_pitchbend,                  type_pitchbend, ///< MIDI pitch bend wheel change event
169                  type_control_change,                  type_control_change, ///< MIDI CC event
170                  type_sysex,           ///< MIDI system exclusive message                  type_sysex,           ///< MIDI system exclusive message
171                  type_cancel_release,  ///< transformed either from a note-on or sustain-pedal-down event                  type_cancel_release_key, ///< transformed either from a (real) MIDI note-on or sustain-pedal-down event
172                  type_release,         ///< transformed either from a note-off or sustain-pedal-up event                  type_release_key,     ///< transformed either from a (real) MIDI note-off or sustain-pedal-up event
173                    type_release_note,    ///< transformed from a type_stop_note event
174                  type_channel_pressure, ///< a.k.a. aftertouch                  type_channel_pressure, ///< a.k.a. aftertouch
175                  type_note_pressure, ///< polyphonic key pressure (aftertouch)                  type_note_pressure, ///< polyphonic key pressure (aftertouch)
176                    type_play_note, ///< caused by a call to built-in instrument script function play_note()
177                    type_stop_note, ///< caused by a call to built-in instrument script function note_off()
178                    type_kill_note, ///< caused by a call to built-in instrument script function fade_out()
179                    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.)
180              } Type;              } Type;
181                enum synth_param_t {
182                    synth_param_volume,
183                    synth_param_volume_time,
184                    synth_param_volume_curve,
185                    synth_param_pitch,
186                    synth_param_pitch_time,
187                    synth_param_pitch_curve,
188                    synth_param_pan,
189                    synth_param_pan_time,
190                    synth_param_pan_curve,
191                    synth_param_cutoff,
192                    synth_param_resonance,
193                    synth_param_attack,
194                    synth_param_decay,
195                    synth_param_sustain,
196                    synth_param_release,
197                    synth_param_cutoff_attack,
198                    synth_param_cutoff_decay,
199                    synth_param_cutoff_sustain,
200                    synth_param_cutoff_release,
201                    synth_param_amp_lfo_depth,
202                    synth_param_amp_lfo_freq,
203                    synth_param_cutoff_lfo_depth,
204                    synth_param_cutoff_lfo_freq,
205                    synth_param_pitch_lfo_depth,
206                    synth_param_pitch_lfo_freq,
207                };
208                enum class ValueScope : unsigned char {
209                    /**
210                     * The new synthesis parameter value should be applied
211                     * relatively to itself (as normalized value range), and then
212                     * applied relatively against other sources (i.e. LFOs, EGs)
213                     * for the same synthesis parameter.
214                     */
215                    SELF_RELATIVE = 1,
216                    /**
217                     * The new synthesis paramater value of itself should be
218                     * replaced, and then applied relatively to other sources
219                     * (i.e. LFOs, EGs) for the same synthesis parameter.
220                     */
221                    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()
222                    /**
223                     * The new synthesis parameter value should be applied
224                     * relatively to itself (as normalized value range), and then
225                     * applied directly (as normalized value range) as final value
226                     * of this synthesis chain, thus all other sources (i.e. LFOs,
227                     * EGs) should entirely be ignored.
228                     */
229                    FINAL_SELF_RELATIVE = 2,
230                    /**
231                     * The new synthesis parameter value of itself should be
232                     * replaced, and then applied directly (as normalized value
233                     * range) as final value of this synthesis chain, thus all other
234                     * sources (i.e. LFOs, EGs) should entirely be ignored.
235                     */
236                    FINAL_NORM = 3,
237                    /**
238                     * Same as @c FINAL_NORM, but this one is already in the native
239                     * unit (i.e. seconds, Hz) of this synthesis parameter.
240                     */
241                    FINAL_NATIVE = 4,
242                };
243              union {              union {
244                  /// Note-on and note-off event specifics                  /// Note-on and note-off event specifics
245                  struct _Note {                  struct _Note {
# Line 88  namespace LinuxSampler { Line 248  namespace LinuxSampler {
248                      uint8_t Velocity;    ///< Trigger or release velocity of note-on / note-off event.                      uint8_t Velocity;    ///< Trigger or release velocity of note-on / note-off event.
249                      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).                      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).
250                      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).                      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).
251                        note_id_t ID;        ///< Unique numeric ID of the @c Note object associated with this note event.
252                        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.
253                      void*   pRegion;     ///< Engine specific pointer to instrument region                      void*   pRegion;     ///< Engine specific pointer to instrument region
254                  } Note;                  } Note;
255                  /// Control change event specifics                  /// Control change event specifics
# Line 108  namespace LinuxSampler { Line 270  namespace LinuxSampler {
270                  /// Channel Pressure (aftertouch) event specifics                  /// Channel Pressure (aftertouch) event specifics
271                  struct _ChannelPressure {                  struct _ChannelPressure {
272                      uint8_t Channel; ///< MIDI channel (0..15)                      uint8_t Channel; ///< MIDI channel (0..15)
273                        uint8_t Controller; ///< Should always be assigned to CTRL_TABLE_IDX_AFTERTOUCH.
274                      uint8_t Value;   ///< New aftertouch / pressure value for keys on that channel.                      uint8_t Value;   ///< New aftertouch / pressure value for keys on that channel.
275                  } ChannelPressure;                  } ChannelPressure;
276                  /// Polyphonic Note Pressure (aftertouch) event specifics                  /// Polyphonic Note Pressure (aftertouch) event specifics
# Line 116  namespace LinuxSampler { Line 279  namespace LinuxSampler {
279                      uint8_t Key;     ///< MIDI note number where key pressure (polyphonic aftertouch) changed.                      uint8_t Key;     ///< MIDI note number where key pressure (polyphonic aftertouch) changed.
280                      uint8_t Value;   ///< New pressure value for note.                      uint8_t Value;   ///< New pressure value for note.
281                  } NotePressure;                  } NotePressure;
282                    ///< Note synthesis parameter change event's specifics (used for real-time instrument script built-in functions which may alter synthesis parameters on note level).
283                    struct _NoteSynthParam {
284                        note_id_t     NoteID;   ///< ID of Note whose voices shall be modified.
285                        synth_param_t Type;     ///< Synthesis parameter which is to be changed.
286                        float         Delta;    ///< The value change that should be applied against the note's current synthesis parameter value.
287                        float         AbsValue; ///< New current absolute value of synthesis parameter (that is after @c Delta being applied).
288                        ValueScope    Scope;    ///< How @c Delta should be applied against @c AbsValue, and how @c AbsValue should then actually be applied to the synthesis chain.
289    
290                        inline bool isFinal() const { return Scope >= ValueScope::FINAL_SELF_RELATIVE; }
291                    } NoteSynthParam;
292              } Param;              } Param;
             /// Sampler format specific informations and variables.  
             union {  
                 /// Gigasampler/GigaStudio format specifics.  
                 struct _Gig {  
                     uint8_t DimMask; ///< May be used to override the Dimension zone to be selected for a new voice: each 1 bit means that respective bit shall be overridden by taking the respective bit from DimBits instead.  
                     uint8_t DimBits; ///< Used only in conjunction with DimMask: Dimension bits that shall be selected.  
                 } Gig;  
             } Format;  
293              EngineChannel* pEngineChannel; ///< Pointer to the EngineChannel where this event occured on, NULL means Engine global event (e.g. SysEx message).              EngineChannel* pEngineChannel; ///< Pointer to the EngineChannel where this event occured on, NULL means Engine global event (e.g. SysEx message).
294              MidiInputPort* pMidiInputPort; ///< Pointer to the MIDI input port on which this event occured (NOTE: currently only for global events, that is SysEx messages)              MidiInputPort* pMidiInputPort; ///< Pointer to the MIDI input port on which this event occured (NOTE: currently only for global events, that is SysEx messages)
295    
296                inline void Init() {
297                    //FIXME: probably we should memset() zero entire structure here, due to potential union initialization conflicts (see comment on ValueScope::RELATIVE)
298                    Param.Note.ID = 0;
299                    Param.Note.ParentNoteID = 0;
300                    Param.NoteSynthParam.NoteID = 0;
301                    Param.NoteSynthParam.Scope = ValueScope::RELATIVE;
302                }
303              inline int32_t FragmentPos() {              inline int32_t FragmentPos() {
304                  if (iFragmentPos >= 0) return iFragmentPos;                  if (iFragmentPos >= 0) return iFragmentPos;
305                  iFragmentPos = pEventGenerator->ToFragmentPos(TimeStamp);                  iFragmentPos = pEventGenerator->ToFragmentPos(TimeStamp);
# Line 137  namespace LinuxSampler { Line 309  namespace LinuxSampler {
309              inline void ResetFragmentPos() {              inline void ResetFragmentPos() {
310                  iFragmentPos = -1;                  iFragmentPos = -1;
311              }              }
312                inline void CopyTimeFrom(const Event& other) {
313                    TimeStamp = other.TimeStamp;
314                    iFragmentPos = other.iFragmentPos;
315                }
316                inline sched_time_t SchedTime() {
317                    return pEventGenerator->schedTimeAtCurrentFragmentStart() + FragmentPos();
318                }
319                inline static ValueScope scopeBy_FinalRelativeUnit(bool bFinal, bool bRelative, bool bNativeUnit) {
320                    if (!bFinal && bRelative)
321                        return ValueScope::SELF_RELATIVE;
322                    if (!bFinal)
323                        return ValueScope::RELATIVE;
324                    if (bRelative)
325                        return ValueScope::FINAL_SELF_RELATIVE;
326                    if (bNativeUnit)
327                        return ValueScope::FINAL_NATIVE;
328                    return ValueScope::FINAL_NORM;
329                }
330          protected:          protected:
331              typedef EventGenerator::time_stamp_t time_stamp_t;              typedef EventGenerator::time_stamp_t time_stamp_t;
332              Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);              Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);
# Line 148  namespace LinuxSampler { Line 338  namespace LinuxSampler {
338              int32_t         iFragmentPos;    ///< Position in the current fragment this event refers to.              int32_t         iFragmentPos;    ///< Position in the current fragment this event refers to.
339      };      };
340    
341        /**
342         * Used to sort timing relevant objects (i.e. events) into timing/scheduler
343         * queue. This class is just intended as base class and should be derived
344         * for its actual purpose (for the precise data type being scheduled).
345         */
346        class SchedulerNode : public RTAVLNode {
347        public:
348            using RTAVLNode::reset; // make reset() method public
349    
350            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.
351    
352            /// Required operator implementation for RTAVLTree class.
353            inline bool operator==(const SchedulerNode& other) const {
354                return this->scheduleTime == other.scheduleTime;
355            }
356    
357            /// Required operator implementation for RTAVLTree class.
358            inline bool operator<(const SchedulerNode& other) const {
359                return this->scheduleTime < other.scheduleTime;
360            }
361    
362            /// This is actually just for code readability.
363            inline RTAVLTreeBase* currentSchedulerQueue() const { return rtavlTree(); }
364        };
365    
366        /**
367         * Used to sort delayed MIDI events into a timing/scheduler queue. This
368         * object just contains the timing informations, the actual MIDI event is
369         * pointed by member variable @c itEvent.
370         */
371        class ScheduledEvent : public SchedulerNode {
372        public:
373            Pool<Event>::Iterator itEvent; ///< Points to the actual Event object being scheduled.
374        };
375    
376      class VMEventHandler;      class VMEventHandler;
377      class VMExecContext;      class VMExecContext;
378    
379        /**
380         * Maximum amount of child script handler instances one script handler is
381         * allowed to create by calling built-in script function fork().
382         */
383        #define MAX_FORK_PER_SCRIPT_HANDLER 8
384    
385      /** @brief Real-time instrument script event.      /** @brief Real-time instrument script event.
386       *       *
387       * Encapsulates one execution instance of a real-time instrument script for       * Encapsulates one execution instance of a real-time instrument script for
388       * exactly one script event handler (script event callback).       * exactly one script event handler (script event callback).
389         *
390         * This class derives from SchedulerNode for being able to be sorted efficiently
391         * by the script scheduler if the script was either a) calling the wait()
392         * script function or b) the script was auto suspended by the ScriptVM
393         * because the script was executing for too long. In both cases the
394         * scheduler has to sort the ScriptEvents in its execution queue according
395         * to the precise time the respective script execution instance needs to be
396         * resumed.
397       */       */
398      class ScriptEvent {      class ScriptEvent : public SchedulerNode {
399      public:      public:
400          Event cause; ///< Original external event that triggered this script event (i.e. MIDI note on event, MIDI CC event, etc.).          Event cause; ///< Copy of original external @c Event that triggered this script event (i.e. MIDI note on event, MIDI CC event, etc.).
401          int id; ///< Unique ID of the external event that triggered this cript event.          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.
402          VMEventHandler** handlers; ///< The script's event handlers (callbacks) to be processed (NULL terminated list).          VMEventHandler** handlers; ///< The script's event handlers (callbacks) to be processed (NULL terminated list).
403          VMExecContext* execCtx; ///< Script's current execution state (polyphonic variables and execution stack).          VMExecContext* execCtx; ///< Script's current execution state (polyphonic variables and execution stack).
404          int currentHandler; ///< Current index in 'handlers' list above.          int currentHandler; ///< Current index in 'handlers' list above.
405          int executionSlices; ///< Amount of times this script event has been executed by the ScriptVM runner class.          int executionSlices; ///< Amount of times this script event has been executed by the ScriptVM runner class.
406            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()).
407            VMEventHandlerType_t handlerType; ///< Native representation of built-in script variable $NI_CALLBACK_TYPE, reflecting the script event type of this script event.
408            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).
409            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).
410            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.
411            int forkIndex; ///< Only for fork() calls: distinguishment feature which is 0 for parent, 1 for 1st child, 2 for 2nd child, etc.
412    
413            void forkTo(ScriptEvent* e, bool bAutoAbort) const;
414            int countChildHandlers() const;
415            void addChildHandlerID(script_callback_id_t childID);
416      };      };
417    
418        /**
419         * Insert given @a node into the supplied timing @a queue with a scheduled
420         * timing position given by @a fragmentPosBase and @a microseconds, where
421         * @a microseconds reflects the amount of microseconds in future from "now"
422         * where the node shall be scheduled, and @a fragmentPos identifies the
423         * sample point within the current audio fragment cycle which shall be
424         * interpreted by this method to be "now".
425         *
426         * The meaning of @a fragmentPosBase becomes more important the larger
427         * the audio fragment size, and vice versa it becomes less important the
428         * smaller the audio fragment size.
429         *
430         * @param queue - destination scheduler queue
431         * @param node - node (i.e. event) to be inserted into the queue
432         * @param fragmentPosBase - sample point in current audio fragment to be "now"
433         * @param microseconds - timing of node from "now" (in microseconds)
434         */
435        template<typename T>
436        void EventGenerator::scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds) {
437            // round up (+1) if microseconds is not zero (i.e. because 44.1 kHz and
438            // 1 us would yield in < 1 and thus would be offset == 0)
439            const sched_time_t offset =
440                (microseconds != 0LL) ?
441                    1.f + (float(uiSampleRate) * (float(microseconds) / 1000000.f))
442                    : 0.f;
443            node.scheduleTime = uiTotalSamplesProcessed + fragmentPosBase + offset;
444            queue.insert(node);
445        }
446    
447  } // namespace LinuxSampler  } // namespace LinuxSampler
448    
449  #endif // __LS_EVENT_H__  #endif // __LS_EVENT_H__

Legend:
Removed from v.2600  
changed lines
  Added in v.3565

  ViewVC Help
Powered by ViewVC