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 {
|
try {
|
||||||
state.opusDecoder = new AudioDecoder({
|
state.opusDecoder = new AudioDecoder({
|
||||||
output: (audioData) => playAudioData(audioData),
|
output: (audioData) => playAudioDataDirect(audioData),
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Opus decode error:', error);
|
console.error('Opus decode error:', error);
|
||||||
showError(`Opus decode error: ${error.message}`);
|
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) {
|
function decodeOpus(opusBuffer) {
|
||||||
if (!state.isListening || !state.opusDecoderReady) {
|
if (!state.isListening || !state.opusDecoderReady) {
|
||||||
if (state.isListening) {
|
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) {
|
function playPcm(arrayBuffer) {
|
||||||
if (!state.audioContextListen) return;
|
if (!state.audioContextListen) return;
|
||||||
const bytes = new Uint8Array(arrayBuffer);
|
const bytes = new Uint8Array(arrayBuffer);
|
||||||
|
|||||||
Reference in New Issue
Block a user