UNPKG

automation-events

Version:

A module which provides an implementation of an automation event list.

161 lines 11.4 kB
import { createExtendedExponentialRampToValueAutomationEvent } from '../functions/create-extended-exponential-ramp-to-value-automation-event'; import { createExtendedLinearRampToValueAutomationEvent } from '../functions/create-extended-linear-ramp-to-value-automation-event'; import { createSetValueAutomationEvent } from '../functions/create-set-value-automation-event'; import { createSetValueCurveAutomationEvent } from '../functions/create-set-value-curve-automation-event'; import { getEndTimeAndValueOfPreviousAutomationEvent } from '../functions/get-end-time-and-value-of-previous-automation-event'; import { getEventTime } from '../functions/get-event-time'; import { getExponentialRampValueAtTime } from '../functions/get-exponential-ramp-value-at-time'; import { getLinearRampValueAtTime } from '../functions/get-linear-ramp-value-at-time'; import { getTargetValueAtTime } from '../functions/get-target-value-at-time'; import { getValueCurveValueAtTime } from '../functions/get-value-curve-value-at-time'; import { getValueOfAutomationEventAtIndexAtTime } from '../functions/get-value-of-automation-event-at-index-at-time'; import { truncateValueCurve } from '../functions/truncate-value-curve'; import { isAnyRampToValueAutomationEvent } from '../guards/any-ramp-to-value-automation-event'; import { isCancelAndHoldAutomationEvent } from '../guards/cancel-and-hold-automation-event'; import { isCancelScheduledValuesAutomationEvent } from '../guards/cancel-scheduled-values-automation-event'; import { isExponentialRampToValueAutomationEvent } from '../guards/exponential-ramp-to-value-automation-event'; import { isLinearRampToValueAutomationEvent } from '../guards/linear-ramp-to-value-automation-event'; import { isSetTargetAutomationEvent } from '../guards/set-target-automation-event'; import { isSetValueAutomationEvent } from '../guards/set-value-automation-event'; import { isSetValueCurveAutomationEvent } from '../guards/set-value-curve-automation-event'; export class AutomationEventList { constructor(defaultValue) { this._automationEvents = []; this._currenTime = 0; this._defaultValue = defaultValue; } [Symbol.iterator]() { return this._automationEvents[Symbol.iterator](); } add(automationEvent) { const eventTime = getEventTime(automationEvent); if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) { const index = this._automationEvents.findIndex((currentAutomationEvent) => { if (isCancelScheduledValuesAutomationEvent(automationEvent) && isSetValueCurveAutomationEvent(currentAutomationEvent)) { return currentAutomationEvent.startTime + currentAutomationEvent.duration >= eventTime; } return getEventTime(currentAutomationEvent) >= eventTime; }); const removedAutomationEvent = this._automationEvents[index]; if (index !== -1) { this._automationEvents = this._automationEvents.slice(0, index); } if (isCancelAndHoldAutomationEvent(automationEvent)) { const lastAutomationEvent = this._automationEvents[this._automationEvents.length - 1]; if (removedAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(removedAutomationEvent)) { if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) { throw new Error('The internal list is malformed.'); } const startTime = lastAutomationEvent === undefined ? removedAutomationEvent.insertTime : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.startTime + lastAutomationEvent.duration : getEventTime(lastAutomationEvent); const startValue = lastAutomationEvent === undefined ? this._defaultValue : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.values[lastAutomationEvent.values.length - 1] : lastAutomationEvent.value; const value = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? getExponentialRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent) : getLinearRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent); const truncatedAutomationEvent = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? createExtendedExponentialRampToValueAutomationEvent(value, eventTime, this._currenTime) : createExtendedLinearRampToValueAutomationEvent(value, eventTime, this._currenTime); this._automationEvents.push(truncatedAutomationEvent); } if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) { this._automationEvents.push(createSetValueAutomationEvent(this.getValue(eventTime), eventTime)); } if (lastAutomationEvent !== undefined && isSetValueCurveAutomationEvent(lastAutomationEvent) && lastAutomationEvent.startTime + lastAutomationEvent.duration > eventTime) { const duration = eventTime - lastAutomationEvent.startTime; this._automationEvents[this._automationEvents.length - 1] = createSetValueCurveAutomationEvent(truncateValueCurve(lastAutomationEvent.values, lastAutomationEvent.duration, duration), lastAutomationEvent.startTime, duration); } } } else { const index = this._automationEvents.findIndex((currentAutomationEvent) => getEventTime(currentAutomationEvent) > eventTime); const previousAutomationEvent = index === -1 ? this._automationEvents[this._automationEvents.length - 1] : this._automationEvents[index - 1]; if (previousAutomationEvent !== undefined && isSetValueCurveAutomationEvent(previousAutomationEvent) && getEventTime(previousAutomationEvent) + previousAutomationEvent.duration > eventTime) { return false; } const persistentAutomationEvent = isExponentialRampToValueAutomationEvent(automationEvent) ? createExtendedExponentialRampToValueAutomationEvent(automationEvent.value, automationEvent.endTime, this._currenTime) : isLinearRampToValueAutomationEvent(automationEvent) ? createExtendedLinearRampToValueAutomationEvent(automationEvent.value, eventTime, this._currenTime) : automationEvent; if (index === -1) { this._automationEvents.push(persistentAutomationEvent); } else { if (isSetValueCurveAutomationEvent(automationEvent) && eventTime + automationEvent.duration > getEventTime(this._automationEvents[index])) { return false; } this._automationEvents.splice(index, 0, persistentAutomationEvent); } } return true; } flush(time) { const index = this._automationEvents.findIndex((currentAutomationEvent) => getEventTime(currentAutomationEvent) > time); if (index > 1) { const remainingAutomationEvents = this._automationEvents.slice(index - 1); const firstRemainingAutomationEvent = remainingAutomationEvents[0]; if (isSetTargetAutomationEvent(firstRemainingAutomationEvent)) { remainingAutomationEvents.unshift(createSetValueAutomationEvent(getValueOfAutomationEventAtIndexAtTime(this._automationEvents, index - 2, firstRemainingAutomationEvent.startTime, this._defaultValue), firstRemainingAutomationEvent.startTime)); } this._automationEvents = remainingAutomationEvents; } } getValue(time) { if (this._automationEvents.length === 0) { return this._defaultValue; } const indexOfNextEvent = this._automationEvents.findIndex((automationEvent) => getEventTime(automationEvent) > time); const nextAutomationEvent = this._automationEvents[indexOfNextEvent]; const indexOfCurrentEvent = (indexOfNextEvent === -1 ? this._automationEvents.length : indexOfNextEvent) - 1; const currentAutomationEvent = this._automationEvents[indexOfCurrentEvent]; if (currentAutomationEvent !== undefined && isSetTargetAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || nextAutomationEvent.insertTime > time)) { return getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(this._automationEvents, indexOfCurrentEvent - 1, currentAutomationEvent.startTime, this._defaultValue), currentAutomationEvent); } if (currentAutomationEvent !== undefined && isSetValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) { return currentAutomationEvent.value; } if (currentAutomationEvent !== undefined && isSetValueCurveAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || currentAutomationEvent.startTime + currentAutomationEvent.duration > time)) { if (time < currentAutomationEvent.startTime + currentAutomationEvent.duration) { return getValueCurveValueAtTime(time, currentAutomationEvent); } return currentAutomationEvent.values[currentAutomationEvent.values.length - 1]; } if (currentAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) { return currentAutomationEvent.value; } if (nextAutomationEvent !== undefined && isExponentialRampToValueAutomationEvent(nextAutomationEvent)) { const [startTime, value] = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue); return getExponentialRampValueAtTime(time, startTime, value, nextAutomationEvent); } if (nextAutomationEvent !== undefined && isLinearRampToValueAutomationEvent(nextAutomationEvent)) { const [startTime, value] = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue); return getLinearRampValueAtTime(time, startTime, value, nextAutomationEvent); } return this._defaultValue; } } //# sourceMappingURL=automation-event-list.js.map