Platine etape 1

This commit is contained in:
valere
2025-12-07 19:44:21 +01:00
parent 9f70419ea5
commit 6176995032
15 changed files with 771 additions and 27 deletions

View File

@@ -0,0 +1,97 @@
class Sampler {
public audioContext: AudioContext = new AudioContext();
public gainNode: GainNode = new GainNode(this.audioContext);
public audioBuffer: AudioBuffer | null = null;
public audioBufferReversed: AudioBuffer | null = null;
public audioSource: AudioBufferSourceNode | null = null;
public duration: number = 0;
public isReversed: boolean = false;
constructor() {
this.gainNode.connect(this.audioContext.destination);
}
async getAudioBuffer(audioUrl: string) {
const response = await fetch(audioUrl);
const arrayBuffer = await response.arrayBuffer();
const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
return audioBuffer;
}
async loadTrack(audioUrl: string) {
this.audioBuffer = await this.getAudioBuffer(audioUrl);
this.audioBufferReversed = this.getReversedAudioBuffer(this.audioBuffer);
this.duration = this.audioBuffer.duration;
}
getReversedAudioBuffer(audioBuffer: AudioBuffer) {
const bufferArray = audioBuffer.getChannelData(0).slice().reverse();
const audioBufferReversed = this.audioContext.createBuffer(
1,
audioBuffer.length,
audioBuffer.sampleRate,
);
audioBufferReversed.getChannelData(0).set(bufferArray);
return audioBufferReversed;
}
changeDirection(isReversed: boolean, secondsPlayed: number) {
this.isReversed = isReversed;
this.play(secondsPlayed);
}
play(offset = 0) {
this.pause();
const buffer = this.isReversed
? this.audioBufferReversed
: this.audioBuffer;
const cueTime = this.isReversed ? this.duration - offset : offset;
this.audioSource = this.audioContext.createBufferSource();
this.audioSource.buffer = buffer;
this.audioSource.loop = false;
this.audioSource.connect(this.gainNode);
this.audioSource.start(0, cueTime);
}
updateSpeed(speed: number, isReversed: boolean, secondsPlayed: number) {
if (!this.audioSource) {
return;
}
if (isReversed !== this.isReversed) {
this.changeDirection(isReversed, secondsPlayed);
}
const { currentTime } = this.audioContext;
const speedAbsolute = Math.abs(speed);
this.audioSource.playbackRate.cancelScheduledValues(currentTime);
this.audioSource.playbackRate.linearRampToValueAtTime(
Math.max(0.001, speedAbsolute),
currentTime,
);
}
pause() {
if (!this.audioSource) {
return;
}
this.audioSource.stop();
}
}
export default Sampler;