Skip to content

Commit

Permalink
Add equalpower crossfade ramp types
Browse files Browse the repository at this point in the history
- Update crossfade default to use equalpower ramps
- Add equalpower ramp fading to automation
  • Loading branch information
almic committed Apr 19, 2024
1 parent 038e5ef commit 8836dc9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
47 changes: 43 additions & 4 deletions src/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,23 @@ export enum AudioRampType {
EXPONENTIAL = 'exponential',

/**
* Natural ramp. Depending on the adjustment being made, this will either be a
* logarithmic adjustment, or an equal-power adjustment. In general, this option
* will produce the best sounding results compared to the other options, and in
* general should always be preferred over the others.
* Natural ramp. This is like exponential, but ideal for adjustments where
* you want a long tail, perfect for fading out sounds.
*/
NATURAL = 'natural',

/**
* Equal power ramp. This is ideal for crossfading two sources.
*/
EQUAL_POWER = 'equal_power',

/**
* Inverse equal power ramp. Advanced usages only!
*
* This should only be used in tandem with the normal equal power ramp,
* specifically applied to the incoming source of a crossfade.
*/
EQUAL_POWER_IN = 'equal_power_in',
}

/**
Expand Down Expand Up @@ -150,6 +161,34 @@ export default function automation(
);
break;
}
case AudioRampType.EQUAL_POWER:
case AudioRampType.EQUAL_POWER_IN: {
// Web Audio API does not have a built in equal power ramp
// setValueCurveAtTime linearly interpolates between values
const pollRate = 10;
const length = Math.round(pollRate * options.duration);
const valueCurve = new Float32Array(length);
const halfPi = Math.PI / 2;
const squashFactor = halfPi / length;
if (options.ramp == AudioRampType.EQUAL_POWER) {
for (let index = 0; index < length; index++) {
// V_0 -> V_1 == V_1 - (V_1 - V_0) * cos( (t - T) * (π / 2T) + (π / 2) )
valueCurve[index] =
value - difference * Math.cos((index - length) * squashFactor + halfPi);
}
} else {
for (let index = 0; index < length; index++) {
// V_0 -> V_1 == V_0 + (V_1 - V_0) * cos( (t - T) * (π / 2T) )
valueCurve[index] = currentValue + difference * Math.cos((index - length) * squashFactor);
}
}
audioParam.setValueCurveAtTime(
valueCurve,
options.delay + audioContext.currentTime,
options.duration,
);
break;
}
default: {
console.warn(`Automation function received unknown ramp type ${options.ramp}`);
audioParam.setValueAtTime(value, options.delay + audioContext.currentTime);
Expand Down
4 changes: 2 additions & 2 deletions src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ export const trackSwapOutIn: TrackSwapAdvancedOptions = Object.freeze({
*/
export const trackSwapCross: TrackSwapAdvancedOptions = Object.freeze({
oldSource: Object.freeze({
ramp: AudioRampType.NATURAL,
ramp: AudioRampType.EQUAL_POWER,
delay: 0,
duration: 1.2,
}),
newSource: Object.freeze({
ramp: AudioRampType.NATURAL,
ramp: AudioRampType.EQUAL_POWER_IN,
delay: 0,
duration: 1.2,
}),
Expand Down

0 comments on commit 8836dc9

Please sign in to comment.