Newer
Older
cortex-hub / ui / tts-client-app / src / services / audioUtils.js
// src/services/audioUtils.js

// This file should not import React or use any hooks.

export const stopAllPlayingAudio = (playingSourcesRef, audioContextRef, playbackTimeRef) => {
    if (audioContextRef.current) {
        playingSourcesRef.current.forEach((source) => {
            try {
                source.stop();
            } catch (e) {
                // Ignore errors from stopping already stopped sources
            }
        });
        playingSourcesRef.current = [];
        playbackTimeRef.current = audioContextRef.current.currentTime;
        console.log("All playing audio has been stopped.");
    }
};

export const stopAllMediaStreams = (vadStreamRef, mediaRecorderRef, scriptProcessorRef, streamRef) => {
    if (vadStreamRef.current) {
        vadStreamRef.current.getTracks().forEach((track) => track.stop());
        vadStreamRef.current = null;
    }
    if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
        mediaRecorderRef.current.stop();
    }
    if (scriptProcessorRef.current) {
        scriptProcessorRef.current.disconnect();
        scriptProcessorRef.current = null;
    }
    if (streamRef.current) {
        streamRef.current.getTracks().forEach(track => track.stop());
        streamRef.current = null;
    }
    console.log("All audio streams and timers have been stopped.");
};

export const resampleBuffer = (buffer, srcRate, dstRate) => {
    if (srcRate === dstRate) return buffer;
    const ratio = srcRate / dstRate;
    const newLength = Math.round(buffer.length / ratio);
    const resampled = new Float32Array(newLength);
    for (let i = 0; i < newLength; i++) {
        const srcIndex = i * ratio;
        const srcIndexFloor = Math.floor(srcIndex);
        const srcIndexCeil = Math.min(srcIndexFloor + 1, buffer.length - 1);
        const weight = srcIndex - srcIndexFloor;
        resampled[i] =
            buffer[srcIndexFloor] * (1 - weight) + buffer[srcIndexCeil] * weight;
    }
    return resampled;
};

export const convertPcmToFloat32 = (pcmBytes) => {
    const int16Array = new Int16Array(
        pcmBytes.buffer,
        pcmBytes.byteOffset,
        pcmBytes.byteLength / 2
    );
    const float32Array = new Float32Array(int16Array.length);
    for (let i = 0; i < int16Array.length; i++) {
        float32Array[i] = int16Array[i] / 32768;
    }
    return float32Array;
};