97cb7be313
Kurzer akustischer Hinweis (Airplane Ding-Dong, 20KB MP3) bei audioService.startRecording-Erfolg im Wake-Word-Pfad — User weiss exakt ab wann er reden darf, statt das Toast nur zu sehen. Quelldatei: android/sounds/Airplane-ding-dong.mp2 → ffmpeg-konvertiert zu MP3 64kbps, abgelegt in android/app/src/main/res/raw/ damit Android sie als Resource laden kann. Toggle in App-Settings → Wake-Word, default aktiv. Bei Aktivierung spielt direkt eine Vorschau ab damit man weiss wie's klingt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
/**
|
|
* Spielt einen kurzen "Bereit"-Sound (Airplane Ding-Dong) wenn das Mikrofon
|
|
* nach Wake-Word-Erkennung wirklich offen ist. Datei liegt in
|
|
* android/app/src/main/res/raw/wake_ready_sound.mp3 — wird ueber Android's
|
|
* Resource-System per react-native-sound abgespielt.
|
|
*
|
|
* Toggle: AsyncStorage-Key 'aria_wake_ready_sound_enabled' (default true).
|
|
*/
|
|
|
|
import Sound from 'react-native-sound';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
|
export const WAKE_READY_SOUND_STORAGE_KEY = 'aria_wake_ready_sound_enabled';
|
|
|
|
Sound.setCategory('Playback', false);
|
|
|
|
let cachedSound: Sound | null = null;
|
|
let cachedFailed = false;
|
|
|
|
function getSound(): Promise<Sound | null> {
|
|
if (cachedFailed) return Promise.resolve(null);
|
|
if (cachedSound) return Promise.resolve(cachedSound);
|
|
return new Promise(resolve => {
|
|
const s = new Sound('wake_ready_sound', Sound.MAIN_BUNDLE, (err) => {
|
|
if (err) {
|
|
console.warn('[WakeReadySound] Konnte nicht geladen werden:', err);
|
|
cachedFailed = true;
|
|
resolve(null);
|
|
return;
|
|
}
|
|
cachedSound = s;
|
|
resolve(s);
|
|
});
|
|
});
|
|
}
|
|
|
|
/** True wenn der User den "Bereit"-Sound aktiviert hat. Default: true. */
|
|
export async function isWakeReadySoundEnabled(): Promise<boolean> {
|
|
try {
|
|
const raw = await AsyncStorage.getItem(WAKE_READY_SOUND_STORAGE_KEY);
|
|
if (raw === null) return true; // Default an
|
|
return raw === 'true';
|
|
} catch {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
export async function setWakeReadySoundEnabled(enabled: boolean): Promise<void> {
|
|
try {
|
|
await AsyncStorage.setItem(WAKE_READY_SOUND_STORAGE_KEY, String(enabled));
|
|
} catch {}
|
|
}
|
|
|
|
/** Spielt den Bereit-Sound einmal ab — non-blocking. Wenn der User ihn
|
|
* in den Settings deaktiviert hat oder die Datei nicht ladbar ist,
|
|
* passiert einfach nichts. */
|
|
export async function playWakeReadySound(): Promise<void> {
|
|
if (!(await isWakeReadySoundEnabled())) return;
|
|
const s = await getSound();
|
|
if (!s) return;
|
|
try {
|
|
s.stop(() => {
|
|
s.setCurrentTime(0);
|
|
s.play((success) => {
|
|
if (!success) console.warn('[WakeReadySound] Wiedergabe fehlgeschlagen');
|
|
});
|
|
});
|
|
} catch (e) {
|
|
console.warn('[WakeReadySound] play() Exception:', e);
|
|
}
|
|
}
|