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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2630 - (hide 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 schoenebeck 2596 /*
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 schoenebeck 2598 return errorResult(-1);
30 schoenebeck 2596 }
31    
32     if (velocity < 0 || velocity > 127) {
33     errMsg("play_note(): argument 2 is an invalid velocity value");
34 schoenebeck 2598 return errorResult(-1);
35 schoenebeck 2596 }
36    
37     if (sampleoffset < 0) {
38     errMsg("play_note(): argument 3 may not be a negative sample offset");
39 schoenebeck 2598 return errorResult(-1);
40 schoenebeck 2596 } 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 schoenebeck 2598 return errorResult(-1);
47 schoenebeck 2596 } 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 persson 2606 memset(&e.Format, 0, sizeof(e.Format)); // init format speific stuff with zero
61 schoenebeck 2596
62 schoenebeck 2598 int id = pEngineChannel->ScheduleEvent(&e, duration);
63 schoenebeck 2596
64 schoenebeck 2598 return successResult(id);
65     }
66    
67 schoenebeck 2600 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 persson 2606 memset(&e.Format, 0, sizeof(e.Format)); // init format speific stuff with zero
81 schoenebeck 2600 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 schoenebeck 2598 InstrumentScriptVMFunction_ignore_event::InstrumentScriptVMFunction_ignore_event(InstrumentScriptVM* parent)
102     : m_vm(parent)
103     {
104     }
105    
106 schoenebeck 2630 bool InstrumentScriptVMFunction_ignore_event::acceptsArgType(int iArg, ExprType_t type) const {
107     return type == INT_EXPR || type == INT_ARR_EXPR;
108     }
109    
110 schoenebeck 2598 VMFnResult* InstrumentScriptVMFunction_ignore_event::exec(VMFnArgs* args) {
111     AbstractEngineChannel* pEngineChannel =
112 schoenebeck 2630 static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
113 schoenebeck 2598
114 schoenebeck 2630 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 schoenebeck 2598
129 schoenebeck 2596 return successResult();
130     }
131    
132 schoenebeck 2598 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 schoenebeck 2629 InstrumentScriptVMFunction_note_off::InstrumentScriptVMFunction_note_off(InstrumentScriptVM* parent)
153     : m_vm(parent)
154     {
155     }
156    
157 schoenebeck 2630 bool InstrumentScriptVMFunction_note_off::acceptsArgType(int iArg, ExprType_t type) const {
158     return type == INT_EXPR || type == INT_ARR_EXPR;
159     }
160    
161 schoenebeck 2629 VMFnResult* InstrumentScriptVMFunction_note_off::exec(VMFnArgs* args) {
162 schoenebeck 2630 AbstractEngineChannel* pEngineChannel =
163     static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
164    
165 schoenebeck 2629 int velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;
166 schoenebeck 2630 if (velocity < 0 || velocity > 127) {
167     errMsg("note_off(): argument 2 is an invalid velocity value");
168     return errorResult();
169     }
170 schoenebeck 2629
171 schoenebeck 2630 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 schoenebeck 2629 }
203    
204 schoenebeck 2630 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 schoenebeck 2629 return errorResult();
219     }
220    
221     AbstractEngineChannel* pEngineChannel =
222     static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
223    
224 schoenebeck 2630 RTList<Event>::Iterator itEvent = pEngineChannel->pEngine->EventByID(eventID);
225 schoenebeck 2629 if (!itEvent) return successResult();
226    
227 schoenebeck 2630 pEngineChannel->pScript->eventGroups[groupID].insert(eventID);
228 schoenebeck 2629
229 schoenebeck 2630 return successResult();
230     }
231 schoenebeck 2629
232 schoenebeck 2630 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 schoenebeck 2629 return successResult();
252     }
253    
254 schoenebeck 2630 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 schoenebeck 2596 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC