@@ -376,6 +376,7 @@ class AIService {
376376 final responseBuffer = StringBuffer ();
377377 bool audioHeaderSent = false ;
378378 bool hasReceivedAudio = false ;
379+ bool usePhoneAudio = ! _watchService.isConnected; // Track if we're using phone audio
379380 DateTime ? lastGlassesUpdate;
380381 const glassesUpdateInterval = Duration (milliseconds: 500 );
381382
@@ -409,12 +410,22 @@ class AIService {
409410 'AIService: Audio header - ${event .sampleRate }Hz, ${event .bitsPerSample }bit, ${event .channels }ch' );
410411 audioHeaderSent = true ;
411412 // Send audio header to watch if connected, otherwise start phone playback
412- if (_watchService.isConnected) {
413- await _watchService.sendAudioHeader (
413+ if (! usePhoneAudio && _watchService.isConnected) {
414+ final success = await _watchService.sendAudioHeader (
414415 sampleRate: event.sampleRate! ,
415416 bitsPerSample: event.bitsPerSample ?? 16 ,
416417 channels: event.channels ?? 1 ,
417418 );
419+ if (! success) {
420+ // Watch send failed - fall back to phone speaker
421+ debugPrint ('AIService: Watch audio header failed, falling back to phone' );
422+ usePhoneAudio = true ;
423+ await _audioPlayerService.startStreaming (
424+ sampleRate: event.sampleRate! ,
425+ bitsPerSample: event.bitsPerSample ?? 16 ,
426+ channels: event.channels ?? 1 ,
427+ );
428+ }
418429 } else {
419430 // Start streaming audio on phone speaker
420431 await _audioPlayerService.startStreaming (
@@ -430,8 +441,20 @@ class AIService {
430441 // Stream audio to watch speaker or phone speaker
431442 if (event.audioData != null && audioHeaderSent) {
432443 hasReceivedAudio = true ;
433- if (_watchService.isConnected) {
434- await _watchService.sendAudioChunk (event.audioData! );
444+ if (! usePhoneAudio && _watchService.isConnected) {
445+ final success = await _watchService.sendAudioChunk (event.audioData! );
446+ if (! success) {
447+ // Watch send failed - switch to phone audio
448+ debugPrint ('AIService: Watch audio chunk failed, switching to phone' );
449+ usePhoneAudio = true ;
450+ // Start phone streaming (we may have missed the header, use defaults)
451+ await _audioPlayerService.startStreaming (
452+ sampleRate: 24000 ,
453+ bitsPerSample: 16 ,
454+ channels: 1 ,
455+ );
456+ await _audioPlayerService.feedAudioChunk (event.audioData! );
457+ }
435458 } else {
436459 // Play on phone speaker
437460 await _audioPlayerService.feedAudioChunk (event.audioData! );
@@ -441,7 +464,7 @@ class AIService {
441464
442465 case ChatStreamEventType .audioEnd:
443466 // Audio streaming complete
444- if (_watchService.isConnected) {
467+ if (! usePhoneAudio && _watchService.isConnected) {
445468 await _watchService.sendAudioEnd ();
446469 } else {
447470 await _audioPlayerService.stopStreaming ();
@@ -717,6 +740,7 @@ class AIService {
717740 final responseBuffer = StringBuffer ();
718741 bool audioHeaderSent = false ;
719742 bool hasReceivedAudio = false ;
743+ bool usePhoneAudio = ! _watchService.isConnected; // Track if we're using phone audio
720744 DateTime ? lastGlassesUpdate;
721745 const glassesUpdateInterval = Duration (milliseconds: 500 );
722746
@@ -748,12 +772,21 @@ class AIService {
748772 debugPrint (
749773 'AIService: Audio header - ${event .sampleRate }Hz, ${event .bitsPerSample }bit, ${event .channels }ch' );
750774 audioHeaderSent = true ;
751- if (_watchService.isConnected) {
752- await _watchService.sendAudioHeader (
775+ if (! usePhoneAudio && _watchService.isConnected) {
776+ final success = await _watchService.sendAudioHeader (
753777 sampleRate: event.sampleRate! ,
754778 bitsPerSample: event.bitsPerSample ?? 16 ,
755779 channels: event.channels ?? 1 ,
756780 );
781+ if (! success) {
782+ debugPrint ('AIService: Watch audio header failed, falling back to phone' );
783+ usePhoneAudio = true ;
784+ await _audioPlayerService.startStreaming (
785+ sampleRate: event.sampleRate! ,
786+ bitsPerSample: event.bitsPerSample ?? 16 ,
787+ channels: event.channels ?? 1 ,
788+ );
789+ }
757790 } else {
758791 // Start streaming audio on phone speaker
759792 await _audioPlayerService.startStreaming (
@@ -769,8 +802,18 @@ class AIService {
769802 // Stream audio to watch speaker or phone speaker
770803 if (event.audioData != null && audioHeaderSent) {
771804 hasReceivedAudio = true ;
772- if (_watchService.isConnected) {
773- await _watchService.sendAudioChunk (event.audioData! );
805+ if (! usePhoneAudio && _watchService.isConnected) {
806+ final success = await _watchService.sendAudioChunk (event.audioData! );
807+ if (! success) {
808+ debugPrint ('AIService: Watch audio chunk failed, switching to phone' );
809+ usePhoneAudio = true ;
810+ await _audioPlayerService.startStreaming (
811+ sampleRate: 24000 ,
812+ bitsPerSample: 16 ,
813+ channels: 1 ,
814+ );
815+ await _audioPlayerService.feedAudioChunk (event.audioData! );
816+ }
774817 } else {
775818 // Play on phone speaker
776819 await _audioPlayerService.feedAudioChunk (event.audioData! );
@@ -780,7 +823,7 @@ class AIService {
780823
781824 case ChatStreamEventType .audioEnd:
782825 // Audio streaming complete
783- if (_watchService.isConnected) {
826+ if (! usePhoneAudio && _watchService.isConnected) {
784827 await _watchService.sendAudioEnd ();
785828 } else {
786829 await _audioPlayerService.stopStreaming ();
@@ -872,6 +915,7 @@ class AIService {
872915 final responseBuffer = StringBuffer ();
873916 bool audioHeaderSent = false ;
874917 bool hasReceivedAudio = false ;
918+ bool usePhoneAudio = ! _watchService.isConnected; // Track if we're using phone audio
875919 DateTime ? lastGlassesUpdate;
876920 const glassesUpdateInterval = Duration (milliseconds: 500 );
877921
@@ -900,12 +944,21 @@ class AIService {
900944 case ChatStreamEventType .audioHeader:
901945 if (event.sampleRate != null ) {
902946 audioHeaderSent = true ;
903- if (_watchService.isConnected) {
904- await _watchService.sendAudioHeader (
947+ if (! usePhoneAudio && _watchService.isConnected) {
948+ final success = await _watchService.sendAudioHeader (
905949 sampleRate: event.sampleRate! ,
906950 bitsPerSample: event.bitsPerSample ?? 16 ,
907951 channels: event.channels ?? 1 ,
908952 );
953+ if (! success) {
954+ debugPrint ('AIService: Watch audio header failed, falling back to phone' );
955+ usePhoneAudio = true ;
956+ await _audioPlayerService.startStreaming (
957+ sampleRate: event.sampleRate! ,
958+ bitsPerSample: event.bitsPerSample ?? 16 ,
959+ channels: event.channels ?? 1 ,
960+ );
961+ }
909962 } else {
910963 // Start streaming audio on phone speaker
911964 await _audioPlayerService.startStreaming (
@@ -920,8 +973,18 @@ class AIService {
920973 case ChatStreamEventType .audioChunk:
921974 if (event.audioData != null && audioHeaderSent) {
922975 hasReceivedAudio = true ;
923- if (_watchService.isConnected) {
924- await _watchService.sendAudioChunk (event.audioData! );
976+ if (! usePhoneAudio && _watchService.isConnected) {
977+ final success = await _watchService.sendAudioChunk (event.audioData! );
978+ if (! success) {
979+ debugPrint ('AIService: Watch audio chunk failed, switching to phone' );
980+ usePhoneAudio = true ;
981+ await _audioPlayerService.startStreaming (
982+ sampleRate: 24000 ,
983+ bitsPerSample: 16 ,
984+ channels: 1 ,
985+ );
986+ await _audioPlayerService.feedAudioChunk (event.audioData! );
987+ }
925988 } else {
926989 // Play on phone speaker
927990 await _audioPlayerService.feedAudioChunk (event.audioData! );
@@ -930,7 +993,7 @@ class AIService {
930993 break ;
931994
932995 case ChatStreamEventType .audioEnd:
933- if (_watchService.isConnected) {
996+ if (! usePhoneAudio && _watchService.isConnected) {
934997 await _watchService.sendAudioEnd ();
935998 } else {
936999 await _audioPlayerService.stopStreaming ();
0 commit comments