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:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user