385 |
if (!pNote) return successResult(); |
if (!pNote) return successResult(); |
386 |
|
|
387 |
// if change_vol() was called immediately after note was triggered |
// if change_vol() was called immediately after note was triggered |
388 |
// then immediately apply the volume to note object |
// then immediately apply the volume to note object, but only if |
389 |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
// change_vol_time() has not been called before |
390 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime && |
391 |
|
pNote->Override.VolumeTime <= DEFAULT_NOTE_VOLUME_TIME_S) |
392 |
|
{ |
393 |
if (relative) |
if (relative) |
394 |
pNote->Override.Volume *= fVolumeLin; |
pNote->Override.Volume *= fVolumeLin; |
395 |
else |
else |
415 |
if (!pNote) continue; |
if (!pNote) continue; |
416 |
|
|
417 |
// if change_vol() was called immediately after note was triggered |
// if change_vol() was called immediately after note was triggered |
418 |
// then immediately apply the volume to Note object |
// then immediately apply the volume to Note object, but only if |
419 |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
// change_vol_time() has not been called before |
420 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime && |
421 |
|
pNote->Override.VolumeTime <= DEFAULT_NOTE_VOLUME_TIME_S) |
422 |
|
{ |
423 |
if (relative) |
if (relative) |
424 |
pNote->Override.Volume *= fVolumeLin; |
pNote->Override.Volume *= fVolumeLin; |
425 |
else |
else |
478 |
if (!pNote) return successResult(); |
if (!pNote) return successResult(); |
479 |
|
|
480 |
// if change_tune() was called immediately after note was triggered |
// if change_tune() was called immediately after note was triggered |
481 |
// then immediately apply the tuning to Note object |
// then immediately apply the tuning to Note object, but only if |
482 |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
// change_tune_time() has not been called before |
483 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime && |
484 |
|
pNote->Override.PitchTime <= DEFAULT_NOTE_PITCH_TIME_S) |
485 |
|
{ |
486 |
if (relative) |
if (relative) |
487 |
pNote->Override.Pitch *= fFreqRatio; |
pNote->Override.Pitch *= fFreqRatio; |
488 |
else |
else |
508 |
if (!pNote) continue; |
if (!pNote) continue; |
509 |
|
|
510 |
// if change_tune() was called immediately after note was triggered |
// if change_tune() was called immediately after note was triggered |
511 |
// then immediately apply the tuning to Note object |
// then immediately apply the tuning to Note object, but only if |
512 |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
// change_tune_time() has not been called before |
513 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime && |
514 |
|
pNote->Override.PitchTime <= DEFAULT_NOTE_PITCH_TIME_S) |
515 |
|
{ |
516 |
if (relative) |
if (relative) |
517 |
pNote->Override.Pitch *= fFreqRatio; |
pNote->Override.Pitch *= fFreqRatio; |
518 |
else |
else |
1071 |
return successResult(); |
return successResult(); |
1072 |
} |
} |
1073 |
|
|
1074 |
|
// template for change_*() functions |
1075 |
|
|
1076 |
bool VMChangeSynthParamFunction::acceptsArgType(int iArg, ExprType_t type) const { |
bool VMChangeSynthParamFunction::acceptsArgType(int iArg, ExprType_t type) const { |
1077 |
if (iArg == 0) |
if (iArg == 0) |
1078 |
return type == INT_EXPR || type == INT_ARR_EXPR; |
return type == INT_EXPR || type == INT_ARR_EXPR; |
1219 |
false, NO_LIMIT, 0>( args, "change_tune_time" ); |
false, NO_LIMIT, 0>( args, "change_tune_time" ); |
1220 |
} |
} |
1221 |
|
|
1222 |
|
// template for change_*_curve() functions |
1223 |
|
|
1224 |
|
bool VMChangeFadeCurveFunction::acceptsArgType(int iArg, ExprType_t type) const { |
1225 |
|
if (iArg == 0) |
1226 |
|
return type == INT_EXPR || type == INT_ARR_EXPR; |
1227 |
|
else |
1228 |
|
return type == INT_EXPR; |
1229 |
|
} |
1230 |
|
|
1231 |
|
template<fade_curve_t NoteBase::_Override::*T_noteParam, int T_synthParam> |
1232 |
|
VMFnResult* VMChangeFadeCurveFunction::execTemplate(VMFnArgs* args, const char* functionName) { |
1233 |
|
int value = args->arg(1)->asInt()->evalInt(); |
1234 |
|
switch (value) { |
1235 |
|
case FADE_CURVE_LINEAR: |
1236 |
|
case FADE_CURVE_EASE_IN_EASE_OUT: |
1237 |
|
break; |
1238 |
|
default: |
1239 |
|
wrnMsg(String(functionName) + "(): invalid curve type passed as argument 2"); |
1240 |
|
return successResult(); |
1241 |
|
} |
1242 |
|
|
1243 |
|
AbstractEngineChannel* pEngineChannel = |
1244 |
|
static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel); |
1245 |
|
|
1246 |
|
if (args->arg(0)->exprType() == INT_EXPR) { |
1247 |
|
const ScriptID id = args->arg(0)->asInt()->evalInt(); |
1248 |
|
if (!id) { |
1249 |
|
wrnMsg(String(functionName) + "(): note ID for argument 1 may not be zero"); |
1250 |
|
return successResult(); |
1251 |
|
} |
1252 |
|
if (!id.isNoteID()) { |
1253 |
|
wrnMsg(String(functionName) + "(): argument 1 is not a note ID"); |
1254 |
|
return successResult(); |
1255 |
|
} |
1256 |
|
|
1257 |
|
NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() ); |
1258 |
|
if (!pNote) return successResult(); |
1259 |
|
|
1260 |
|
// if this change_*_curve() script function was called immediately after |
1261 |
|
// note was triggered then immediately apply the synth parameter |
1262 |
|
// change to Note object |
1263 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
1264 |
|
pNote->Override.*T_noteParam = (fade_curve_t) value; |
1265 |
|
} else { // otherwise schedule this synth parameter change ... |
1266 |
|
Event e = m_vm->m_event->cause; // copy to get fragment time for "now" |
1267 |
|
e.Init(); // clear IDs |
1268 |
|
e.Type = Event::type_note_synth_param; |
1269 |
|
e.Param.NoteSynthParam.NoteID = id.noteID(); |
1270 |
|
e.Param.NoteSynthParam.Type = (Event::synth_param_t) T_synthParam; |
1271 |
|
e.Param.NoteSynthParam.Delta = value; |
1272 |
|
e.Param.NoteSynthParam.Relative = false; |
1273 |
|
|
1274 |
|
pEngineChannel->ScheduleEventMicroSec(&e, 0); |
1275 |
|
} |
1276 |
|
} else if (args->arg(0)->exprType() == INT_ARR_EXPR) { |
1277 |
|
VMIntArrayExpr* ids = args->arg(0)->asIntArray(); |
1278 |
|
for (int i = 0; i < ids->arraySize(); ++i) { |
1279 |
|
const ScriptID id = ids->evalIntElement(i); |
1280 |
|
if (!id || !id.isNoteID()) continue; |
1281 |
|
|
1282 |
|
NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() ); |
1283 |
|
if (!pNote) continue; |
1284 |
|
|
1285 |
|
// if this change_*_curve() script function was called immediately after |
1286 |
|
// note was triggered then immediately apply the synth parameter |
1287 |
|
// change to Note object |
1288 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
1289 |
|
pNote->Override.*T_noteParam = (fade_curve_t) value; |
1290 |
|
} else { // otherwise schedule this synth parameter change ... |
1291 |
|
Event e = m_vm->m_event->cause; // copy to get fragment time for "now" |
1292 |
|
e.Init(); // clear IDs |
1293 |
|
e.Type = Event::type_note_synth_param; |
1294 |
|
e.Param.NoteSynthParam.NoteID = id.noteID(); |
1295 |
|
e.Param.NoteSynthParam.Type = (Event::synth_param_t) T_synthParam; |
1296 |
|
e.Param.NoteSynthParam.Delta = value; |
1297 |
|
e.Param.NoteSynthParam.Relative = false; |
1298 |
|
|
1299 |
|
pEngineChannel->ScheduleEventMicroSec(&e, 0); |
1300 |
|
} |
1301 |
|
} |
1302 |
|
} |
1303 |
|
|
1304 |
|
return successResult(); |
1305 |
|
} |
1306 |
|
|
1307 |
|
// change_vol_curve() function |
1308 |
|
|
1309 |
|
VMFnResult* InstrumentScriptVMFunction_change_vol_curve::exec(VMFnArgs* args) { |
1310 |
|
return VMChangeFadeCurveFunction::execTemplate< |
1311 |
|
&NoteBase::_Override::VolumeCurve, |
1312 |
|
Event::synth_param_volume_curve>( args, "change_vol_curve" ); |
1313 |
|
} |
1314 |
|
|
1315 |
|
// change_tune_curve() function |
1316 |
|
|
1317 |
|
VMFnResult* InstrumentScriptVMFunction_change_tune_curve::exec(VMFnArgs* args) { |
1318 |
|
return VMChangeFadeCurveFunction::execTemplate< |
1319 |
|
&NoteBase::_Override::PitchCurve, |
1320 |
|
Event::synth_param_pitch_curve>( args, "change_tune_curve" ); |
1321 |
|
} |
1322 |
|
|
1323 |
// fade_in() function |
// fade_in() function |
1324 |
|
|
1325 |
InstrumentScriptVMFunction_fade_in::InstrumentScriptVMFunction_fade_in(InstrumentScriptVM* parent) |
InstrumentScriptVMFunction_fade_in::InstrumentScriptVMFunction_fade_in(InstrumentScriptVM* parent) |
1670 |
wrnMsg("set_event_par(): note number of argument 3 is out of range"); |
wrnMsg("set_event_par(): note number of argument 3 is out of range"); |
1671 |
return successResult(); |
return successResult(); |
1672 |
} |
} |
1673 |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
1674 |
pNote->cause.Param.Note.Key = value; |
pNote->cause.Param.Note.Key = value; |
1675 |
else |
m_vm->m_event->cause.Param.Note.Key = value; |
1676 |
|
} else { |
1677 |
wrnMsg("set_event_par(): note number can only be changed when note is new"); |
wrnMsg("set_event_par(): note number can only be changed when note is new"); |
1678 |
|
} |
1679 |
return successResult(); |
return successResult(); |
1680 |
case EVENT_PAR_VELOCITY: |
case EVENT_PAR_VELOCITY: |
1681 |
if (value < 0 || value > 127) { |
if (value < 0 || value > 127) { |
1682 |
wrnMsg("set_event_par(): velocity of argument 3 is out of range"); |
wrnMsg("set_event_par(): velocity of argument 3 is out of range"); |
1683 |
return successResult(); |
return successResult(); |
1684 |
} |
} |
1685 |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) |
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
1686 |
pNote->cause.Param.Note.Velocity = value; |
pNote->cause.Param.Note.Velocity = value; |
1687 |
else |
m_vm->m_event->cause.Param.Note.Velocity = value; |
1688 |
|
} else { |
1689 |
wrnMsg("set_event_par(): velocity can only be changed when note is new"); |
wrnMsg("set_event_par(): velocity can only be changed when note is new"); |
1690 |
|
} |
1691 |
return successResult(); |
return successResult(); |
1692 |
case EVENT_PAR_VOLUME: |
case EVENT_PAR_VOLUME: |
1693 |
wrnMsg("set_event_par(): changing volume by this function is currently not supported, use change_vol() instead"); |
wrnMsg("set_event_par(): changing volume by this function is currently not supported, use change_vol() instead"); |
1713 |
return successResult(); |
return successResult(); |
1714 |
} |
} |
1715 |
|
|
1716 |
|
// change_note() function |
1717 |
|
|
1718 |
|
InstrumentScriptVMFunction_change_note::InstrumentScriptVMFunction_change_note(InstrumentScriptVM* parent) |
1719 |
|
: m_vm(parent) |
1720 |
|
{ |
1721 |
|
} |
1722 |
|
|
1723 |
|
VMFnResult* InstrumentScriptVMFunction_change_note::exec(VMFnArgs* args) { |
1724 |
|
AbstractEngineChannel* pEngineChannel = |
1725 |
|
static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel); |
1726 |
|
|
1727 |
|
const ScriptID id = args->arg(0)->asInt()->evalInt(); |
1728 |
|
if (!id) { |
1729 |
|
wrnMsg("change_note(): note ID for argument 1 may not be zero"); |
1730 |
|
return successResult(); |
1731 |
|
} |
1732 |
|
if (!id.isNoteID()) { |
1733 |
|
wrnMsg("change_note(): argument 1 is not a note ID"); |
1734 |
|
return successResult(); |
1735 |
|
} |
1736 |
|
|
1737 |
|
NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() ); |
1738 |
|
if (!pNote) return successResult(); |
1739 |
|
|
1740 |
|
const int value = args->arg(1)->asInt()->evalInt(); |
1741 |
|
if (value < 0 || value > 127) { |
1742 |
|
wrnMsg("change_note(): note number of argument 2 is out of range"); |
1743 |
|
return successResult(); |
1744 |
|
} |
1745 |
|
|
1746 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
1747 |
|
pNote->cause.Param.Note.Key = value; |
1748 |
|
m_vm->m_event->cause.Param.Note.Key = value; |
1749 |
|
} else { |
1750 |
|
wrnMsg("change_note(): note number can only be changed when note is new"); |
1751 |
|
} |
1752 |
|
|
1753 |
|
return successResult(); |
1754 |
|
} |
1755 |
|
|
1756 |
|
// change_velo() function |
1757 |
|
|
1758 |
|
InstrumentScriptVMFunction_change_velo::InstrumentScriptVMFunction_change_velo(InstrumentScriptVM* parent) |
1759 |
|
: m_vm(parent) |
1760 |
|
{ |
1761 |
|
} |
1762 |
|
|
1763 |
|
VMFnResult* InstrumentScriptVMFunction_change_velo::exec(VMFnArgs* args) { |
1764 |
|
AbstractEngineChannel* pEngineChannel = |
1765 |
|
static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel); |
1766 |
|
|
1767 |
|
const ScriptID id = args->arg(0)->asInt()->evalInt(); |
1768 |
|
if (!id) { |
1769 |
|
wrnMsg("change_velo(): note ID for argument 1 may not be zero"); |
1770 |
|
return successResult(); |
1771 |
|
} |
1772 |
|
if (!id.isNoteID()) { |
1773 |
|
wrnMsg("change_velo(): argument 1 is not a note ID"); |
1774 |
|
return successResult(); |
1775 |
|
} |
1776 |
|
|
1777 |
|
NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() ); |
1778 |
|
if (!pNote) return successResult(); |
1779 |
|
|
1780 |
|
const int value = args->arg(1)->asInt()->evalInt(); |
1781 |
|
if (value < 0 || value > 127) { |
1782 |
|
wrnMsg("change_velo(): velocity of argument 2 is out of range"); |
1783 |
|
return successResult(); |
1784 |
|
} |
1785 |
|
|
1786 |
|
if (m_vm->m_event->scheduleTime == pNote->triggerSchedTime) { |
1787 |
|
pNote->cause.Param.Note.Velocity = value; |
1788 |
|
m_vm->m_event->cause.Param.Note.Velocity = value; |
1789 |
|
} else { |
1790 |
|
wrnMsg("change_velo(): velocity can only be changed when note is new"); |
1791 |
|
} |
1792 |
|
|
1793 |
|
return successResult(); |
1794 |
|
} |
1795 |
|
|
1796 |
// event_status() function |
// event_status() function |
1797 |
|
|
1798 |
InstrumentScriptVMFunction_event_status::InstrumentScriptVMFunction_event_status(InstrumentScriptVM* parent) |
InstrumentScriptVMFunction_event_status::InstrumentScriptVMFunction_event_status(InstrumentScriptVM* parent) |