feat(audio): Wake-Word parallel zu TTS mit AcousticEchoCanceler
Du kannst jetzt "Computer" sagen waehrend ARIA noch redet — TTS verstummt, neue Aufnahme startet. Vorher musste man warten oder manuell den Voice-Button tappen. Native (OpenWakeWordModule.kt): - AudioRecord-Source von MIC auf VOICE_COMMUNICATION (aktiviert auf den meisten Geraeten Echo-Cancellation + Noise-Suppression) - Zusaetzlich AcousticEchoCanceler/NoiseSuppressor/AutomaticGainControl explizit aktiviert wenn vorhanden — robuster auf Geraeten wo die VOICE_COMMUNICATION-Source die Effects nicht automatisch mitbringt - releaseAudioEffects() im stop/dispose JS (wakeword.ts): - Neue API: startBargeListening / stopBargeListening — Wake-Word parallel aktivieren, ohne den State 'conversing' zu verlassen - onWakeDetected unterscheidet jetzt: in 'conversing' → barge-in- Callback (nicht der normale wake-callback). Sonst Standard-Pfad. - onBargeIn-Subscriber-API + isBargeListening-Getter Lifecycle-Wiring (audio.ts + ChatScreen): - audioService.onPlaybackStarted callback (neu) - ChatScreen: Bei TTS-Start → wakeWord.startBargeListening - ChatScreen: Bei TTS-Ende → wakeWord.stopBargeListening (sonst kein AudioRecord fuer die naechste Aufnahme) - ChatScreen: Bei BargeIn → haltAllPlayback + cancel_request + 150ms-Pause + neue Aufnahme starten issue.md + README aktualisiert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -668,6 +668,7 @@ class AudioService {
|
||||
}
|
||||
this._cancelDeferredFocusRelease();
|
||||
AudioFocus?.requestDuck().catch(() => {});
|
||||
this._firePlaybackStarted();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,6 +783,7 @@ class AudioService {
|
||||
|
||||
// Callback wenn alle Audio-Teile abgespielt sind
|
||||
private playbackFinishedListeners: (() => void)[] = [];
|
||||
private playbackStartedListeners: (() => void)[] = [];
|
||||
|
||||
onPlaybackFinished(callback: () => void): () => void {
|
||||
this.playbackFinishedListeners.push(callback);
|
||||
@@ -790,6 +792,21 @@ class AudioService {
|
||||
};
|
||||
}
|
||||
|
||||
/** Callback wenn ARIAs TTS-Wiedergabe startet — fuer Wake-Word-parallel-
|
||||
* Listening waehrend ARIA spricht (Barge-In via "Computer" sagen). */
|
||||
onPlaybackStarted(callback: () => void): () => void {
|
||||
this.playbackStartedListeners.push(callback);
|
||||
return () => {
|
||||
this.playbackStartedListeners = this.playbackStartedListeners.filter(cb => cb !== callback);
|
||||
};
|
||||
}
|
||||
|
||||
private _firePlaybackStarted(): void {
|
||||
this.playbackStartedListeners.forEach(cb => {
|
||||
try { cb(); } catch (e) { console.warn('[Audio] playbackStarted listener err:', e); }
|
||||
});
|
||||
}
|
||||
|
||||
/** Naechstes Audio aus der Queue abspielen */
|
||||
private async _playNext(): Promise<void> {
|
||||
if (this.audioQueue.length === 0) {
|
||||
@@ -802,10 +819,11 @@ class AudioService {
|
||||
return;
|
||||
}
|
||||
|
||||
// Beim ersten Playback-Start: andere Apps ducken
|
||||
// Beim ersten Playback-Start: andere Apps ducken + Listener informieren
|
||||
if (!this.isPlaying) {
|
||||
this._cancelDeferredFocusRelease();
|
||||
AudioFocus?.requestDuck().catch(() => {});
|
||||
this._firePlaybackStarted();
|
||||
}
|
||||
this.isPlaying = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user