/[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 2948 by schoenebeck, Fri Jul 15 15:29:04 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 51  namespace LinuxSampler { Line 53  namespace LinuxSampler {
53    
54          Event e = m_vm->m_event->cause; // copy to get fragment time for "now"          Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
55          e.Init(); // clear IDs          e.Init(); // clear IDs
56          e.Type = Event::type_note_on;          e.Type = Event::type_play_note;
57          e.Param.Note.Key = note;          e.Param.Note.Key = note;
58          e.Param.Note.Velocity = velocity;          e.Param.Note.Velocity = velocity;
59          // make this new note dependent to the life time of the original note          // make this new note dependent to the life time of the original note
# Line 65  namespace LinuxSampler { Line 67  namespace LinuxSampler {
67    
68          const note_id_t id = pEngineChannel->ScheduleNoteMicroSec(&e, 0);          const note_id_t id = pEngineChannel->ScheduleNoteMicroSec(&e, 0);
69    
70          // if a duration is supplied (and note-on event was scheduled          // if a duration is supplied (and play-note event was scheduled
71          // successfully above), then schedule a subsequent note-off event          // successfully above), then schedule a subsequent stop-note event
72          if (id && duration > 0) {          if (id && duration > 0) {
73              e.Type = Event::type_note_off;              e.Type = Event::type_stop_note;
74                e.Param.Note.ID = id;
75              e.Param.Note.Velocity = 127;              e.Param.Note.Velocity = 127;
76              pEngineChannel->ScheduleEventMicroSec(&e, duration);              pEngineChannel->ScheduleEventMicroSec(&e, duration);
77          }          }
# Line 79  namespace LinuxSampler { Line 82  namespace LinuxSampler {
82          return successResult( ScriptID::fromNoteID(id) );          return successResult( ScriptID::fromNoteID(id) );
83      }      }
84    
85        // set_controller() function
86    
87      InstrumentScriptVMFunction_set_controller::InstrumentScriptVMFunction_set_controller(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_set_controller::InstrumentScriptVMFunction_set_controller(InstrumentScriptVM* parent)
88          : m_vm(parent)          : m_vm(parent)
89      {      {
# Line 114  namespace LinuxSampler { Line 119  namespace LinuxSampler {
119          // would abort the script, and under heavy load it may be considerable          // would abort the script, and under heavy load it may be considerable
120          // that ScheduleEventMicroSec() fails above, so simply ignore that          // that ScheduleEventMicroSec() fails above, so simply ignore that
121          return successResult( ScriptID::fromEventID(id) );          return successResult( ScriptID::fromEventID(id) );
122      }          }
123    
124        // ignore_event() function
125    
126      InstrumentScriptVMFunction_ignore_event::InstrumentScriptVMFunction_ignore_event(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_ignore_event::InstrumentScriptVMFunction_ignore_event(InstrumentScriptVM* parent)
127          : m_vm(parent)          : m_vm(parent)
# Line 148  namespace LinuxSampler { Line 155  namespace LinuxSampler {
155          return successResult();          return successResult();
156      }      }
157    
158        // ignore_controller() function
159    
160      InstrumentScriptVMFunction_ignore_controller::InstrumentScriptVMFunction_ignore_controller(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_ignore_controller::InstrumentScriptVMFunction_ignore_controller(InstrumentScriptVM* parent)
161          : m_vm(parent)          : m_vm(parent)
162      {      {
# Line 168  namespace LinuxSampler { Line 177  namespace LinuxSampler {
177          return successResult();          return successResult();
178      }      }
179    
180        // note_off() function
181    
182      InstrumentScriptVMFunction_note_off::InstrumentScriptVMFunction_note_off(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_note_off::InstrumentScriptVMFunction_note_off(InstrumentScriptVM* parent)
183          : m_vm(parent)          : m_vm(parent)
184      {      {
# Line 204  namespace LinuxSampler { Line 215  namespace LinuxSampler {
215              Event e = pNote->cause;              Event e = pNote->cause;
216              e.Init(); // clear IDs              e.Init(); // clear IDs
217              e.CopyTimeFrom(m_vm->m_event->cause); // set fragment time for "now"              e.CopyTimeFrom(m_vm->m_event->cause); // set fragment time for "now"
218              e.Type = Event::type_note_off;              e.Type = Event::type_stop_note;
219                e.Param.Note.ID = id.noteID();
220                e.Param.Note.Key = pNote->hostKey;
221              e.Param.Note.Velocity = velocity;              e.Param.Note.Velocity = velocity;
222    
223              pEngineChannel->ScheduleEventMicroSec(&e, 0);              pEngineChannel->ScheduleEventMicroSec(&e, 0);
# Line 220  namespace LinuxSampler { Line 233  namespace LinuxSampler {
233                  Event e = pNote->cause;                  Event e = pNote->cause;
234                  e.Init(); // clear IDs                  e.Init(); // clear IDs
235                  e.CopyTimeFrom(m_vm->m_event->cause); // set fragment time for "now"                  e.CopyTimeFrom(m_vm->m_event->cause); // set fragment time for "now"
236                  e.Type = Event::type_note_off;                  e.Type = Event::type_stop_note;
237                    e.Param.Note.ID = id.noteID();
238                    e.Param.Note.Key = pNote->hostKey;
239                  e.Param.Note.Velocity = velocity;                  e.Param.Note.Velocity = velocity;
240    
241                  pEngineChannel->ScheduleEventMicroSec(&e, 0);                  pEngineChannel->ScheduleEventMicroSec(&e, 0);
# Line 230  namespace LinuxSampler { Line 245  namespace LinuxSampler {
245          return successResult();          return successResult();
246      }      }
247    
248        // set_event_mark() function
249    
250      InstrumentScriptVMFunction_set_event_mark::InstrumentScriptVMFunction_set_event_mark(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_set_event_mark::InstrumentScriptVMFunction_set_event_mark(InstrumentScriptVM* parent)
251          : m_vm(parent)          : m_vm(parent)
252      {      {
# Line 266  namespace LinuxSampler { Line 283  namespace LinuxSampler {
283          return successResult();          return successResult();
284      }      }
285    
286        // delete_event_mark() function
287    
288      InstrumentScriptVMFunction_delete_event_mark::InstrumentScriptVMFunction_delete_event_mark(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_delete_event_mark::InstrumentScriptVMFunction_delete_event_mark(InstrumentScriptVM* parent)
289          : m_vm(parent)          : m_vm(parent)
290      {      {
# Line 288  namespace LinuxSampler { Line 307  namespace LinuxSampler {
307          return successResult();          return successResult();
308      }      }
309    
310        // by_marks() function
311    
312      InstrumentScriptVMFunction_by_marks::InstrumentScriptVMFunction_by_marks(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_by_marks::InstrumentScriptVMFunction_by_marks(InstrumentScriptVM* parent)
313          : m_vm(parent)          : m_vm(parent)
314      {      {
# Line 327  namespace LinuxSampler { Line 348  namespace LinuxSampler {
348          return successResult( &pEngineChannel->pScript->eventGroups[groupID] );          return successResult( &pEngineChannel->pScript->eventGroups[groupID] );
349      }      }
350    
351        // change_vol() function
352    
353        InstrumentScriptVMFunction_change_vol::InstrumentScriptVMFunction_change_vol(InstrumentScriptVM* parent)
354            : m_vm(parent)
355        {
356        }
357    
358        bool InstrumentScriptVMFunction_change_vol::acceptsArgType(int iArg, ExprType_t type) const {
359            if (iArg == 0)
360                return type == INT_EXPR || type == INT_ARR_EXPR;
361            else
362                return INT_EXPR;
363        }
364    
365        VMFnResult* InstrumentScriptVMFunction_change_vol::exec(VMFnArgs* args) {
366            int volume = args->arg(1)->asInt()->evalInt(); // volume change in milli dB
367            bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
368    
369            AbstractEngineChannel* pEngineChannel =
370                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
371    
372            if (args->arg(0)->exprType() == INT_EXPR) {
373                const ScriptID id = args->arg(0)->asInt()->evalInt();
374                if (!id) {
375                    wrnMsg("change_vol(): note ID for argument 1 may not be zero");
376                    return successResult();
377                }
378                if (!id.isNoteID()) {
379                    wrnMsg("change_vol(): argument 1 is not a note ID");
380                    return successResult();
381                }
382    
383                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
384                if (!pNote) return successResult();
385    
386                const float fVolumeLin = RTMath::DecibelToLinRatio(float(volume) / 1000.f);
387                // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
388                /*if (relative)
389                    pNote->Override.Volume *= fVolumeLin;
390                else
391                    pNote->Override.Volume = fVolumeLin;*/
392    
393                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
394                e.Init(); // clear IDs
395                e.Type = Event::type_note_synth_param;
396                e.Param.NoteSynthParam.NoteID   = id.noteID();
397                e.Param.NoteSynthParam.Type     = Event::synth_param_volume;
398                e.Param.NoteSynthParam.Delta    = fVolumeLin;
399                e.Param.NoteSynthParam.Relative = relative;
400    
401                pEngineChannel->ScheduleEventMicroSec(&e, 0);
402            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
403                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
404                for (int i = 0; i < ids->arraySize(); ++i) {
405                    const ScriptID id = ids->evalIntElement(i);
406                    if (!id || !id.isNoteID()) continue;
407    
408                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
409                    if (!pNote) continue;
410    
411                    const float fVolumeLin = RTMath::DecibelToLinRatio(float(volume) / 1000.f);
412                    // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
413                    /*if (relative)
414                        pNote->Override.Volume *= fVolumeLin;
415                    else
416                        pNote->Override.Volume = fVolumeLin;*/
417    
418                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
419                    e.Init(); // clear IDs
420                    e.Type = Event::type_note_synth_param;
421                    e.Param.NoteSynthParam.NoteID   = id.noteID();
422                    e.Param.NoteSynthParam.Type     = Event::synth_param_volume;
423                    e.Param.NoteSynthParam.Delta    = fVolumeLin;
424                    e.Param.NoteSynthParam.Relative = relative;
425    
426                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
427                }
428            }
429    
430            return successResult();
431        }
432    
433        // change_tune() function
434    
435        InstrumentScriptVMFunction_change_tune::InstrumentScriptVMFunction_change_tune(InstrumentScriptVM* parent)
436            : m_vm(parent)
437        {
438        }
439    
440        bool InstrumentScriptVMFunction_change_tune::acceptsArgType(int iArg, ExprType_t type) const {
441            if (iArg == 0)
442                return type == INT_EXPR || type == INT_ARR_EXPR;
443            else
444                return INT_EXPR;
445        }
446    
447        VMFnResult* InstrumentScriptVMFunction_change_tune::exec(VMFnArgs* args) {
448            int tune = args->arg(1)->asInt()->evalInt(); // tuning change in milli cents
449            bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
450    
451            AbstractEngineChannel* pEngineChannel =
452                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
453    
454            if (args->arg(0)->exprType() == INT_EXPR) {
455                const ScriptID id = args->arg(0)->asInt()->evalInt();
456                if (!id) {
457                    wrnMsg("change_tune(): note ID for argument 1 may not be zero");
458                    return successResult();
459                }
460                if (!id.isNoteID()) {
461                    wrnMsg("change_tune(): argument 1 is not a note ID");
462                    return successResult();
463                }
464    
465                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
466                if (!pNote) return successResult();
467    
468                const float fFreqRatio = RTMath::CentsToFreqRatioUnlimited(float(tune) / 1000.f);
469                // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
470                /*if (relative)
471                    pNote->Override.Pitch *= fFreqRatio;
472                else
473                    pNote->Override.Pitch = fFreqRatio;*/
474    
475                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
476                e.Init(); // clear IDs
477                e.Type = Event::type_note_synth_param;
478                e.Param.NoteSynthParam.NoteID   = id.noteID();
479                e.Param.NoteSynthParam.Type     = Event::synth_param_pitch;
480                e.Param.NoteSynthParam.Delta    = fFreqRatio;
481                e.Param.NoteSynthParam.Relative = relative;
482    
483                pEngineChannel->ScheduleEventMicroSec(&e, 0);
484            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
485                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
486                for (int i = 0; i < ids->arraySize(); ++i) {
487                    const ScriptID id = ids->evalIntElement(i);
488                    if (!id || !id.isNoteID()) continue;
489    
490                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
491                    if (!pNote) continue;
492    
493                    const float fFreqRatio = RTMath::CentsToFreqRatioUnlimited(float(tune) / 1000.f);
494                    // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
495                    /*if (relative)
496                        pNote->Override.Pitch *= fFreqRatio;
497                    else
498                        pNote->Override.Pitch = fFreqRatio;*/
499    
500                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
501                    e.Init(); // clear IDs
502                    e.Type = Event::type_note_synth_param;
503                    e.Param.NoteSynthParam.NoteID   = id.noteID();
504                    e.Param.NoteSynthParam.Type     = Event::synth_param_pitch;
505                    e.Param.NoteSynthParam.Delta    = fFreqRatio;
506                    e.Param.NoteSynthParam.Relative = relative;
507    
508                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
509                }
510            }
511    
512            return successResult();
513        }
514    
515        // change_pan() function
516    
517        InstrumentScriptVMFunction_change_pan::InstrumentScriptVMFunction_change_pan(InstrumentScriptVM* parent)
518            : m_vm(parent)
519        {
520        }
521    
522        bool InstrumentScriptVMFunction_change_pan::acceptsArgType(int iArg, ExprType_t type) const {
523            if (iArg == 0)
524                return type == INT_EXPR || type == INT_ARR_EXPR;
525            else
526                return INT_EXPR;
527        }
528    
529        VMFnResult* InstrumentScriptVMFunction_change_pan::exec(VMFnArgs* args) {
530            int pan = args->arg(1)->asInt()->evalInt();
531            bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
532    
533            if (pan > 1000) {
534                wrnMsg("change_pan(): argument 2 may not be larger than 1000");
535                pan = 1000;
536            } else if (pan < -1000) {
537                wrnMsg("change_pan(): argument 2 may not be smaller than -1000");
538                pan = -1000;
539            }
540    
541            AbstractEngineChannel* pEngineChannel =
542                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
543    
544            if (args->arg(0)->exprType() == INT_EXPR) {
545                const ScriptID id = args->arg(0)->asInt()->evalInt();
546                if (!id) {
547                    wrnMsg("change_pan(): note ID for argument 1 may not be zero");
548                    return successResult();
549                }
550                if (!id.isNoteID()) {
551                    wrnMsg("change_pan(): argument 1 is not a note ID");
552                    return successResult();
553                }
554    
555                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
556                if (!pNote) return successResult();
557    
558                const float fPan = float(pan) / 1000.f;
559                // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
560                /*if (relative) {
561                    pNote->Override.Pan = RTMath::RelativeSummedAvg(pNote->Override.Pan, fPan, ++pNote->Override.PanSources);
562                } else {
563                    pNote->Override.Pan = fPan;
564                    pNote->Override.PanSources = 1; // only relevant on subsequent change_pan() calls on same note with 'relative' being set
565                }*/
566    
567                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
568                e.Init(); // clear IDs
569                e.Type = Event::type_note_synth_param;
570                e.Param.NoteSynthParam.NoteID   = id.noteID();
571                e.Param.NoteSynthParam.Type     = Event::synth_param_pan;
572                e.Param.NoteSynthParam.Delta    = fPan;
573                e.Param.NoteSynthParam.Relative = relative;
574    
575                pEngineChannel->ScheduleEventMicroSec(&e, 0);
576            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
577                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
578                for (int i = 0; i < ids->arraySize(); ++i) {
579                    const ScriptID id = ids->evalIntElement(i);
580                    if (!id || !id.isNoteID()) continue;
581    
582                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
583                    if (!pNote) continue;
584    
585                    const float fPan = float(pan) / 1000.f;
586                    // commented out, performed by EngineBase::ProcessNoteSynthParam() for time accuracy behavior
587                    /*if (relative) {
588                        pNote->Override.Pan = RTMath::RelativeSummedAvg(pNote->Override.Pan, fPan, ++pNote->Override.PanSources);
589                    } else {
590                        pNote->Override.Pan = fPan;
591                        pNote->Override.PanSources = 1; // only relevant on subsequent change_pan() calls on same note with 'relative' being set
592                    }*/
593    
594                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
595                    e.Init(); // clear IDs
596                    e.Type = Event::type_note_synth_param;
597                    e.Param.NoteSynthParam.NoteID   = id.noteID();
598                    e.Param.NoteSynthParam.Type     = Event::synth_param_pan;
599                    e.Param.NoteSynthParam.Delta    = fPan;
600                    e.Param.NoteSynthParam.Relative = relative;
601    
602                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
603                }
604            }
605    
606            return successResult();
607        }
608    
609        #define VM_FILTER_PAR_MAX_VALUE 1000000
610    
611        // change_cutoff() function
612    
613        InstrumentScriptVMFunction_change_cutoff::InstrumentScriptVMFunction_change_cutoff(InstrumentScriptVM* parent)
614            : m_vm(parent)
615        {
616        }
617    
618        bool InstrumentScriptVMFunction_change_cutoff::acceptsArgType(int iArg, ExprType_t type) const {
619            if (iArg == 0)
620                return type == INT_EXPR || type == INT_ARR_EXPR;
621            else
622                return INT_EXPR;
623        }
624    
625        VMFnResult* InstrumentScriptVMFunction_change_cutoff::exec(VMFnArgs* args) {
626            int cutoff = args->arg(1)->asInt()->evalInt();
627            if (cutoff > VM_FILTER_PAR_MAX_VALUE) {
628                wrnMsg("change_cutoff(): argument 2 may not be larger than 1000000");
629                cutoff = VM_FILTER_PAR_MAX_VALUE;
630            } else if (cutoff < 0) {
631                wrnMsg("change_cutoff(): argument 2 may not be negative");
632                cutoff = 0;
633            }
634    
635            AbstractEngineChannel* pEngineChannel =
636                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
637    
638            if (args->arg(0)->exprType() == INT_EXPR) {
639                const ScriptID id = args->arg(0)->asInt()->evalInt();
640                if (!id) {
641                    wrnMsg("change_cutoff(): note ID for argument 1 may not be zero");
642                    return successResult();
643                }
644                if (!id.isNoteID()) {
645                    wrnMsg("change_cutoff(): argument 1 is not a note ID");
646                    return successResult();
647                }
648    
649                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
650                if (!pNote) return successResult();
651    
652                const float fCutoff = float(cutoff) / float(VM_FILTER_PAR_MAX_VALUE);
653    
654                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
655                e.Init(); // clear IDs
656                e.Type = Event::type_note_synth_param;
657                e.Param.NoteSynthParam.NoteID   = id.noteID();
658                e.Param.NoteSynthParam.Type     = Event::synth_param_cutoff;
659                e.Param.NoteSynthParam.Delta    = fCutoff;
660                e.Param.NoteSynthParam.Relative = false;
661    
662                pEngineChannel->ScheduleEventMicroSec(&e, 0);
663            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
664                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
665                for (int i = 0; i < ids->arraySize(); ++i) {
666                    const ScriptID id = ids->evalIntElement(i);
667                    if (!id || !id.isNoteID()) continue;
668    
669                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
670                    if (!pNote) continue;
671    
672                    const float fCutoff = float(cutoff) / float(VM_FILTER_PAR_MAX_VALUE);
673    
674                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
675                    e.Init(); // clear IDs
676                    e.Type = Event::type_note_synth_param;
677                    e.Param.NoteSynthParam.NoteID   = id.noteID();
678                    e.Param.NoteSynthParam.Type     = Event::synth_param_cutoff;
679                    e.Param.NoteSynthParam.Delta    = fCutoff;
680                    e.Param.NoteSynthParam.Relative = false;
681    
682                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
683                }
684            }
685    
686            return successResult();
687        }
688    
689        // change_reso() function
690        
691        InstrumentScriptVMFunction_change_reso::InstrumentScriptVMFunction_change_reso(InstrumentScriptVM* parent)
692            : m_vm(parent)
693        {
694        }
695    
696        bool InstrumentScriptVMFunction_change_reso::acceptsArgType(int iArg, ExprType_t type) const {
697            if (iArg == 0)
698                return type == INT_EXPR || type == INT_ARR_EXPR;
699            else
700                return INT_EXPR;
701        }
702    
703        VMFnResult* InstrumentScriptVMFunction_change_reso::exec(VMFnArgs* args) {
704            int resonance = args->arg(1)->asInt()->evalInt();
705            if (resonance > VM_FILTER_PAR_MAX_VALUE) {
706                wrnMsg("change_reso(): argument 2 may not be larger than 1000000");
707                resonance = VM_FILTER_PAR_MAX_VALUE;
708            } else if (resonance < 0) {
709                wrnMsg("change_reso(): argument 2 may not be negative");
710                resonance = 0;
711            }
712    
713            AbstractEngineChannel* pEngineChannel =
714                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
715    
716            if (args->arg(0)->exprType() == INT_EXPR) {
717                const ScriptID id = args->arg(0)->asInt()->evalInt();
718                if (!id) {
719                    wrnMsg("change_reso(): note ID for argument 1 may not be zero");
720                    return successResult();
721                }
722                if (!id.isNoteID()) {
723                    wrnMsg("change_reso(): argument 1 is not a note ID");
724                    return successResult();
725                }
726    
727                NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
728                if (!pNote) return successResult();
729    
730                const float fResonance = float(resonance) / float(VM_FILTER_PAR_MAX_VALUE);
731    
732                Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
733                e.Init(); // clear IDs
734                e.Type = Event::type_note_synth_param;
735                e.Param.NoteSynthParam.NoteID   = id.noteID();
736                e.Param.NoteSynthParam.Type     = Event::synth_param_resonance;
737                e.Param.NoteSynthParam.Delta    = fResonance;
738                e.Param.NoteSynthParam.Relative = false;
739    
740                pEngineChannel->ScheduleEventMicroSec(&e, 0);
741            } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
742                VMIntArrayExpr* ids = args->arg(0)->asIntArray();
743                for (int i = 0; i < ids->arraySize(); ++i) {
744                    const ScriptID id = ids->evalIntElement(i);
745                    if (!id || !id.isNoteID()) continue;
746    
747                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
748                    if (!pNote) continue;
749    
750                    const float fResonance = float(resonance) / float(VM_FILTER_PAR_MAX_VALUE);
751    
752                    Event e = m_vm->m_event->cause; // copy to get fragment time for "now"
753                    e.Init(); // clear IDs
754                    e.Type = Event::type_note_synth_param;
755                    e.Param.NoteSynthParam.NoteID   = id.noteID();
756                    e.Param.NoteSynthParam.Type     = Event::synth_param_resonance;
757                    e.Param.NoteSynthParam.Delta    = fResonance;
758                    e.Param.NoteSynthParam.Relative = false;
759    
760                    pEngineChannel->ScheduleEventMicroSec(&e, 0);
761                }
762            }
763    
764            return successResult();
765        }
766    
767        // event_status() function
768    
769        InstrumentScriptVMFunction_event_status::InstrumentScriptVMFunction_event_status(InstrumentScriptVM* parent)
770            : m_vm(parent)
771        {
772        }
773    
774        VMFnResult* InstrumentScriptVMFunction_event_status::exec(VMFnArgs* args) {
775            AbstractEngineChannel* pEngineChannel =
776                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
777    
778            const ScriptID id = args->arg(0)->asInt()->evalInt();
779            if (!id) {
780                wrnMsg("event_status(): note ID for argument 1 may not be zero");
781                return successResult(EVENT_STATUS_INACTIVE);
782            }
783            if (!id.isNoteID()) {
784                wrnMsg("event_status(): argument 1 is not a note ID");
785                return successResult(EVENT_STATUS_INACTIVE);
786            }
787    
788            NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
789            return successResult(pNote ? EVENT_STATUS_NOTE_QUEUE : EVENT_STATUS_INACTIVE);
790        }
791    
792        // wait() function (overrides core wait() implementation)
793    
794        InstrumentScriptVMFunction_wait::InstrumentScriptVMFunction_wait(InstrumentScriptVM* parent)
795            : CoreVMFunction_wait(parent)
796        {    
797        }
798    
799        VMFnResult* InstrumentScriptVMFunction_wait::exec(VMFnArgs* args) {
800            InstrumentScriptVM* m_vm = (InstrumentScriptVM*) vm;
801    
802            // this might be set by passing 1 with the 2nd argument of built-in stop_wait() function
803            if (m_vm->m_event->ignoreAllWaitCalls) return successResult();
804    
805            return CoreVMFunction_wait::exec(args);
806        }
807    
808        // stop_wait() function
809    
810        InstrumentScriptVMFunction_stop_wait::InstrumentScriptVMFunction_stop_wait(InstrumentScriptVM* parent)
811            : m_vm(parent)
812        {    
813        }
814    
815        VMFnResult* InstrumentScriptVMFunction_stop_wait::exec(VMFnArgs* args) {
816            AbstractEngineChannel* pEngineChannel =
817                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
818    
819            const script_callback_id_t id = args->arg(0)->asInt()->evalInt();
820            if (!id) {
821                wrnMsg("stop_wait(): callback ID for argument 1 may not be zero");
822                return successResult();
823            }
824    
825            RTList<ScriptEvent>::Iterator itCallback = pEngineChannel->ScriptCallbackByID(id);
826            if (!itCallback) return successResult(); // ignore if callback is i.e. not alive anymore
827    
828            const bool disableWaitForever =
829                (args->argsCount() >= 2) ? (args->arg(1)->asInt()->evalInt() == 1) : false;
830    
831            pEngineChannel->ScheduleResumeOfScriptCallback(
832                itCallback, m_vm->m_event->cause.SchedTime(), disableWaitForever
833            );
834    
835            return successResult();
836        }
837    
838  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC