// Type definitions for scratch-audio
// Project: https://github.com/LLK/scratch-audio
///
declare namespace AudioEngine {
interface Target {
// TODO
}
interface Loudness {
audioContext: AudioContext;
connectingToMic: boolean;
mic: MediaStreamAudioSourceNode;
/**
* @returns Loudness measured from 0-100.
*/
getLoudness(): number;
}
interface AbstractEffect {
audioEngine: AudioEngine;
audioPlayer: SoundPlayer;
lastEffect: AbstractEffect;
value: number;
initialized: boolean;
initialize(): void;
inputNode: AudioNode;
getInputNode(): AudioNode;
outputNode: AudioNode;
target: Target;
connect(target: Target): void;
get name(): string;
get DEFAULT_VALUE(): string;
get _isPatch(): boolean;
_set(value: number): void;
set(value: number): void;
update(): void;
clear(): void;
dispose(): void;
}
interface PitchEffect extends AbstractEffect {
get name(): 'pitch';
ratio: number;
getRatio(val: number): number;
updatePlayer(soundPlayer: SoundPlayer): void;
updatePlayers(soundPlayers: Record | SoundPlayer[]): void;
}
interface PanEffect extends AbstractEffect {
get name(): 'pan';
leftGain: GainNode;
rightGain: GainNode;
channelMerger: ChannelMergerNode;
}
interface VolumeEffect extends AbstractEffect {
get name(): 'volume';
}
type Effect = PitchEffect | PanEffect | VolumeEffect;
interface EffectConstructor {
new(audioEngine: AudioEngine, soundPlayer: SoundPlayer, lastEffect: Effect | null): Effect;
}
interface EffectChain {
audioEngine: AudioEngine;
inputNode: GainNode;
getInputNode(): GainNode;
effects: EffectConstructor[];
_effects: Effect[];
firstEffect: Effect;
lastEffect: Effect;
_soundPlayers: Set;
getSoundPlayers(): SoundPlayer[];
clone(): EffectChain;
addSoundPlayer(soundPlayer: SoundPlayer): void;
removeSoundPlayer(soundPlayer: SoundPlayer): void;
target?: AudioNode;
connect(target: AudioNode): void;
setEffectsFromTarget(target: Target): void;
set(effect: string, value: number): void;
update(): void;
clear(): void;
dispose(): void;
}
interface SoundPlayerEventMap {
stop: [];
play: [];
}
interface SoundPlayer extends EventEmitter {
id: string;
audioEngine: AudioEngine;
buffer: AudioBuffer;
outputNode: AudioNode;
isStarting: boolean;
isPlaying: boolean;
startingUntil: number;
handleEvent(event: Event): void;
onEnded(): void;
_createSource(): void;
initialize(): void;
dispose(): void;
play(): void;
stop(): void;
stopImmediately(): void;
finished(): Promise;
setPlaybackRate(playbackRate: number): void;
take(): SoundPlayer;
connect(connectable: AudioEngine | Effect | EffectChain): void;
}
interface SoundBank {
audioEngine: AudioEngine;
/**
* Maps sound ID to its sound player.
*/
soundPlayers: Record;
/**
* Maps sound IDs to the target they were most recently been started by.
*/
playerTargets: Map;
/**
* Maps sound IDs to their effect chain.
*/
soundEffects: Map;
/**
* Original effect chain cloned for each sound.
*/
effectChainPrime: EffectChain;
addSoundPlayer(soundPlayer: SoundPlayer): void;
getSoundPlayer(soundId: string): SoundPlayer | undefined;
getSoundEffects(soundId: string): EffectChain;
playSound(target: Target, soundId: string): Promise;
setEffects(target: Target): void;
stop(target: Target, soundId: string): void;
stopAllSounds(target: Target | '*'): void;
dispose(): void;
}
interface SoundToDecode {
data: {
buffer: ArrayBuffer;
}
}
}
declare class AudioEngine {
constructor(audioContext?: AudioContext);
audioContext: AudioContext;
get currentTime(): number;
inputNode: GainNode;
getInputNode(): GainNode;
audioBuffers: Record;
loudness: AudioEngine.Loudness | null;
/**
* @see {AudioEngine.Loudness.getLoudness}
*/
getLoudness(): number;
effects: AudioEngine.EffectConstructor[];
get EFFECT_NAMES(): Record;
get DECAY_DURATION(): number;
get DECAY_WAIT(): number;
_emptySound(): AudioBuffer;
decodeSound(sound: AudioEngine.SoundToDecode): Promise;
decodeSoundPlayer(sound: AudioEngine.SoundToDecode): Promise;
/**
* Returns a tuple of [sound id, buffer]
*/
_decodeSound(sound: AudioEngine.SoundToDecode): Promise<[string, AudioBuffer]>;
createEffectChain(): AudioEngine.EffectChain;
createBank(): AudioEngine.SoundBank;
}