Skip to content

Instantly share code, notes, and snippets.

@eliassjogreen
Created April 27, 2023 08:29
Show Gist options
  • Save eliassjogreen/6a1c3fac2ac1090a014c32748153cbaa to your computer and use it in GitHub Desktop.
Save eliassjogreen/6a1c3fac2ac1090a014c32748153cbaa to your computer and use it in GitHub Desktop.
expo-av fade
import { Audio } from "expo-av";
export function linear(n: number): [number, number] {
return [1 - n, n];
}
export function halfsine(n: number): [number, number] {
return [1 - Math.sin(n * Math.PI * 0.5), Math.sin(n * Math.PI * 0.5)];
}
export function instant(n: number): [number, number] {
return [n < 0.5 ? 1 : 0, n > 0.5 ? 1 : 0];
}
export interface FadeOptions {
duration: number;
shape: (n: number) => [number, number];
}
export const defaultFadeOptions: FadeOptions = {
volume: 1,
duration: 5000,
interval: 100,
shape: linear,
};
/**
* Fades two audio sources together over a specified {@link duration} in
* {@link interval time steps} using it's {@link shape} method into a final
* specified {@link volume}.
*/
export async function fade(
a: Audio.Sound,
b: Audio.Sound,
options?: Partial<FadeOptions>
): Promise<void> {
const volume = options.volume ?? defaultFadeOptions.volume;
const duration = options.duration ?? defaultFadeOptions.duration;
const interval = options.interval ?? defaultFadeOptions.interval;
const shape = options.shape ?? defaultFadeOptions.shape;
return new Promise((resolve) => {
let elapsed = 0;
b.playAsync();
const id = setInterval(() => {
elapsed += interval;
if (elapsed > duration || !a._loaded || !b._loaded) {
// Make sure that both sounds end up at the proper volume.
if (a._loaded) {
a.setVolumeAsync(0);
}
if (b._loaded) {
b.setVolumeAsync(volume);
}
clearInterval(id);
resolve();
return;
}
const n = elapsed / duration;
const volumes = shape(n);
// Set the volumes to the absolute volume calculated by the step scaled to the target volume
Promise.all([a.setVolumeAsync(volumes[0] * volume), b.setVolumeAsync(volumes[1] * volume)]);
}, interval);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment