Chime event → file mapping in voices.yaml

YAML chimes section maps event names to arbitrary file paths.
Falls back to chimes/<name>.wav or .ogg if not listed.
Allows custom locations and formats without renaming files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-30 05:25:47 +00:00
parent 688549a6c3
commit 0a16bd6da3
2 changed files with 17 additions and 8 deletions

View File

@@ -28,16 +28,16 @@ const PORT = parseInt(process.env.TTS_PORT ?? '11500')
const VOICES_FILE = path.join(import.meta.dirname, 'voices.yaml')
const CHIMES_DIR = path.join(import.meta.dirname, 'chimes')
function reload_voices() {
function reload_config() {
try {
const doc = yaml.load(fs.readFileSync(VOICES_FILE, 'utf8'))
return doc?.voices ?? {}
return { voices: doc?.voices ?? {}, chimes: doc?.chimes ?? {} }
} catch {
return {}
return { voices: {}, chimes: {} }
}
}
let voices = reload_voices()
let { voices, chimes } = reload_config()
let current_voice = null // name of active voice, or null
// --- TTS setup ---
@@ -87,7 +87,7 @@ const server = http.createServer(async (req, res) => {
}
if (req.method === 'GET' && req.url === '/voices') {
voices = reload_voices()
({ voices, chimes } = reload_config())
const list = Object.entries(voices).map(([name, v]) => ({
name,
description: v.description ?? '',
@@ -103,7 +103,7 @@ const server = http.createServer(async (req, res) => {
}
const { name } = body
if (!name) return send(res, 400, { error: 'name required' })
voices = reload_voices()
;({ voices, chimes } = reload_config())
if (!voices[name]) return send(res, 404, { error: `unknown voice: ${name}` })
current_voice = name
process.stderr.write(`[tts-server] voice switched to: ${name}\n`)
@@ -117,10 +117,11 @@ const server = http.createServer(async (req, res) => {
}
const { name } = body
if (!name) return send(res, 400, { error: 'name required' })
// Try .wav then .ogg
// YAML mapping takes priority; fall back to chimes/<name>.wav or .ogg
;({ voices, chimes } = reload_config())
const wav = path.join(CHIMES_DIR, `${name}.wav`)
const ogg = path.join(CHIMES_DIR, `${name}.ogg`)
const file = fs.existsSync(wav) ? wav : fs.existsSync(ogg) ? ogg : null
const file = chimes[name] ?? (fs.existsSync(wav) ? wav : fs.existsSync(ogg) ? ogg : null)
if (!file) return send(res, 404, { error: `chime not found: ${name}` })
try {
await enqueue(() => play_file(file))