Add configurable speech voice settings

This commit is contained in:
Ismail Ali
2026-04-28 15:42:42 +02:00
parent 82d982dea0
commit 96435e53e1
3 changed files with 40 additions and 4 deletions

View File

@@ -1,2 +1,7 @@
EXPO_PUBLIC_OLLAMA_BASE_URL=http://localhost:11434
EXPO_PUBLIC_OLLAMA_MODEL=llama3.2
EXPO_PUBLIC_SPEECH_LANGUAGE=en-US
EXPO_PUBLIC_SPEECH_RATE=0.85
EXPO_PUBLIC_SPEECH_PITCH=1
# Optional iOS voice identifier. Leave empty to use the first matching iPhone voice.
# EXPO_PUBLIC_SPEECH_VOICE=com.apple.voice.compact.en-US.Samantha

6
src/config/speech.ts Normal file
View File

@@ -0,0 +1,6 @@
export const speechConfig = {
language: process.env.EXPO_PUBLIC_SPEECH_LANGUAGE ?? 'en-US',
preferredVoice: process.env.EXPO_PUBLIC_SPEECH_VOICE,
pitch: Number(process.env.EXPO_PUBLIC_SPEECH_PITCH ?? 1),
rate: Number(process.env.EXPO_PUBLIC_SPEECH_RATE ?? 0.85),
};

View File

@@ -1,11 +1,19 @@
import * as Speech from 'expo-speech';
export function speakText(text: string) {
import { speechConfig } from '../config/speech';
let cachedVoice: string | undefined;
export async function speakText(text: string) {
Speech.stop();
const voice = await getPreferredVoice();
Speech.speak(stripThinkingBlocks(text), {
language: 'en-US',
pitch: 1,
rate: 0.9,
language: speechConfig.language,
pitch: speechConfig.pitch,
rate: speechConfig.rate,
voice,
});
}
@@ -16,3 +24,20 @@ export function stopSpeaking() {
function stripThinkingBlocks(text: string) {
return text.replace(/<think>[\s\S]*?<\/think>/gi, '').trim();
}
async function getPreferredVoice() {
if (cachedVoice) {
return cachedVoice;
}
if (speechConfig.preferredVoice) {
cachedVoice = speechConfig.preferredVoice;
return cachedVoice;
}
const voices = await Speech.getAvailableVoicesAsync();
const matchingVoice = voices.find((voice) => voice.language === speechConfig.language);
cachedVoice = matchingVoice?.identifier;
return cachedVoice;
}