TeaWeb/web/app/voice/AudioResampler.ts

47 lines
1.7 KiB
TypeScript
Raw Normal View History

2020-03-30 13:44:18 +02:00
import {LogCategory} from "tc-shared/log";
import * as log from "tc-shared/log";
export class AudioResampler {
2020-06-12 19:33:05 +02:00
readonly targetSampleRate: number;
2018-09-26 15:04:56 +02:00
private _use_promise: boolean;
2018-03-07 19:06:52 +01:00
constructor(targetSampleRate: number){
2018-03-07 19:06:52 +01:00
this.targetSampleRate = targetSampleRate;
if(this.targetSampleRate < 3000 || this.targetSampleRate > 384000) throw tr("The target sample rate is outside the range [3000, 384000].");
2018-03-07 19:06:52 +01:00
}
resample(buffer: AudioBuffer) : Promise<AudioBuffer> {
2018-09-26 15:04:56 +02:00
if(!buffer) {
2019-08-30 23:06:39 +02:00
log.warn(LogCategory.AUDIO, tr("Received empty buffer as input! Returning empty output!"));
return Promise.resolve(buffer);
2018-09-26 15:04:56 +02:00
}
2020-06-12 19:33:05 +02:00
2018-03-07 19:06:52 +01:00
if(buffer.sampleRate == this.targetSampleRate)
return Promise.resolve(buffer);
2018-03-07 19:06:52 +01:00
let context;
2018-09-26 15:30:22 +02:00
context = new (window.webkitOfflineAudioContext || window.OfflineAudioContext)(buffer.numberOfChannels, Math.ceil(buffer.length * this.targetSampleRate / buffer.sampleRate), this.targetSampleRate);
2018-03-07 19:06:52 +01:00
let source = context.createBufferSource();
source.buffer = buffer;
source.start(0);
2018-09-26 15:04:56 +02:00
source.connect(context.destination);
if(typeof(this._use_promise) === "undefined") {
this._use_promise = navigator.browserSpecs.name != 'Safari';
}
2018-03-07 19:06:52 +01:00
2018-09-26 15:04:56 +02:00
if(this._use_promise)
return context.startRendering();
else {
return new Promise<AudioBuffer>((resolve, reject) => {
context.oncomplete = event => resolve(event.renderedBuffer);
try {
context.startRendering();
} catch (ex) {
reject(ex);
}
})
}
2018-03-07 19:06:52 +01:00
}
}