/[svn]/linuxsampler/trunk/src/engines/EngineBase.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/EngineBase.h

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

revision 2593 by schoenebeck, Sun May 18 17:38:25 2014 UTC revision 2594 by schoenebeck, Thu Jun 5 00:16:25 2014 UTC
# Line 631  namespace LinuxSampler { Line 631  namespace LinuxSampler {
631                  AbstractEngineChannel* pChannel = static_cast<AbstractEngineChannel*>(pEngineChannel);                  AbstractEngineChannel* pChannel = static_cast<AbstractEngineChannel*>(pEngineChannel);
632                  pChannel->ImportEvents(Samples);                  pChannel->ImportEvents(Samples);
633    
634                  // process events                  // if a valid real-time instrument script is loaded, pre-process
635                    // the event list by running the script now, since the script
636                    // might filter events or add new ones for this cycle
637                    if (pChannel->script.bHasValidScript) {
638                        // resume any suspended script executions still hanging
639                        // around of previous audio fragment cycles
640                        for (RTList<ScriptEvent>::Iterator itEvent = pChannel->pScriptEvents->first(),
641                            end = pChannel->pScriptEvents->end(); itEvent != end; ++itEvent)
642                        {
643                            ResumeScriptEvent(pChannel, itEvent);
644                        }
645    
646                        // spawn new script executions for the new MIDI events of
647                        // this audio fragment cycle
648                        for (RTList<Event>::Iterator itEvent = pChannel->pEvents->first(),
649                            end = pChannel->pEvents->end(); itEvent != end; ++itEvent)
650                        {
651                            switch (itEvent->Type) {
652                                case Event::type_note_on:
653                                    if (pChannel->script.handlerNote)
654                                        ProcessEventByScript(pChannel, itEvent, pChannel->script.handlerNote);
655                                    break;
656                                case Event::type_note_off:
657                                    //TODO: ...
658                                    break;
659                                case Event::type_control_change:
660                                case Event::type_channel_pressure:
661                                case Event::type_pitchbend:
662                                    if (pChannel->script.handlerController)
663                                        ProcessEventByScript(pChannel, itEvent, pChannel->script.handlerController);                            
664                                    break;
665                                case Event::type_note_pressure:
666                                    //TODO: ...
667                                    break;
668                            }
669                        }
670                    }
671    
672                    // now process all events regularly
673                  {                  {
674                      RTList<Event>::Iterator itEvent = pChannel->pEvents->first();                      RTList<Event>::Iterator itEvent = pChannel->pEvents->first();
675                      RTList<Event>::Iterator end     = pChannel->pEvents->end();                      RTList<Event>::Iterator end     = pChannel->pEvents->end();
# Line 673  namespace LinuxSampler { Line 711  namespace LinuxSampler {
711                  pLastStolenChannel        = NULL;                  pLastStolenChannel        = NULL;
712              }              }
713    
714                /** @brief Call instrument script's event handler for this event.
715                 *
716                 * Causes a new execution instance of the currently loaded real-time
717                 * instrument script's event handler (callback) to be spawned for
718                 * the given MIDI event.
719                 *
720                 * @param pChannel - engine channel on which the MIDI event occured
721                 * @param itEvent - MIDI event that causes this new script execution
722                 * @param pEventHandler - script's event handler to be executed
723                 */
724                void ProcessEventByScript(AbstractEngineChannel* pChannel, RTList<Event>::Iterator& itEvent, VMEventHandler* pEventHandler) {
725                    RTList<ScriptEvent>::Iterator itScriptEvent =
726                        pChannel->pScriptEvents->allocAppend();
727    
728                    if (!itScriptEvent) return; // no free script event left for execution
729    
730                    // fill the list of script handlers to be executed by this event
731                    int i = 0;
732                    if (pChannel->script.handlerInit)
733                        itScriptEvent->handlers[i++] = pChannel->script.handlerInit;
734                    itScriptEvent->handlers[i++] = pEventHandler; // actual event handler (i.e. note, controller)
735                    itScriptEvent->handlers[i] = NULL; // NULL termination of list
736    
737                    // initialize/reset other members
738                    itScriptEvent->cause = *itEvent;
739                    itScriptEvent->currentHandler = 0;
740                    itScriptEvent->executionSlices = 0;
741    
742                    // run script handler(s)
743                    VMExecStatus_t res = pScriptVM->exec(
744                        pChannel->script.parserContext, &*itScriptEvent
745                    );
746    
747                    // in case the script was suspended, keep it on the allocated
748                    // ScriptEvent list to be continued on the next audio cycle,
749                    // otherwise if execution has been finished, free it for a new
750                    // future script event to be triggered from start
751                    if (!(res & VM_EXEC_SUSPENDED))
752                        pChannel->pScriptEvents->free(itScriptEvent);
753                }
754    
755                /** @brief Resume execution of instrument script.
756                 *
757                 * Will be called to resume execution of a real-time instrument
758                 * script event which has been suspended in a previous audio
759                 * fragment cycle.
760                 *
761                 * Script execution might be suspended for various reasons. Usually
762                 * a script will be suspended if the script called the built-in
763                 * "wait()" function, but it might also be suspended automatically
764                 * if the script took too much execution time in an audio fragment
765                 * cycle. So in the latter case automatic suspension is performed in
766                 * order to avoid harm for the sampler's overall real-time
767                 * requirements.
768                 *
769                 * @param pChannel - engine channel this script is running for
770                 * @param itScriptEvent - script execution that shall be resumed
771                 */
772                void ResumeScriptEvent(AbstractEngineChannel* pChannel, RTList<ScriptEvent>::Iterator& itScriptEvent) {
773                    // run script
774                    VMExecStatus_t res = pScriptVM->exec(
775                        pChannel->script.parserContext, &*itScriptEvent
776                    );
777                    // in case the script was again suspended, keep it on the allocated
778                    // ScriptEvent list to be continued on the next audio cycle,
779                    // otherwise if execution has been finished, free it for a new
780                    // future script event to be triggered from start
781                    if (!(res & VM_EXEC_SUSPENDED))
782                        pChannel->pScriptEvents->free(itScriptEvent);
783                }
784    
785              /**              /**
786               *  Will be called by LaunchVoice() method in case there are no free               *  Will be called by LaunchVoice() method in case there are no free
787               *  voices left. This method will select and kill one old voice for               *  voices left. This method will select and kill one old voice for

Legend:
Removed from v.2593  
changed lines
  Added in v.2594

  ViewVC Help
Powered by ViewVC