/[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 2948 by schoenebeck, Fri Jul 15 15:29:04 2016 UTC revision 3688 by schoenebeck, Thu Jan 2 23:47:42 2020 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 - 2016 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2020 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 31  Line 31 
31  #include "../EngineChannel.h"  #include "../EngineChannel.h"
32  #include "../../scriptvm/common.h"  #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
# Line 58  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    
# Line 158  namespace LinuxSampler { Line 167  namespace LinuxSampler {
167                  type_note_off, ///< (real) MIDI note-off event                  type_note_off, ///< (real) MIDI note-off event
168                  type_pitchbend, ///< MIDI pitch bend wheel change event                  type_pitchbend, ///< MIDI pitch bend wheel change event
169                  type_control_change, ///< MIDI CC event                  type_control_change, ///< MIDI CC event
170                    type_rpn, ///< Transformed from a raw RPN CC MIDI event.
171                    type_nrpn, ///< Transformed from a raw NRPN CC MIDI event.
172                  type_sysex,           ///< MIDI system exclusive message                  type_sysex,           ///< MIDI system exclusive message
173                  type_cancel_release_key, ///< transformed either from a (real) MIDI note-on or sustain-pedal-down event                  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                  type_release_key,     ///< transformed either from a (real) MIDI note-off or sustain-pedal-up event
# Line 166  namespace LinuxSampler { Line 177  namespace LinuxSampler {
177                  type_note_pressure, ///< polyphonic key pressure (aftertouch)                  type_note_pressure, ///< polyphonic key pressure (aftertouch)
178                  type_play_note, ///< caused by a call to built-in instrument script function play_note()                  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()                  type_stop_note, ///< caused by a call to built-in instrument script function note_off()
180                    type_kill_note, ///< caused by a call to built-in instrument script function fade_out()
181                  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.)                  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              } Type;              } Type;
183              enum synth_param_t {              enum synth_param_t {
184                  synth_param_volume,                  synth_param_volume,
185                    synth_param_volume_time,
186                    synth_param_volume_curve,
187                  synth_param_pitch,                  synth_param_pitch,
188                    synth_param_pitch_time,
189                    synth_param_pitch_curve,
190                  synth_param_pan,                  synth_param_pan,
191                    synth_param_pan_time,
192                    synth_param_pan_curve,
193                  synth_param_cutoff,                  synth_param_cutoff,
194                  synth_param_resonance,                  synth_param_resonance,
195                    synth_param_attack,
196                    synth_param_decay,
197                    synth_param_sustain,
198                    synth_param_release,
199                    synth_param_cutoff_attack,
200                    synth_param_cutoff_decay,
201                    synth_param_cutoff_sustain,
202                    synth_param_cutoff_release,
203                    synth_param_amp_lfo_depth,
204                    synth_param_amp_lfo_freq,
205                    synth_param_cutoff_lfo_depth,
206                    synth_param_cutoff_lfo_freq,
207                    synth_param_pitch_lfo_depth,
208                    synth_param_pitch_lfo_freq,
209                };
210                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                    SELF_RELATIVE = 1,
218                    /**
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                    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                    /**
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                    FINAL_SELF_RELATIVE = 2,
232                    /**
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                    FINAL_NORM = 3,
239                    /**
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                    FINAL_NATIVE = 4,
244              };              };
245              union {              union {
246                  /// Note-on and note-off event specifics                  /// Note-on and note-off event specifics
# Line 193  namespace LinuxSampler { Line 260  namespace LinuxSampler {
260                      uint8_t Controller;  ///< MIDI controller number of control change event.                      uint8_t Controller;  ///< MIDI controller number of control change event.
261                      uint8_t Value;       ///< Controller Value of control change event.                      uint8_t Value;       ///< Controller Value of control change event.
262                  } CC;                  } CC;
263                    /// 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                  /// Pitchbend event specifics                  /// Pitchbend event specifics
274                  struct _Pitch {                  struct _Pitch {
275                      uint8_t Channel;     ///< MIDI channel (0..15)                      uint8_t Channel;     ///< MIDI channel (0..15)
# Line 219  namespace LinuxSampler { Line 296  namespace LinuxSampler {
296                      note_id_t     NoteID;   ///< ID of Note whose voices shall be modified.                      note_id_t     NoteID;   ///< ID of Note whose voices shall be modified.
297                      synth_param_t Type;     ///< Synthesis parameter which is to be changed.                      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.                      float         Delta;    ///< The value change that should be applied against the note's current synthesis parameter value.
                     bool          Relative; ///< Whether @c Delta should be applied relatively against the note's current synthesis parameter value (false means the paramter's current value is simply replaced by Delta).  
299                      float         AbsValue; ///< New current absolute value of synthesis parameter (that is after @c Delta being applied).                      float         AbsValue; ///< New current absolute value of synthesis parameter (that is after @c Delta being applied).
300                        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                  } NoteSynthParam;                  } NoteSynthParam;
304              } Param;              } Param;
305              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).
306              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)
307    
308              inline void Init() {              inline void Init() {
309                  Param.Note.ID = 0;                  memset(&Param, 0, sizeof(Param));
                 Param.Note.ParentNoteID = 0;  
                 Param.NoteSynthParam.NoteID = 0;  
310              }              }
311              inline int32_t FragmentPos() {              inline int32_t FragmentPos() {
312                  if (iFragmentPos >= 0) return iFragmentPos;                  if (iFragmentPos >= 0) return iFragmentPos;
# Line 247  namespace LinuxSampler { Line 324  namespace LinuxSampler {
324              inline sched_time_t SchedTime() {              inline sched_time_t SchedTime() {
325                  return pEventGenerator->schedTimeAtCurrentFragmentStart() + FragmentPos();                  return pEventGenerator->schedTimeAtCurrentFragmentStart() + FragmentPos();
326              }              }
327                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          protected:          protected:
339              typedef EventGenerator::time_stamp_t time_stamp_t;              typedef EventGenerator::time_stamp_t time_stamp_t;
340              Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);              Event(EventGenerator* pGenerator, EventGenerator::time_stamp_t Time);
# Line 258  namespace LinuxSampler { Line 346  namespace LinuxSampler {
346              int32_t         iFragmentPos;    ///< Position in the current fragment this event refers to.              int32_t         iFragmentPos;    ///< Position in the current fragment this event refers to.
347      };      };
348    
349        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      /**      /**
376       * Used to sort timing relevant objects (i.e. events) into timing/scheduler       * 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       * queue. This class is just intended as base class and should be derived
# Line 296  namespace LinuxSampler { Line 410  namespace LinuxSampler {
410      class VMEventHandler;      class VMEventHandler;
411      class VMExecContext;      class VMExecContext;
412    
413        /**
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      /** @brief Real-time instrument script event.      /** @brief Real-time instrument script event.
420       *       *
421       * Encapsulates one execution instance of a real-time instrument script for       * Encapsulates one execution instance of a real-time instrument script for
# Line 319  namespace LinuxSampler { Line 439  namespace LinuxSampler {
439          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.
440          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()).          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          VMEventHandlerType_t handlerType; ///< Native representation of built-in script variable $NI_CALLBACK_TYPE, reflecting the script event type of this script event.          VMEventHandlerType_t handlerType; ///< Native representation of built-in script variable $NI_CALLBACK_TYPE, reflecting the script event type of this script event.
442            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).
443            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).
444            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.
445            int forkIndex; ///< Only for fork() calls: distinguishment feature which is 0 for parent, 1 for 1st child, 2 for 2nd child, etc.
446    
447            void forkTo(ScriptEvent* e, bool bAutoAbort) const;
448            int countChildHandlers() const;
449            void addChildHandlerID(script_callback_id_t childID);
450      };      };
451    
452      /**      /**
# Line 330  namespace LinuxSampler { Line 458  namespace LinuxSampler {
458       * interpreted by this method to be "now".       * interpreted by this method to be "now".
459       *       *
460       * The meaning of @a fragmentPosBase becomes more important the larger       * The meaning of @a fragmentPosBase becomes more important the larger
461       * the audio fragment size, and vice versa it bcomes less important the       * the audio fragment size, and vice versa it becomes less important the
462       * smaller the audio fragment size.       * smaller the audio fragment size.
463       *       *
464       * @param queue - destination scheduler queue       * @param queue - destination scheduler queue
# Line 340  namespace LinuxSampler { Line 468  namespace LinuxSampler {
468       */       */
469      template<typename T>      template<typename T>
470      void EventGenerator::scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds) {      void EventGenerator::scheduleAheadMicroSec(RTAVLTree<T>& queue, T& node, int32_t fragmentPosBase, uint64_t microseconds) {
471          node.scheduleTime = uiTotalSamplesProcessed + fragmentPosBase + float(uiSampleRate) * (float(microseconds) / 1000000.f);          // round up (+1) if microseconds is not zero (i.e. because 44.1 kHz and
472            // 1 us would yield in < 1 and thus would be offset == 0)
473            const sched_time_t offset =
474                (microseconds != 0LL) ?
475                    1.f + (float(uiSampleRate) * (float(microseconds) / 1000000.f))
476                    : 0.f;
477            node.scheduleTime = uiTotalSamplesProcessed + fragmentPosBase + offset;
478          queue.insert(node);          queue.insert(node);
479      }      }
480    

Legend:
Removed from v.2948  
changed lines
  Added in v.3688

  ViewVC Help
Powered by ViewVC