/[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 890 by schoenebeck, Sat Jul 1 13:43:04 2006 UTC revision 2871 by schoenebeck, Sun Apr 10 18:22:23 2016 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, 2006 Christian Schoenebeck                        *   *   Copyright (C) 2005 - 2016 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    
33  namespace LinuxSampler {  namespace LinuxSampler {
34    
35      // just symbol prototyping      // just symbol prototyping
36      class Event;      class Event;
37        class SchedulerNode;
38        class ScriptEvent;
39        class ScheduledEvent;
40    
41        /**
42         * Data type used to schedule events sample point accurately both within, as
43         * well as beyond the scope of the current audio fragment cycle. The timing
44         * reflected by this data type is consecutively running for a very long
45         * time. Even with a sample rate of 96 kHz a scheduler time of this data
46         * type will not wrap before 6 million years. So in practice such time
47         * stamps are unique and will not repeat (unless the EventGenerator is
48         * reset).
49         */
50        typedef uint64_t sched_time_t;
51    
52      /**      /**
53       * Generates Event objects and is responsible for resolving the position       * Generates Event objects and is responsible for resolving the position
# Line 42  namespace LinuxSampler { Line 58  namespace LinuxSampler {
58              EventGenerator(uint SampleRate);              EventGenerator(uint SampleRate);
59              void UpdateFragmentTime(uint SamplesToProcess);              void UpdateFragmentTime(uint SamplesToProcess);
60              Event CreateEvent();              Event CreateEvent();
61                Event CreateEvent(int32_t FragmentPos);
62    
63                template<typename T>
64                void scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds);
65    
66                RTList<ScheduledEvent>::Iterator popNextScheduledEvent(RTAVLTree<ScheduledEvent>& queue, Pool<ScheduledEvent>& pool, sched_time_t end);
67                RTList<ScriptEvent>::Iterator popNextScheduledScriptEvent(RTAVLTree<ScriptEvent>& queue, Pool<ScriptEvent>& pool, sched_time_t end);
68    
69                /**
70                 * Returns the scheduler time for the first sample point of the next
71                 * audio fragment cycle.
72                 */
73                sched_time_t schedTimeAtCurrentFragmentEnd() const {
74                    return uiTotalSamplesProcessed + uiSamplesProcessed;
75                }
76    
77          protected:          protected:
78              typedef RTMath::time_stamp_t time_stamp_t;              typedef RTMath::time_stamp_t time_stamp_t;
79              inline int32_t ToFragmentPos(time_stamp_t TimeStamp) {              inline int32_t ToFragmentPos(time_stamp_t TimeStamp) {
# Line 56  namespace LinuxSampler { Line 88  namespace LinuxSampler {
88                  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.
89                  float        sample_ratio; ///< (Samples per cycle) / (Real time duration of cycle)                  float        sample_ratio; ///< (Samples per cycle) / (Real time duration of cycle)
90              } FragmentTime;              } FragmentTime;
91                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).
92      };      };
93    
94      /**      /**
95       * Events are usually caused by a MIDI source or an internal modulation       * Events are usually caused by a MIDI source or an internal modulation
96       * controller like LFO or EG. An event can only be created by an       * controller like LFO or EG. An event should only be created by an
97       * EventGenerator.       * EventGenerator!
98       *       *
99       * @see EventGenerator       * @see EventGenerator, ScriptEvent
100       */       */
101      class Event {      class Event {
102          public:          public:
# Line 75  namespace LinuxSampler { Line 108  namespace LinuxSampler {
108                  type_control_change,                  type_control_change,
109                  type_sysex,           ///< MIDI system exclusive message                  type_sysex,           ///< MIDI system exclusive message
110                  type_cancel_release,  ///< transformed either from a note-on or sustain-pedal-down event                  type_cancel_release,  ///< transformed either from a note-on or sustain-pedal-down event
111                  type_release          ///< transformed either from a note-off or sustain-pedal-up event                  type_release,         ///< transformed either from a note-off or sustain-pedal-up event
112                    type_channel_pressure, ///< a.k.a. aftertouch
113                    type_note_pressure, ///< polyphonic key pressure (aftertouch)
114              } Type;              } Type;
115              union {              union {
116                  /// Note-on and note-off event specifics                  /// Note-on and note-off event specifics
117                  struct _Note {                  struct _Note {
118                        uint8_t Channel;     ///< MIDI channel (0..15)
119                      uint8_t Key;         ///< MIDI key number of note-on / note-off event.                      uint8_t Key;         ///< MIDI key number of note-on / note-off event.
120                      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.
121                      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).
122                      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).
123                        void*   pRegion;     ///< Engine specific pointer to instrument region
124                  } Note;                  } Note;
125                  /// Control change event specifics                  /// Control change event specifics
126                  struct _CC {                  struct _CC {
127                        uint8_t Channel;     ///< MIDI channel (0..15)
128                      uint8_t Controller;  ///< MIDI controller number of control change event.                      uint8_t Controller;  ///< MIDI controller number of control change event.
129                      uint8_t Value;       ///< Controller Value of control change event.                      uint8_t Value;       ///< Controller Value of control change event.
130                  } CC;                  } CC;
131                  /// Pitchbend event specifics                  /// Pitchbend event specifics
132                  struct _Pitch {                  struct _Pitch {
133                        uint8_t Channel;     ///< MIDI channel (0..15)
134                      int16_t Pitch;       ///< Pitch value of pitchbend event.                      int16_t Pitch;       ///< Pitch value of pitchbend event.
135                  } Pitch;                  } Pitch;
136                  /// MIDI system exclusive event specifics                  /// MIDI system exclusive event specifics
137                  struct _Sysex {                  struct _Sysex {
138                      uint Size;           ///< Data length (in bytes) of MIDI system exclusive message.                      uint Size;           ///< Data length (in bytes) of MIDI system exclusive message.
139                  } Sysex;                  } Sysex;
140                    /// Channel Pressure (aftertouch) event specifics
141                    struct _ChannelPressure {
142                        uint8_t Channel; ///< MIDI channel (0..15)
143                        uint8_t Controller; ///< Should always be assigned to CTRL_TABLE_IDX_AFTERTOUCH.
144                        uint8_t Value;   ///< New aftertouch / pressure value for keys on that channel.
145                    } ChannelPressure;
146                    /// Polyphonic Note Pressure (aftertouch) event specifics
147                    struct _NotePressure {
148                        uint8_t Channel; ///< MIDI channel (0..15)
149                        uint8_t Key;     ///< MIDI note number where key pressure (polyphonic aftertouch) changed.
150                        uint8_t Value;   ///< New pressure value for note.
151                    } NotePressure;
152              } Param;              } Param;
153                /// Sampler format specific informations and variables.
154                union {
155                    /// Gigasampler/GigaStudio format specifics.
156                    struct _Gig {
157                        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.
158                        uint8_t DimBits; ///< Used only in conjunction with DimMask: Dimension bits that shall be selected.
159                    } Gig;
160                } Format;
161              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).
162                MidiInputPort* pMidiInputPort; ///< Pointer to the MIDI input port on which this event occured (NOTE: currently only for global events, that is SysEx messages)
163    
164              inline int32_t FragmentPos() {              inline int32_t FragmentPos() {
165                  if (iFragmentPos >= 0) return iFragmentPos;                  if (iFragmentPos >= 0) return iFragmentPos;
# Line 113  namespace LinuxSampler { Line 173  namespace LinuxSampler {
173          protected:          protected:
174              typedef EventGenerator::time_stamp_t time_stamp_t;              typedef EventGenerator::time_stamp_t time_stamp_t;
175              Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);              Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);
176                Event(EventGenerator* pGenerator, int32_t FragmentPos);
177              friend class EventGenerator;              friend class EventGenerator;
178          private:          private:
179              EventGenerator* pEventGenerator; ///< Creator of the event.              EventGenerator* pEventGenerator; ///< Creator of the event.
# Line 120  namespace LinuxSampler { Line 181  namespace LinuxSampler {
181              int32_t         iFragmentPos;    ///< Position in the current fragment this event refers to.              int32_t         iFragmentPos;    ///< Position in the current fragment this event refers to.
182      };      };
183    
184        /**
185         * Used to sort timing relevant objects (i.e. events) into timing/scheduler
186         * queue. This class is just intended as base class and should be derived
187         * for its actual purpose (for the precise data type being scheduled).
188         */
189        class SchedulerNode : public RTAVLNode {
190        public:
191            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.
192    
193            /// Required operator implementation for RTAVLTree class.
194            inline bool operator==(const SchedulerNode& other) const {
195                return this->scheduleTime == other.scheduleTime;
196            }
197    
198            /// Required operator implementation for RTAVLTree class.
199            inline bool operator<(const SchedulerNode& other) const {
200                return this->scheduleTime < other.scheduleTime;
201            }
202        };
203    
204        /**
205         * Used to sort delayed MIDI events into a timing/scheduler queue. This
206         * object just contains the timing informations, the actual MIDI event is
207         * pointed by member variable @c itEvent.
208         */
209        class ScheduledEvent : public SchedulerNode {
210        public:
211            Pool<Event>::Iterator itEvent; ///< Points to the actual Event object being scheduled.
212        };
213    
214        class VMEventHandler;
215        class VMExecContext;
216    
217        /** @brief Real-time instrument script event.
218         *
219         * Encapsulates one execution instance of a real-time instrument script for
220         * exactly one script event handler (script event callback).
221         *
222         * This class derives from SchedulerNode for being able to be sorted efficiently
223         * by the script scheduler if the script was either a) calling the wait()
224         * script function or b) the script was auto suspended by the ScriptVM
225         * because the script was executing for too long. In both cases the
226         * scheduler has to sort the ScriptEvents in its execution queue according
227         * to the precise time the respective script execution instance needs to be
228         * resumed.
229         */
230        class ScriptEvent : public SchedulerNode {
231        public:
232            Event cause; ///< Original external event that triggered this script event (i.e. MIDI note on event, MIDI CC event, etc.).
233            int id; ///< Unique ID of the external event that triggered this script event.
234            VMEventHandler** handlers; ///< The script's event handlers (callbacks) to be processed (NULL terminated list).
235            VMExecContext* execCtx; ///< Script's current execution state (polyphonic variables and execution stack).
236            int currentHandler; ///< Current index in 'handlers' list above.
237            int executionSlices; ///< Amount of times this script event has been executed by the ScriptVM runner class.
238        };
239    
240        /**
241         * Insert given @a node into the supplied timing @a queue with a scheduled
242         * timing position given by @a fragmentPosBase and @a microseconds, where
243         * @a microseconds reflects the amount microseconds in future from "now"
244         * where the node shall be scheduled, and @a fragmentPos identifies the
245         * sample point within the current audio fragment cycle which shall be
246         * interpreted by this method to be "now".
247         *
248         * The meaning of @a fragmentPosBase becomes more important the larger
249         * the audio fragment size, and vice versa it bcomes less important the
250         * smaller the audio fragment size.
251         *
252         * @param queue - destination scheduler queue
253         * @param node - node (i.e. event) to be inserted into the queue
254         * @param fragmentPosBase - sample point in current audio fragment to be "now"
255         * @param microseconds - timing of node from "now" (in microseconds)
256         */
257        template<typename T>
258        void EventGenerator::scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds) {
259            node.scheduleTime = uiTotalSamplesProcessed + fragmentPosBase + float(uiSampleRate) * (float(microseconds) / 1000000.f);
260            queue.insert(node);
261        }
262    
263  } // namespace LinuxSampler  } // namespace LinuxSampler
264    
265  #endif // __LS_EVENT_H__  #endif // __LS_EVENT_H__

Legend:
Removed from v.890  
changed lines
  Added in v.2871

  ViewVC Help
Powered by ViewVC