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

Contents of /linuxsampler/trunk/src/engines/common/InstrumentScriptVMFunctions.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2630 - (show annotations) (download)
Fri Jun 13 15:01:06 2014 UTC (9 years, 10 months ago) by schoenebeck
File size: 11028 byte(s)
* Implemented built-in instrument script function "set_event_mark()".
* Implemented built-in instrument script function "delete_event_mark()".
* Implemented built-in instrument script function "by_marks()".
* Added built-in instrument script int const variables $MARK_1 to $MARK_28.
* Built-in instrument script functions "ignore_event()", "note_off()" and
  "gig_set_dim_zone()" now also accept an array of event IDs as argument
  (i.e. return value of new script function "by_marks()").
* Bumped version (1.0.0.svn53).

1 /*
2 * Copyright (c) 2014 Christian Schoenebeck
3 *
4 * http://www.linuxsampler.org
5 *
6 * This file is part of LinuxSampler and released under the same terms.
7 * See README file for details.
8 */
9
10 #include "InstrumentScriptVMFunctions.h"
11 #include "InstrumentScriptVM.h"
12 #include "../AbstractEngineChannel.h"
13
14 namespace LinuxSampler {
15
16 InstrumentScriptVMFunction_play_note::InstrumentScriptVMFunction_play_note(InstrumentScriptVM* parent)
17 : m_vm(parent)
18 {
19 }
20
21 VMFnResult* InstrumentScriptVMFunction_play_note::exec(VMFnArgs* args) {
22 int note = args->arg(0)->asInt()->evalInt();
23 int velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;
24 int sampleoffset = (args->argsCount() >= 3) ? args->arg(2)->asInt()->evalInt() : 0;
25 int duration = (args->argsCount() >= 4) ? args->arg(3)->asInt()->evalInt() : 0; //TODO: once -1 is implemented, it might be a better default value instead of 0
26
27 if (note < 0 || note > 127) {
28 errMsg("play_note(): argument 1 is an invalid note number");
29 return errorResult(-1);
30 }
31
32 if (velocity < 0 || velocity > 127) {
33 errMsg("play_note(): argument 2 is an invalid velocity value");
34 return errorResult(-1);
35 }
36
37 if (sampleoffset < 0) {
38 errMsg("play_note(): argument 3 may not be a negative sample offset");
39 return errorResult(-1);
40 } else if (sampleoffset != 0) {
41 wrnMsg("play_note(): argument 3 does not support a sample offset other than 0 yet");
42 }
43
44 if (duration < -1) {
45 errMsg("play_note(): argument 4 must be a duration value of at least -1 or higher");
46 return errorResult(-1);
47 } else if (duration == -1) {
48 wrnMsg("play_note(): argument 4 does not support special value -1 as duration yet");
49 } else if (duration != 0) {
50 wrnMsg("play_note(): argument 4 does not support any other value as 0 as duration yet");
51 }
52
53 AbstractEngineChannel* pEngineChannel =
54 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
55
56 Event e = m_vm->m_event->cause;
57 e.Type = Event::type_note_on;
58 e.Param.Note.Key = note;
59 e.Param.Note.Velocity = velocity;
60 memset(&e.Format, 0, sizeof(e.Format)); // init format speific stuff with zero
61
62 int id = pEngineChannel->ScheduleEvent(&e, duration);
63
64 return successResult(id);
65 }
66
67 InstrumentScriptVMFunction_set_controller::InstrumentScriptVMFunction_set_controller(InstrumentScriptVM* parent)
68 : m_vm(parent)
69 {
70 }
71
72 VMFnResult* InstrumentScriptVMFunction_set_controller::exec(VMFnArgs* args) {
73 int controller = args->arg(0)->asInt()->evalInt();
74 int value = args->arg(1)->asInt()->evalInt();
75
76 AbstractEngineChannel* pEngineChannel =
77 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
78
79 Event e = m_vm->m_event->cause;
80 memset(&e.Format, 0, sizeof(e.Format)); // init format speific stuff with zero
81 if (controller == CTRL_TABLE_IDX_AFTERTOUCH) {
82 e.Type = Event::type_channel_pressure;
83 e.Param.ChannelPressure.Value = value & 127;
84 } else if (controller == CTRL_TABLE_IDX_PITCHBEND) {
85 e.Type = Event::type_pitchbend;
86 e.Param.Pitch.Pitch = value;
87 } else if (controller >= 0 && controller <= 127) {
88 e.Type = Event::type_control_change;
89 e.Param.CC.Controller = controller;
90 e.Param.CC.Value = value;
91 } else {
92 errMsg("set_controller(): argument 1 is an invalid controller");
93 return errorResult();
94 }
95
96 int id = pEngineChannel->ScheduleEvent(&e, 0);
97
98 return successResult(id);
99 }
100
101 InstrumentScriptVMFunction_ignore_event::InstrumentScriptVMFunction_ignore_event(InstrumentScriptVM* parent)
102 : m_vm(parent)
103 {
104 }
105
106 bool InstrumentScriptVMFunction_ignore_event::acceptsArgType(int iArg, ExprType_t type) const {
107 return type == INT_EXPR || type == INT_ARR_EXPR;
108 }
109
110 VMFnResult* InstrumentScriptVMFunction_ignore_event::exec(VMFnArgs* args) {
111 AbstractEngineChannel* pEngineChannel =
112 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
113
114 if (args->arg(0)->exprType() == INT_EXPR) {
115 int id = args->arg(0)->asInt()->evalInt();
116 if (id < 0) {
117 wrnMsg("ignore_event(): argument may not be a negative event ID");
118 return successResult();
119 }
120 pEngineChannel->IgnoreEvent(id);
121 } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
122 VMIntArrayExpr* ids = args->arg(0)->asIntArray();
123 for (int i = 0; i < ids->arraySize(); ++i) {
124 int id = ids->evalIntElement(i);
125 pEngineChannel->IgnoreEvent(id);
126 }
127 }
128
129 return successResult();
130 }
131
132 InstrumentScriptVMFunction_ignore_controller::InstrumentScriptVMFunction_ignore_controller(InstrumentScriptVM* parent)
133 : m_vm(parent)
134 {
135 }
136
137 VMFnResult* InstrumentScriptVMFunction_ignore_controller::exec(VMFnArgs* args) {
138 int id = (args->argsCount() >= 1) ? args->arg(0)->asInt()->evalInt() : m_vm->m_event->id;
139 if (id < 0) {
140 wrnMsg("ignore_controller(): argument may not be a negative event ID");
141 return successResult();
142 }
143
144 AbstractEngineChannel* pEngineChannel =
145 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
146
147 pEngineChannel->IgnoreEvent(id);
148
149 return successResult();
150 }
151
152 InstrumentScriptVMFunction_note_off::InstrumentScriptVMFunction_note_off(InstrumentScriptVM* parent)
153 : m_vm(parent)
154 {
155 }
156
157 bool InstrumentScriptVMFunction_note_off::acceptsArgType(int iArg, ExprType_t type) const {
158 return type == INT_EXPR || type == INT_ARR_EXPR;
159 }
160
161 VMFnResult* InstrumentScriptVMFunction_note_off::exec(VMFnArgs* args) {
162 AbstractEngineChannel* pEngineChannel =
163 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
164
165 int velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;
166 if (velocity < 0 || velocity > 127) {
167 errMsg("note_off(): argument 2 is an invalid velocity value");
168 return errorResult();
169 }
170
171 if (args->arg(0)->exprType() == INT_EXPR) {
172 int id = args->arg(0)->asInt()->evalInt();
173 if (id < 0) {
174 wrnMsg("note_off(): argument 1 may not be a negative event ID");
175 return successResult();
176 }
177
178 RTList<Event>::Iterator itEvent = pEngineChannel->pEngine->EventByID(id);
179 if (!itEvent) return successResult();
180
181 Event e = *itEvent;
182 e.Type = Event::type_note_off;
183 e.Param.Note.Velocity = velocity;
184 memset(&e.Format, 0, sizeof(e.Format)); // init format speific stuff with zero
185
186 int releaseEventID = pEngineChannel->ScheduleEvent(&e, 0);
187 } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
188 VMIntArrayExpr* ids = args->arg(0)->asIntArray();
189 for (int i = 0; i < ids->arraySize(); ++i) {
190 int id = ids->evalIntElement(i);
191
192 RTList<Event>::Iterator itEvent = pEngineChannel->pEngine->EventByID(id);
193 if (!itEvent) continue;
194
195 Event e = *itEvent;
196 e.Type = Event::type_note_off;
197 e.Param.Note.Velocity = velocity;
198 memset(&e.Format, 0, sizeof(e.Format)); // init format speific stuff with zero
199
200 int releaseEventID = pEngineChannel->ScheduleEvent(&e, 0);
201 }
202 }
203
204 return successResult();
205 }
206
207 InstrumentScriptVMFunction_set_event_mark::InstrumentScriptVMFunction_set_event_mark(InstrumentScriptVM* parent)
208 : m_vm(parent)
209 {
210 }
211
212 VMFnResult* InstrumentScriptVMFunction_set_event_mark::exec(VMFnArgs* args) {
213 int eventID = args->arg(0)->asInt()->evalInt();
214 int groupID = args->arg(1)->asInt()->evalInt();
215
216 if (groupID < 0 || groupID >= INSTR_SCRIPT_EVENT_GROUPS) {
217 errMsg("set_event_mark(): argument 2 is an invalid group id");
218 return errorResult();
219 }
220
221 AbstractEngineChannel* pEngineChannel =
222 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
223
224 RTList<Event>::Iterator itEvent = pEngineChannel->pEngine->EventByID(eventID);
225 if (!itEvent) return successResult();
226
227 pEngineChannel->pScript->eventGroups[groupID].insert(eventID);
228
229 return successResult();
230 }
231
232 InstrumentScriptVMFunction_delete_event_mark::InstrumentScriptVMFunction_delete_event_mark(InstrumentScriptVM* parent)
233 : m_vm(parent)
234 {
235 }
236
237 VMFnResult* InstrumentScriptVMFunction_delete_event_mark::exec(VMFnArgs* args) {
238 int eventID = args->arg(0)->asInt()->evalInt();
239 int groupID = args->arg(1)->asInt()->evalInt();
240
241 if (groupID < 0 || groupID >= INSTR_SCRIPT_EVENT_GROUPS) {
242 errMsg("delete_event_mark(): argument 2 is an invalid group id");
243 return errorResult();
244 }
245
246 AbstractEngineChannel* pEngineChannel =
247 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
248
249 pEngineChannel->pScript->eventGroups[groupID].erase(eventID);
250
251 return successResult();
252 }
253
254 InstrumentScriptVMFunction_by_marks::InstrumentScriptVMFunction_by_marks(InstrumentScriptVM* parent)
255 : m_vm(parent)
256 {
257 }
258
259 int InstrumentScriptVMFunction_by_marks::Result::arraySize() const {
260 return eventGroup->size();
261 }
262
263 int InstrumentScriptVMFunction_by_marks::Result::evalIntElement(uint i) {
264 return (*eventGroup)[i];
265 }
266
267 VMFnResult* InstrumentScriptVMFunction_by_marks::errorResult() {
268 m_result.eventGroup = NULL;
269 m_result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
270 return &m_result;
271 }
272
273 VMFnResult* InstrumentScriptVMFunction_by_marks::successResult(EventGroup* eventGroup) {
274 m_result.eventGroup = eventGroup;
275 m_result.flags = STMT_SUCCESS;
276 return &m_result;
277 }
278
279 VMFnResult* InstrumentScriptVMFunction_by_marks::exec(VMFnArgs* args) {
280 int groupID = args->arg(0)->asInt()->evalInt();
281
282 if (groupID < 0 || groupID >= INSTR_SCRIPT_EVENT_GROUPS) {
283 errMsg("by_marks(): argument is an invalid group id");
284 return errorResult();
285 }
286
287 AbstractEngineChannel* pEngineChannel =
288 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
289
290 return successResult( &pEngineChannel->pScript->eventGroups[groupID] );
291 }
292
293 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC