avr-resampler
Version:
Audio Resampler for Agent Voice Response (AVR) STS or TTS service
67 lines • 3.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AudioResampler = void 0;
const libsamplerate_js_1 = require("@alexanderolsen/libsamplerate-js");
/**
* Audio Resampler for STS or TTS service
* Handles conversion between provider sample rate and client sample rate (8000 Hz)
*/
class AudioResampler {
constructor(outputSampleRate = 48000) {
this.inputSampleRate = 8000; // Fixed for client
this.outputSampleRate = outputSampleRate;
}
/**
* Initialize the downsampler (provider -> client)
*/
async initialize() {
console.log(`Initializing downsampler: ${this.outputSampleRate} Hz -> ${this.inputSampleRate} Hz`);
this.downResampler = await (0, libsamplerate_js_1.create)(1, this.outputSampleRate, this.inputSampleRate, {
converterType: libsamplerate_js_1.ConverterType.SRC_SINC_BEST_QUALITY, // best quality sinc filter
});
console.log(`Initializing upsampler: ${this.inputSampleRate} Hz -> ${this.outputSampleRate} Hz`);
this.upResampler = await (0, libsamplerate_js_1.create)(1, this.inputSampleRate, this.outputSampleRate, {
converterType: libsamplerate_js_1.ConverterType.SRC_SINC_BEST_QUALITY, // best quality sinc filter
});
}
/**
* Convert PCM16 to Float32, downsample, filter and convert back to PCM16
*/
downsample(pcm) {
const sampleCount = pcm.length / 2;
const float32Input = new Float32Array(sampleCount);
for (let i = 0; i < sampleCount; i++) {
const int16 = pcm.readInt16LE(i * 2);
float32Input[i] = int16 / 32768;
}
const float32Output = this.downResampler.full(float32Input);
const int16Output = new Int16Array(float32Output.length);
for (let i = 0; i < float32Output.length; i++) {
const s = Math.max(-1, Math.min(1, float32Output[i]));
int16Output[i] = Math.round(s * 32767);
}
return Buffer.from(int16Output.buffer, int16Output.byteOffset, int16Output.byteLength);
}
upsample(pcm) {
const sampleCount = pcm.length / 2; // 16 bit = 2 byte per sample
const float32Input = new Float32Array(sampleCount);
// Converti Int16 LE -> Float32 normalizzati (-1.0 a 1.0)
for (let i = 0; i < sampleCount; i++) {
const int16 = pcm.readInt16LE(i * 2);
float32Input[i] = int16 / 32768;
}
const float32Output = this.upResampler.full(float32Input);
const int16Output = new Int16Array(float32Output.length);
for (let i = 0; i < float32Output.length; i++) {
const s = Math.max(-1, Math.min(1, float32Output[i]));
int16Output[i] = Math.round(s * 32767);
}
return Buffer.from(int16Output.buffer, int16Output.byteOffset, int16Output.byteLength);
}
destroy() {
this.downResampler.destroy();
this.upResampler.destroy();
}
}
exports.AudioResampler = AudioResampler;
//# sourceMappingURL=index.js.map