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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2871 - (hide annotations) (download)
Sun Apr 10 18:22:23 2016 UTC (8 years ago) by schoenebeck
File size: 8913 byte(s)
* All engines: Implemented scheduler for delayed MIDI events and for
  suspended real-time instrument scripts.
* Real-Time instrument scripts: Implemented support for built-in "wait()"
  function's "duration-us" argument, thus scripts using this function are
  now correctly resumed after the requested amount of microseconds.
* Real-Time instrument scripts: Implemented support for built-in
  "play_note()" function's "duration-us" argument, thus notes triggered
  with this argument are now correctly released after the requested amount
  of microseconds.
* Real-Time instrument scripts: Fixed crash which happened when trying to
  reference an undeclared script variable.
* Real-Time instrument scripts: Script events were not cleared when
  engine channel was reset, potentially causing undefined behavior.
* All engines: Attempt to partly fix resetting engine channels vs.
  resetting engine, an overall cleanup of the Reset*(),
  ConnectAudioDevice(), DisconnectAudioDevice() API methods would still be
  desirable though, because the current situation is still inconsistent
  and error prone.
* Bumped version (2.0.0.svn2).

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 2871 * Copyright (C) 2005 - 2016 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     #include "Event.h"
25    
26     namespace LinuxSampler {
27    
28     /**
29     * Create an EventGenerator.
30     *
31     * @param SampleRate - sample rate of the sampler engine's audio output
32     * signal (in Hz)
33     */
34     EventGenerator::EventGenerator(uint SampleRate) {
35     uiSampleRate = SampleRate;
36     uiSamplesProcessed = 0;
37 schoenebeck 328 FragmentTime.end = RTMath::CreateTimeStamp();
38 schoenebeck 2871 uiTotalSamplesProcessed = 0;
39 schoenebeck 53 }
40    
41     /**
42     * Updates the time stamps for the beginning and end of the current audio
43     * fragment. This is needed to be able to calculate the respective sample
44     * point later to which an event belongs to.
45     *
46     * @param SamplesToProcess - number of sample points to process in this
47     * audio fragment cycle
48     */
49     void EventGenerator::UpdateFragmentTime(uint SamplesToProcess) {
50 schoenebeck 2871 // update total amount of sample points being processed since this object was created
51     uiTotalSamplesProcessed += uiSamplesProcessed;
52 schoenebeck 53 // update time stamp for this audio fragment cycle
53     FragmentTime.begin = FragmentTime.end;
54 schoenebeck 328 FragmentTime.end = RTMath::CreateTimeStamp();
55 schoenebeck 53 // recalculate sample ratio for this audio fragment
56     time_stamp_t fragmentDuration = FragmentTime.end - FragmentTime.begin;
57     FragmentTime.sample_ratio = (float) uiSamplesProcessed / (float) fragmentDuration;
58     // store amount of samples to process for the next cycle
59     uiSamplesProcessed = SamplesToProcess;
60     }
61 schoenebeck 2871
62     /**
63     * Get the next scheduled MIDI event (the one with the lowest time value)
64     * for the current audio fragment cycle and remove it from the queue. This
65     * method will not return any event scheduled past the current audio
66     * fragment boundary.
67     *
68     * @param queue - where the MIDI events are scheduled on
69     * @param pool - used to allocate and deallocate ScheduledEvent objects
70     * @param end - you @b MUST always pass EventGenerator::schedTimeAtCurrentFragmentEnd()
71     * here reflecting the current audio fragment's scheduler end time
72     */
73     RTList<ScheduledEvent>::Iterator EventGenerator::popNextScheduledEvent(RTAVLTree<ScheduledEvent>& queue, Pool<ScheduledEvent>& pool, sched_time_t end) {
74     if (queue.isEmpty())
75     return RTList<ScheduledEvent>::Iterator(); // return invalid iterator
76     ScheduledEvent& e = queue.lowest();
77     if (e.scheduleTime >= end)
78     return RTList<ScheduledEvent>::Iterator(); // no event scheduled before 'end'
79     RTList<ScheduledEvent>::Iterator itEvent = pool.fromPtr(&e);
80     queue.erase(e);
81     if (!itEvent || !itEvent->itEvent) {
82     dmsg(1,("EventGenerator::popNextScheduledEvent(): !itEvent\n"));
83     return itEvent; // should never happen at this point, but just to be sure
84     }
85     if (!itEvent->itEvent) {
86     dmsg(1,("EventGenerator::popNextScheduledEvent(): !itEvent->itEvent\n"));
87     return itEvent; // should never happen at this point, but just to be sure
88     }
89 schoenebeck 53
90 schoenebeck 2871 // update position of this event in the current audio fragment
91     // (since calling scheduleAheadMicroSec() will relate to this)
92     itEvent->itEvent->iFragmentPos = uiSamplesProcessed - (end - itEvent->scheduleTime);
93     // safety first: fragment boundary sanity checks
94     if (itEvent->itEvent->iFragmentPos < 0)
95     itEvent->itEvent->iFragmentPos = 0;
96     if (itEvent->itEvent->iFragmentPos >= uiSamplesProcessed)
97     itEvent->itEvent->iFragmentPos = uiSamplesProcessed - 1;
98    
99     return itEvent;
100     }
101    
102 schoenebeck 53 /**
103 schoenebeck 2871 * Get the next instrument script event (the one with the lowest time value)
104     * for the current audio fragment cycle and remove it from the queue. This
105     * method will not return any event scheduled past the current audio
106     * fragment boundary.
107     *
108     * @param queue - where the instrument script events are scheduled on
109     * @param pool - used to allocate and deallocate ScriptEvent objects
110     * @param end - you @b MUST always pass EventGenerator::schedTimeAtCurrentFragmentEnd()
111     * here reflecting the current audio fragment's scheduler end time
112     */
113     RTList<ScriptEvent>::Iterator EventGenerator::popNextScheduledScriptEvent(RTAVLTree<ScriptEvent>& queue, Pool<ScriptEvent>& pool, sched_time_t end) {
114     if (queue.isEmpty())
115     return RTList<ScriptEvent>::Iterator(); // return invalid iterator
116     ScriptEvent& e = queue.lowest();
117     if (e.scheduleTime >= end)
118     return RTList<ScriptEvent>::Iterator(); // no event scheduled before 'end'
119     RTList<ScriptEvent>::Iterator itEvent = pool.fromPtr(&e);
120     queue.erase(e);
121     if (!itEvent) { // should never happen at this point, but just to be sure
122     dmsg(1,("EventGenerator::popNextScheduledScriptEvent(): !itEvent\n"));
123     return itEvent;
124     }
125    
126     // update position of this event in the current audio fragment
127     // (since calling scheduleAheadMicroSec() will relate to this)
128     itEvent->cause.iFragmentPos = uiSamplesProcessed - (end - itEvent->scheduleTime);
129     // safety first: fragment boundary sanity checks
130     if (itEvent->cause.iFragmentPos < 0)
131     itEvent->cause.iFragmentPos = 0;
132     if (itEvent->cause.iFragmentPos >= uiSamplesProcessed)
133     itEvent->cause.iFragmentPos = uiSamplesProcessed - 1;
134    
135     return itEvent;
136     }
137    
138     /**
139 schoenebeck 53 * Create a new event with the current time as time stamp.
140     */
141     Event EventGenerator::CreateEvent() {
142 schoenebeck 328 return Event(this, RTMath::CreateTimeStamp());
143 schoenebeck 53 }
144    
145     /**
146 schoenebeck 906 * Create a new event for the given sample point position in the current
147     * audio fragment.
148     *
149     * @param FragmentPos - actual sample point position in the current
150     * audio fragment to which the new event belongs to
151     */
152     Event EventGenerator::CreateEvent(int32_t FragmentPos) {
153     return Event(this, FragmentPos);
154     }
155    
156     /**
157 schoenebeck 53 * Will be called by an EventGenerator to create a new Event.
158 schoenebeck 906 * This Constructor expects a time stamp. The actual sample point
159     * position to which this event belongs to will be calculated later
160     * when FragmentPos() was called the first time.
161     *
162     * @param pGenerator - creator of this event
163     * @param Time - time stamp on which this event occured
164 schoenebeck 53 */
165     Event::Event(EventGenerator* pGenerator, time_stamp_t Time) {
166     pEventGenerator = pGenerator;
167     TimeStamp = Time;
168     iFragmentPos = -1;
169     }
170    
171 schoenebeck 906 /**
172     * Will be called by an EventGenerator to create a new Event.
173     * This constructor expects the final sample point position to which
174     * this event belongs to.
175     *
176     * @param pGenerator - creator of this event
177     * @param FragmentPos - actual sample point position in the current
178     * audio fragment to which this event belongs to
179     */
180     Event::Event(EventGenerator* pGenerator, int32_t FragmentPos) {
181     pEventGenerator = pGenerator;
182     iFragmentPos = FragmentPos;
183     }
184    
185 schoenebeck 53 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC