mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import { getApp } from "../olympusapp";
|
|
import { Filter, Noise } from "./audiolibrary";
|
|
|
|
export class PlaybackPipeline {
|
|
#decoder = new AudioDecoder({
|
|
output: (chunk) => this.#handleDecodedData(chunk),
|
|
error: (e) => console.log(e),
|
|
});
|
|
#trackGenerator: any; // TODO can we have typings?
|
|
#writer: any;
|
|
#gainNode: GainNode;
|
|
#pannerNode: StereoPannerNode;
|
|
#enabled: boolean = false;
|
|
|
|
constructor() {
|
|
this.#decoder.configure({
|
|
codec: "opus",
|
|
numberOfChannels: 1,
|
|
sampleRate: 16000,
|
|
//@ts-ignore // TODO why is this giving an error?
|
|
opus: {
|
|
frameDuration: 40000,
|
|
},
|
|
bitrateMode: "constant",
|
|
});
|
|
|
|
//@ts-ignore
|
|
this.#trackGenerator = new MediaStreamTrackGenerator({ kind: "audio" });
|
|
this.#writer = this.#trackGenerator.writable.getWriter();
|
|
|
|
const stream = new MediaStream([this.#trackGenerator]);
|
|
const mediaStreamSource = getApp().getAudioManager().getAudioContext().createMediaStreamSource(stream);
|
|
|
|
/* Connect to the device audio output */
|
|
this.#gainNode = getApp().getAudioManager().getAudioContext().createGain();
|
|
this.#pannerNode = getApp().getAudioManager().getAudioContext().createStereoPanner();
|
|
let splitter = getApp().getAudioManager().getAudioContext().createChannelSplitter();
|
|
let bandpass = new Filter(getApp().getAudioManager().getAudioContext(), "banpass", 600, 10);
|
|
bandpass.setup();
|
|
|
|
mediaStreamSource.connect(this.#gainNode);
|
|
this.#gainNode.connect(bandpass.input);
|
|
bandpass.output.connect(splitter);
|
|
splitter.connect(this.#pannerNode);
|
|
|
|
this.#pannerNode.pan.setValueAtTime(0, getApp().getAudioManager().getAudioContext().currentTime);
|
|
|
|
let noise = new Noise(getApp().getAudioManager().getAudioContext(), 0.01);
|
|
noise.init();
|
|
noise.connect(this.#gainNode);
|
|
}
|
|
|
|
playBuffer(arrayBuffer) {
|
|
const init = {
|
|
type: "key",
|
|
data: arrayBuffer,
|
|
timestamp: 0,
|
|
duration: 2000000,
|
|
transfer: [arrayBuffer],
|
|
};
|
|
//@ts-ignore //TODO Typings?
|
|
let encodedAudioChunk = new EncodedAudioChunk(init);
|
|
|
|
this.#decoder.decode(encodedAudioChunk);
|
|
}
|
|
|
|
setEnabled(enabled) {
|
|
if (enabled && !this.#enabled) {
|
|
this.#enabled = true;
|
|
this.#pannerNode.connect(getApp().getAudioManager().getAudioContext().destination);
|
|
} else if (!enabled && this.#enabled) {
|
|
this.#enabled = false;
|
|
this.#pannerNode.disconnect(getApp().getAudioManager().getAudioContext().destination);
|
|
}
|
|
}
|
|
|
|
setPan(pan) {
|
|
this.#pannerNode.pan.setValueAtTime(pan, getApp().getAudioManager().getAudioContext().currentTime);
|
|
}
|
|
|
|
#handleDecodedData(audioData) {
|
|
this.#writer.ready.then(() => {
|
|
this.#writer.write(audioData);
|
|
});
|
|
}
|
|
}
|