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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2879 by schoenebeck, Tue Apr 19 14:07:53 2016 UTC revision 2931 by schoenebeck, Sat Jul 9 14:38:33 2016 UTC
# Line 12  Line 12 
12  #include "../AbstractEngineChannel.h"  #include "../AbstractEngineChannel.h"
13    
14  namespace LinuxSampler {  namespace LinuxSampler {
15        
16        // play_note() function
17    
18      InstrumentScriptVMFunction_play_note::InstrumentScriptVMFunction_play_note(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_play_note::InstrumentScriptVMFunction_play_note(InstrumentScriptVM* parent)
19          : m_vm(parent)          : m_vm(parent)
# Line 79  namespace LinuxSampler { Line 81  namespace LinuxSampler {
81          return successResult( ScriptID::fromNoteID(id) );          return successResult( ScriptID::fromNoteID(id) );
82      }      }
83    
84        // set_controller() function
85    
86      InstrumentScriptVMFunction_set_controller::InstrumentScriptVMFunction_set_controller(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_set_controller::InstrumentScriptVMFunction_set_controller(InstrumentScriptVM* parent)
87          : m_vm(parent)          : m_vm(parent)
88      {      {
# Line 114  namespace LinuxSampler { Line 118  namespace LinuxSampler {
118          // would abort the script, and under heavy load it may be considerable          // would abort the script, and under heavy load it may be considerable
119          // that ScheduleEventMicroSec() fails above, so simply ignore that          // that ScheduleEventMicroSec() fails above, so simply ignore that
120          return successResult( ScriptID::fromEventID(id) );          return successResult( ScriptID::fromEventID(id) );
121      }          }
122    
123        // ignore_event() function
124    
125      InstrumentScriptVMFunction_ignore_event::InstrumentScriptVMFunction_ignore_event(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_ignore_event::InstrumentScriptVMFunction_ignore_event(InstrumentScriptVM* parent)
126          : m_vm(parent)          : m_vm(parent)
# Line 148  namespace LinuxSampler { Line 154  namespace LinuxSampler {
154          return successResult();          return successResult();
155      }      }
156    
157        // ignore_controller() function
158    
159      InstrumentScriptVMFunction_ignore_controller::InstrumentScriptVMFunction_ignore_controller(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_ignore_controller::InstrumentScriptVMFunction_ignore_controller(InstrumentScriptVM* parent)
160          : m_vm(parent)          : m_vm(parent)
161      {      {
# Line 168  namespace LinuxSampler { Line 176  namespace LinuxSampler {
176          return successResult();          return successResult();
177      }      }
178    
179        // note_off() function
180    
181      InstrumentScriptVMFunction_note_off::InstrumentScriptVMFunction_note_off(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_note_off::InstrumentScriptVMFunction_note_off(InstrumentScriptVM* parent)
182          : m_vm(parent)          : m_vm(parent)
183      {      {
# Line 230  namespace LinuxSampler { Line 240  namespace LinuxSampler {
240          return successResult();          return successResult();
241      }      }
242    
243        // set_event_mark() function
244    
245      InstrumentScriptVMFunction_set_event_mark::InstrumentScriptVMFunction_set_event_mark(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_set_event_mark::InstrumentScriptVMFunction_set_event_mark(InstrumentScriptVM* parent)
246          : m_vm(parent)          : m_vm(parent)
247      {      {
# Line 266  namespace LinuxSampler { Line 278  namespace LinuxSampler {
278          return successResult();          return successResult();
279      }      }
280    
281        // delete_event_mark() function
282    
283      InstrumentScriptVMFunction_delete_event_mark::InstrumentScriptVMFunction_delete_event_mark(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_delete_event_mark::InstrumentScriptVMFunction_delete_event_mark(InstrumentScriptVM* parent)
284          : m_vm(parent)          : m_vm(parent)
285      {      {
# Line 288  namespace LinuxSampler { Line 302  namespace LinuxSampler {
302          return successResult();          return successResult();
303      }      }
304    
305        // by_marks() function
306    
307      InstrumentScriptVMFunction_by_marks::InstrumentScriptVMFunction_by_marks(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_by_marks::InstrumentScriptVMFunction_by_marks(InstrumentScriptVM* parent)
308          : m_vm(parent)          : m_vm(parent)
309      {      {
# Line 327  namespace LinuxSampler { Line 343  namespace LinuxSampler {
343          return successResult( &pEngineChannel->pScript->eventGroups[groupID] );          return successResult( &pEngineChannel->pScript->eventGroups[groupID] );
344      }      }
345    
346        // change_vol() function
347    
348        InstrumentScriptVMFunction_change_vol::InstrumentScriptVMFunction_change_vol(InstrumentScriptVM* parent)
349            : m_vm(parent)
350        {
351        }
352    
353        bool InstrumentScriptVMFunction_change_vol::acceptsArgType(int iArg, ExprType_t type) const {
354            if (iArg == 0)
355                return type == INT_EXPR || type == INT_ARR_EXPR;
356            else
357                return INT_EXPR;
358        }
359    
360        VMFnResult* InstrumentScriptVMFunction_change_vol::exec(VMFnArgs* args) {
361            int volume = args->arg(1)->asInt()->evalInt(); // volume change in milli dB
362            bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
363    
364            AbstractEngineChannel* pEngineChannel =
365                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
366    
367            if (args->arg(0)->exprType() == INT_EXPR) {
368                const ScriptID id = args->arg(0)->asInt()->evalInt();
369                if (!id) {
370                    wrnMsg("change_vol(): note ID for argument 1 may not be zero");
371                    return successResult();
372                }
373                if (!id.isNoteID()) {
374                    wrnMsg("change_vol(): argument 1 is not a note ID");
375                    return successResult();
376                }
377    
378                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
379                if (!pNote) return successResult();
380    
381                const float fVolumeLin = RTMath::DecibelToLinRatio(float(volume) / 1000.f);
382                // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
383                /*if (relative)
384                    pNote->Override.Volume *= fVolumeLin;
385                else
386                    pNote->Override.Volume = fVolumeLin;*/
387    
388                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
389                e.Init(); // clear IDs
390                e.Type = Event::type_note_synth_param;
391                e.Param.NoteSynthParam.NoteID   = id.noteID();
392                e.Param.NoteSynthParam.Type     = Event::synth_param_volume;
393                e.Param.NoteSynthParam.Delta    = fVolumeLin;
394                e.Param.NoteSynthParam.Relative = relative;
395    
396                pEngineChannel->ScheduleEventMicroSec(&e, 0);
397            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
398                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
399                for (int i = 0; i < ids->arraySize(); ++i) {
400                    const ScriptID id = ids->evalIntElement(i);
401                    if (!id || !id.isNoteID()) continue;
402    
403                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
404                    if (!pNote) continue;
405    
406                    const float fVolumeLin = RTMath::DecibelToLinRatio(float(volume) / 1000.f);
407                    // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
408                    /*if (relative)
409                        pNote->Override.Volume *= fVolumeLin;
410                    else
411                        pNote->Override.Volume = fVolumeLin;*/
412    
413                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
414                    e.Init(); // clear IDs
415                    e.Type = Event::type_note_synth_param;
416                    e.Param.NoteSynthParam.NoteID   = id.noteID();
417                    e.Param.NoteSynthParam.Type     = Event::synth_param_volume;
418                    e.Param.NoteSynthParam.Delta    = fVolumeLin;
419                    e.Param.NoteSynthParam.Relative = relative;
420    
421                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
422                }
423            }
424    
425            return successResult();
426        }
427    
428        // change_tune() function
429    
430        InstrumentScriptVMFunction_change_tune::InstrumentScriptVMFunction_change_tune(InstrumentScriptVM* parent)
431            : m_vm(parent)
432        {
433        }
434    
435        bool InstrumentScriptVMFunction_change_tune::acceptsArgType(int iArg, ExprType_t type) const {
436            if (iArg == 0)
437                return type == INT_EXPR || type == INT_ARR_EXPR;
438            else
439                return INT_EXPR;
440        }
441    
442        VMFnResult* InstrumentScriptVMFunction_change_tune::exec(VMFnArgs* args) {
443            int tune = args->arg(1)->asInt()->evalInt(); // tuning change in milli cents
444            bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
445    
446            AbstractEngineChannel* pEngineChannel =
447                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
448    
449            if (args->arg(0)->exprType() == INT_EXPR) {
450                const ScriptID id = args->arg(0)->asInt()->evalInt();
451                if (!id) {
452                    wrnMsg("change_tune(): note ID for argument 1 may not be zero");
453                    return successResult();
454                }
455                if (!id.isNoteID()) {
456                    wrnMsg("change_tune(): argument 1 is not a note ID");
457                    return successResult();
458                }
459    
460                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
461                if (!pNote) return successResult();
462    
463                const float fFreqRatio = RTMath::CentsToFreqRatioUnlimited(float(tune) / 1000.f);
464                // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
465                /*if (relative)
466                    pNote->Override.Pitch *= fFreqRatio;
467                else
468                    pNote->Override.Pitch = fFreqRatio;*/
469    
470                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
471                e.Init(); // clear IDs
472                e.Type = Event::type_note_synth_param;
473                e.Param.NoteSynthParam.NoteID   = id.noteID();
474                e.Param.NoteSynthParam.Type     = Event::synth_param_pitch;
475                e.Param.NoteSynthParam.Delta    = fFreqRatio;
476                e.Param.NoteSynthParam.Relative = relative;
477    
478                pEngineChannel->ScheduleEventMicroSec(&e, 0);
479            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
480                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
481                for (int i = 0; i < ids->arraySize(); ++i) {
482                    const ScriptID id = ids->evalIntElement(i);
483                    if (!id || !id.isNoteID()) continue;
484    
485                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
486                    if (!pNote) continue;
487    
488                    const float fFreqRatio = RTMath::CentsToFreqRatioUnlimited(float(tune) / 1000.f);
489                    // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
490                    /*if (relative)
491                        pNote->Override.Pitch *= fFreqRatio;
492                    else
493                        pNote->Override.Pitch = fFreqRatio;*/
494    
495                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
496                    e.Init(); // clear IDs
497                    e.Type = Event::type_note_synth_param;
498                    e.Param.NoteSynthParam.NoteID   = id.noteID();
499                    e.Param.NoteSynthParam.Type     = Event::synth_param_pitch;
500                    e.Param.NoteSynthParam.Delta    = fFreqRatio;
501                    e.Param.NoteSynthParam.Relative = relative;
502    
503                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
504                }
505            }
506    
507            return successResult();
508        }
509    
510        // change_pan() function
511    
512        InstrumentScriptVMFunction_change_pan::InstrumentScriptVMFunction_change_pan(InstrumentScriptVM* parent)
513            : m_vm(parent)
514        {
515        }
516    
517        bool InstrumentScriptVMFunction_change_pan::acceptsArgType(int iArg, ExprType_t type) const {
518            if (iArg == 0)
519                return type == INT_EXPR || type == INT_ARR_EXPR;
520            else
521                return INT_EXPR;
522        }
523    
524        VMFnResult* InstrumentScriptVMFunction_change_pan::exec(VMFnArgs* args) {
525            int pan = args->arg(1)->asInt()->evalInt();
526            bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
527    
528            if (pan > 1000) {
529                wrnMsg("change_pan(): argument 2 may not be larger than 1000");
530                pan = 1000;
531            } else if (pan < -1000) {
532                wrnMsg("change_pan(): argument 2 may not be smaller than -1000");
533                pan = -1000;
534            }
535    
536            AbstractEngineChannel* pEngineChannel =
537                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
538    
539            if (args->arg(0)->exprType() == INT_EXPR) {
540                const ScriptID id = args->arg(0)->asInt()->evalInt();
541                if (!id) {
542                    wrnMsg("change_pan(): note ID for argument 1 may not be zero");
543                    return successResult();
544                }
545                if (!id.isNoteID()) {
546                    wrnMsg("change_pan(): argument 1 is not a note ID");
547                    return successResult();
548                }
549    
550                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
551                if (!pNote) return successResult();
552    
553                const float fPan = float(pan) / 1000.f;
554                // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
555                /*if (relative) {
556                    pNote->Override.Pan = RTMath::RelativeSummedAvg(pNote->Override.Pan, fPan, ++pNote->Override.PanSources);
557                } else {
558                    pNote->Override.Pan = fPan;
559                    pNote->Override.PanSources = 1; // only relevant on subsequent change_pan() calls on same note with 'relative' being set
560                }*/
561    
562                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
563                e.Init(); // clear IDs
564                e.Type = Event::type_note_synth_param;
565                e.Param.NoteSynthParam.NoteID   = id.noteID();
566                e.Param.NoteSynthParam.Type     = Event::synth_param_pan;
567                e.Param.NoteSynthParam.Delta    = fPan;
568                e.Param.NoteSynthParam.Relative = relative;
569    
570                pEngineChannel->ScheduleEventMicroSec(&e, 0);
571            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
572                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
573                for (int i = 0; i < ids->arraySize(); ++i) {
574                    const ScriptID id = ids->evalIntElement(i);
575                    if (!id || !id.isNoteID()) continue;
576    
577                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
578                    if (!pNote) continue;
579    
580                    const float fPan = float(pan) / 1000.f;
581                    // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
582                    /*if (relative) {
583                        pNote->Override.Pan = RTMath::RelativeSummedAvg(pNote->Override.Pan, fPan, ++pNote->Override.PanSources);
584                    } else {
585                        pNote->Override.Pan = fPan;
586                        pNote->Override.PanSources = 1; // only relevant on subsequent change_pan() calls on same note with 'relative' being set
587                    }*/
588    
589                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
590                    e.Init(); // clear IDs
591                    e.Type = Event::type_note_synth_param;
592                    e.Param.NoteSynthParam.NoteID   = id.noteID();
593                    e.Param.NoteSynthParam.Type     = Event::synth_param_pan;
594                    e.Param.NoteSynthParam.Delta    = fPan;
595                    e.Param.NoteSynthParam.Relative = relative;
596    
597                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
598                }
599            }
600    
601            return successResult();
602        }
603    
604  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2879  
changed lines
  Added in v.2931

  ViewVC Help
Powered by ViewVC