fix: simplify AudioData playback with direct copyTo approach
- Rename playAudioData to playAudioDataDirect for clarity - Remove duplicate playAudioData function with debug logging - Use direct copyTo into temp Float32Array per channel - Check isListening state in output callback
This commit is contained in:
@@ -437,7 +437,7 @@ const state = {
|
||||
}
|
||||
try {
|
||||
state.opusDecoder = new AudioDecoder({
|
||||
output: (audioData) => playAudioData(audioData),
|
||||
output: (audioData) => playAudioDataDirect(audioData),
|
||||
error: (error) => {
|
||||
console.error('Opus decode error:', error);
|
||||
showError(`Opus decode error: ${error.message}`);
|
||||
@@ -458,6 +458,39 @@ const state = {
|
||||
}
|
||||
}
|
||||
|
||||
function playAudioDataDirect(audioData) {
|
||||
if (!state.audioContextListen || !state.isListening) {
|
||||
audioData.close();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const sampleRate = audioData.sampleRate;
|
||||
const frameCount = audioData.numberOfFrames;
|
||||
const numberOfChannels = audioData.numberOfChannels;
|
||||
const audioBuffer = state.audioContextListen.createBuffer(
|
||||
numberOfChannels,
|
||||
frameCount,
|
||||
sampleRate
|
||||
);
|
||||
for (let ch = 0; ch < numberOfChannels; ch++) {
|
||||
const channelData = audioBuffer.getChannelData(ch);
|
||||
const tempArray = new Float32Array(frameCount);
|
||||
audioData.copyTo(tempArray, { planeIndex: ch });
|
||||
channelData.set(tempArray);
|
||||
}
|
||||
const source = state.audioContextListen.createBufferSource();
|
||||
source.buffer = audioBuffer;
|
||||
source.connect(state.audioContextListen.destination);
|
||||
const startAt = Math.max(state.nextStartTime, state.audioContextListen.currentTime);
|
||||
source.start(startAt);
|
||||
state.nextStartTime = startAt + audioBuffer.duration;
|
||||
} catch (error) {
|
||||
console.error('Play audio error:', error);
|
||||
} finally {
|
||||
audioData.close();
|
||||
}
|
||||
}
|
||||
|
||||
function decodeOpus(opusBuffer) {
|
||||
if (!state.isListening || !state.opusDecoderReady) {
|
||||
if (state.isListening) {
|
||||
@@ -484,39 +517,6 @@ const state = {
|
||||
}
|
||||
}
|
||||
|
||||
function playAudioData(audioData) {
|
||||
if (!state.audioContextListen) {
|
||||
audioData.close();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const sampleRate = audioData.sampleRate;
|
||||
const frameCount = audioData.numberOfFrames;
|
||||
const numberOfChannels = audioData.numberOfChannels;
|
||||
console.log(`AudioData: ${frameCount} frames, ${numberOfChannels} ch, ${sampleRate}Hz`);
|
||||
const audioBuffer = state.audioContextListen.createBuffer(
|
||||
numberOfChannels,
|
||||
frameCount,
|
||||
sampleRate
|
||||
);
|
||||
for (let ch = 0; ch < numberOfChannels; ch++) {
|
||||
const channelData = audioBuffer.getChannelData(ch);
|
||||
console.log(`Channel ${ch}: copyTo into ${channelData.length} samples`);
|
||||
audioData.copyTo(channelData, { planeIndex: ch });
|
||||
}
|
||||
const source = state.audioContextListen.createBufferSource();
|
||||
source.buffer = audioBuffer;
|
||||
source.connect(state.audioContextListen.destination);
|
||||
const startAt = Math.max(state.nextStartTime, state.audioContextListen.currentTime);
|
||||
source.start(startAt);
|
||||
state.nextStartTime = startAt + audioBuffer.duration;
|
||||
} catch (error) {
|
||||
console.error('Play audio error:', error);
|
||||
} finally {
|
||||
audioData.close();
|
||||
}
|
||||
}
|
||||
|
||||
function playPcm(arrayBuffer) {
|
||||
if (!state.audioContextListen) return;
|
||||
const bytes = new Uint8Array(arrayBuffer);
|
||||
|
||||
Reference in New Issue
Block a user