--- linuxsampler/trunk/src/engines/EngineBase.h 2016/12/15 12:47:45 3054 +++ linuxsampler/trunk/src/engines/EngineBase.h 2017/05/24 20:05:38 3205 @@ -5,7 +5,7 @@ * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * * Copyright (C) 2005-2008 Christian Schoenebeck * * Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev * - * Copyright (C) 2012-2016 Christian Schoenebeck and Andreas Persson * + * Copyright (C) 2012-2017 Christian Schoenebeck and Andreas Persson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -605,7 +605,7 @@ // implementation of abstract methods derived from class 'LinuxSampler::NotePool' virtual Pool* GetVoicePool() OVERRIDE { return pVoicePool; } virtual Pool< Note >* GetNotePool() OVERRIDE { return pNotePool; } - virtual Pool* GetNodeIDPool() OVERRIDE { return ¬eIDPool; } + virtual Pool* GetNoteIDPool() OVERRIDE { return ¬eIDPool; } D* GetDiskThread() { return pDiskThread; } @@ -676,7 +676,7 @@ * @param pNoteOnEvent - event which caused this * @returns new note's unique ID (or zero on error) */ - note_id_t LaunchNewNote(LinuxSampler::EngineChannel* pEngineChannel, Event* pNoteOnEvent) OVERRIDE { + note_id_t LaunchNewNote(LinuxSampler::EngineChannel* pEngineChannel, Pool::Iterator& itNoteOnEvent) OVERRIDE { EngineChannelBase* pChannel = static_cast*>(pEngineChannel); Pool< Note >* pNotePool = GetNotePool(); @@ -691,7 +691,7 @@ const note_id_t newNoteID = pNotePool->getID(itNewNote); // remember the engine's time when this note was triggered exactly - itNewNote->triggerSchedTime = pNoteOnEvent->SchedTime(); + itNewNote->triggerSchedTime = itNoteOnEvent->SchedTime(); // usually the new note (and its subsequent voices) will be // allocated on the key provided by the event's note number, @@ -699,11 +699,11 @@ // note, but rather a child note, then this new note will be // allocated on the parent note's key instead in order to // release the child note simultaniously with its parent note - itNewNote->hostKey = pNoteOnEvent->Param.Note.Key; + itNewNote->hostKey = itNoteOnEvent->Param.Note.Key; // in case this new note was requested to be a child note, // then retrieve its parent note and link them with each other - const note_id_t parentNoteID = pNoteOnEvent->Param.Note.ParentNoteID; + const note_id_t parentNoteID = itNoteOnEvent->Param.Note.ParentNoteID; if (parentNoteID) { NoteIterator itParentNote = pNotePool->fromID(parentNoteID); if (itParentNote) { @@ -731,15 +731,18 @@ dmsg(2,("Launched new note on host key %d\n", itNewNote->hostKey)); // copy event which caused this note - itNewNote->cause = *pNoteOnEvent; - itNewNote->eventID = pEventPool->getID(pNoteOnEvent); + itNewNote->cause = *itNoteOnEvent; + itNewNote->eventID = pEventPool->getID(itNoteOnEvent); + if (!itNewNote->eventID) { + dmsg(0,("Engine: No valid event ID resolved for note. This is a bug!!!\n")); + } // move new note to its host key MidiKey* pKey = &pChannel->pMIDIKeyInfo[itNewNote->hostKey]; itNewNote.moveToEndOf(pKey->pActiveNotes); // assign unique note ID of this new note to the original note on event - pNoteOnEvent->Param.Note.ID = newNoteID; + itNoteOnEvent->Param.Note.ID = newNoteID; return newNoteID; // success } @@ -809,6 +812,7 @@ case Event::type_release_note: case Event::type_play_note: case Event::type_stop_note: + case Event::type_kill_note: case Event::type_note_synth_param: break; // noop } @@ -881,6 +885,10 @@ dmsg(5,("Engine: Stop Note received\n")); ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent); break; + case Event::type_kill_note: + dmsg(5,("Engine: Kill Note received\n")); + ProcessKillNote((EngineChannel*)itEvent->pEngineChannel, itEvent); + break; case Event::type_control_change: dmsg(5,("Engine: MIDI CC received\n")); ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent); @@ -1008,6 +1016,7 @@ // initialize/reset other members itScriptEvent->cause = *itEvent; + itScriptEvent->scheduleTime = itEvent->SchedTime(); itScriptEvent->currentHandler = 0; itScriptEvent->executionSlices = 0; itScriptEvent->ignoreAllWaitCalls = false; @@ -1354,7 +1363,7 @@ // usually there should already be a new Note object NoteIterator itNote = GetNotePool()->fromID(itVoiceStealEvent->Param.Note.ID); if (!itNote) { // should not happen, but just to be sure ... - const note_id_t noteID = LaunchNewNote(pEngineChannel, &*itVoiceStealEvent); + const note_id_t noteID = LaunchNewNote(pEngineChannel, itVoiceStealEvent); if (!noteID) { dmsg(1,("Engine: Voice stealing failed; No Note object and Note pool empty!\n")); continue; @@ -1831,7 +1840,7 @@ itPseudoNoteOnEvent->Param.Note.Key = i; itPseudoNoteOnEvent->Param.Note.Velocity = pOtherKey->Velocity; // assign a new note to this note-on event - if (LaunchNewNote(pChannel, &*itPseudoNoteOnEvent)) { + if (LaunchNewNote(pChannel, itPseudoNoteOnEvent)) { // allocate and trigger new voice(s) for the other key TriggerNewVoices(pChannel, itPseudoNoteOnEvent, false); } @@ -1918,7 +1927,7 @@ // spawn release triggered voice(s) if needed if (pKey->ReleaseTrigger && pChannel->pInstrument) { // assign a new note to this release event - if (LaunchNewNote(pChannel, &*itEvent)) { + if (LaunchNewNote(pChannel, itEvent)) { // allocate and trigger new release voice(s) TriggerReleaseVoices(pChannel, itEvent); } @@ -1927,9 +1936,27 @@ } /** + * Called on "kill note" events, which currently only happens on + * built-in real-time instrument script function fade_out(). This + * method only fulfills one task: moving the even to the Note's own + * event list so that its voices can process the kill event sample + * accurately. + */ + void ProcessKillNote(EngineChannel* pEngineChannel, RTList::Iterator& itEvent) { + EngineChannelBase* pChannel = static_cast*>(pEngineChannel); + + NoteBase* pNote = pChannel->pEngine->NoteByID( itEvent->Param.Note.ID ); + if (!pNote || pNote->hostKey < 0 || pNote->hostKey >= 128) return; + + // move note kill event to its MIDI key + MidiKey* pKey = &pChannel->pMIDIKeyInfo[pNote->hostKey]; + itEvent.moveToEndOf(pKey->pEvents); + } + + /** * Called on note synthesis parameter change events. These are * internal events caused by calling built-in real-time instrument - * script functions like change_vol(), change_pitch(), etc. + * script functions like change_vol(), change_tune(), etc. * * This method performs two tasks: * @@ -1960,6 +1987,9 @@ pNote->Override.Volume = itEvent->Param.NoteSynthParam.Delta; itEvent->Param.NoteSynthParam.AbsValue = pNote->Override.Volume; break; + case Event::synth_param_volume_time: + pNote->Override.VolumeTime = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; + break; case Event::synth_param_pitch: if (relative) pNote->Override.Pitch *= itEvent->Param.NoteSynthParam.Delta; @@ -1967,6 +1997,9 @@ pNote->Override.Pitch = itEvent->Param.NoteSynthParam.Delta; itEvent->Param.NoteSynthParam.AbsValue = pNote->Override.Pitch; break; + case Event::synth_param_pitch_time: + pNote->Override.PitchTime = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; + break; case Event::synth_param_pan: if (relative) { pNote->Override.Pan = RTMath::RelativeSummedAvg(pNote->Override.Pan, itEvent->Param.NoteSynthParam.Delta, ++pNote->Override.PanSources); @@ -1991,6 +2024,18 @@ case Event::synth_param_release: pNote->Override.Release = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; break; + case Event::synth_param_amp_lfo_depth: + pNote->Override.AmpLFODepth = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; + break; + case Event::synth_param_amp_lfo_freq: + pNote->Override.AmpLFOFreq = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; + break; + case Event::synth_param_pitch_lfo_depth: + pNote->Override.PitchLFODepth = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; + break; + case Event::synth_param_pitch_lfo_freq: + pNote->Override.PitchLFOFreq = itEvent->Param.NoteSynthParam.AbsValue = itEvent->Param.NoteSynthParam.Delta; + break; } // move note parameter event to its MIDI key