@@ -118,20 +118,42 @@ <h1>🎤 Voice Interaction</h1>
118118 }
119119 }
120120
121- async function convertAndSend ( audioBlob ) {
122- // Convert webm to raw PCM using Web Audio API
123- const arrayBuffer = await audioBlob . arrayBuffer ( ) ;
124- const audioContext = new AudioContext ( ) ;
125- const audioBuffer = await audioContext . decodeAudioData ( arrayBuffer ) ;
126-
127- // Convert to mono 16kHz
128- const channelData = audioBuffer . getChannelData ( 0 ) ;
129- const samples = channelData . filter ( ( _ , i ) => i % 3 === 0 ) ; // Downsample
130- const int16Array = new Int16Array ( samples . length ) ;
131-
132- for ( let i = 0 ; i < samples . length ; i ++ ) {
133- int16Array [ i ] = Math . max ( - 1 , Math . min ( 1 , samples [ i ] ) ) * 32767 ;
121+ async function convertAndSend ( audioBlob ) {
122+ try {
123+ const arrayBuffer = await audioBlob . arrayBuffer ( ) ;
124+ const audioContext = new AudioContext ( ) ;
125+ const audioBuffer = await audioContext . decodeAudioData ( arrayBuffer ) ;
126+
127+ // Get mono channel and convert to 16kHz
128+ const channelData = audioBuffer . getChannelData ( 0 ) ;
129+ const sampleRate = audioBuffer . sampleRate ;
130+ const targetSampleRate = 16000 ;
131+
132+ // Resample
133+ const ratio = sampleRate / targetSampleRate ;
134+ const newLength = Math . floor ( channelData . length / ratio ) ;
135+ const resampled = new Float32Array ( newLength ) ;
136+
137+ for ( let i = 0 ; i < newLength ; i ++ ) {
138+ resampled [ i ] = channelData [ Math . floor ( i * ratio ) ] ;
139+ }
140+
141+ // Convert to Int16 PCM
142+ const int16Array = new Int16Array ( newLength ) ;
143+ for ( let i = 0 ; i < newLength ; i ++ ) {
144+ const sample = Math . max ( - 1 , Math . min ( 1 , resampled [ i ] ) ) ;
145+ int16Array [ i ] = sample * 32767 ;
146+ }
147+
148+ if ( ws && ws . readyState === WebSocket . OPEN ) {
149+ ws . send ( int16Array . buffer ) ;
150+ }
151+
152+ await audioContext . close ( ) ;
153+ } catch ( e ) {
154+ console . error ( 'Audio conversion error:' , e ) ;
134155 }
156+ }
135157
136158 if ( ws && ws . readyState === WebSocket . OPEN ) {
137159 ws . send ( int16Array . buffer ) ;
0 commit comments