166 lines
6.1 KiB
Bash
Executable File
166 lines
6.1 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# File: .claude/hooks/piper-multispeaker-registry.sh
|
|
#
|
|
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
# Website: https://agentvibes.org
|
|
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
#
|
|
# Co-created by Paul Preibisch with Claude AI
|
|
# Copyright (c) 2025 Paul Preibisch
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
# DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# express or implied, including but not limited to the warranties of
|
|
# merchantability, fitness for a particular purpose and noninfringement.
|
|
# In no event shall the authors or copyright holders be liable for any claim,
|
|
# damages or other liability, whether in an action of contract, tort or
|
|
# otherwise, arising from, out of or in connection with the software or the
|
|
# use or other dealings in the software.
|
|
#
|
|
# ---
|
|
#
|
|
# @fileoverview Multi-Speaker Voice Registry - Maps speaker names to ONNX models and speaker IDs
|
|
# @context Enables individual speaker selection from multi-speaker Piper models (e.g., 16Speakers)
|
|
# @architecture Static registry mapping speaker names to model files and numeric speaker IDs
|
|
# @dependencies piper-voice-manager.sh (voice storage), play-tts-piper.sh (TTS with speaker ID)
|
|
# @entrypoints Sourced by voice-manager.sh for multi-speaker voice switching
|
|
# @patterns Registry pattern, speaker ID mapping, model-to-speaker association
|
|
# @related voice-manager.sh, play-tts-piper.sh, 16Speakers.onnx.json (speaker_id_map)
|
|
#
|
|
|
|
# Registry of multi-speaker models and their speaker names
|
|
# Format: "SpeakerName:model_file:speaker_id:description"
|
|
#
|
|
# 16Speakers Model (12 US + 4 UK voices):
|
|
# Source: LibriVox Public Domain recordings
|
|
# Model: 16Speakers.onnx (77MB)
|
|
#
|
|
MULTISPEAKER_VOICES=(
|
|
# US English Speakers (0-11)
|
|
"Cori_Samuel:16Speakers:0:US English Female"
|
|
"Kara_Shallenberg:16Speakers:1:US English Female"
|
|
"Kristin_Hughes:16Speakers:2:US English Female"
|
|
"Maria_Kasper:16Speakers:3:US English Female"
|
|
"Mike_Pelton:16Speakers:4:US English Male"
|
|
"Mark_Nelson:16Speakers:5:US English Male"
|
|
"Michael_Scherer:16Speakers:6:US English Male"
|
|
"James_K_White:16Speakers:7:US English Male"
|
|
"Rose_Ibex:16Speakers:8:US English Female"
|
|
"progressingamerica:16Speakers:9:US English Male"
|
|
"Steve_C:16Speakers:10:US English Male"
|
|
"Owlivia:16Speakers:11:US English Female"
|
|
|
|
# UK English Speakers (12-15)
|
|
"Paul_Hampton:16Speakers:12:UK English Male"
|
|
"Jennifer_Dorr:16Speakers:13:UK English Female"
|
|
"Emily_Cripps:16Speakers:14:UK English Female"
|
|
"Martin_Clifton:16Speakers:15:UK English Male"
|
|
)
|
|
|
|
# @function get_multispeaker_info
|
|
# @intent Get model and speaker ID for a speaker name
|
|
# @why Enables users to select individual speakers from multi-speaker models by name
|
|
# @param $1 {string} speaker_name - Speaker name (e.g., "Cori_Samuel", "Rose_Ibex")
|
|
# @returns Echoes "model:speaker_id" (e.g., "16Speakers:0") to stdout
|
|
# @exitcode 0=speaker found, 1=speaker not found
|
|
# @sideeffects None (read-only lookup)
|
|
# @edgecases Case-insensitive matching
|
|
# @calledby voice-manager.sh switch command
|
|
# @calls None (pure bash array iteration)
|
|
get_multispeaker_info() {
|
|
local speaker_name="$1"
|
|
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
name="${entry%%:*}"
|
|
rest="${entry#*:}"
|
|
model="${rest%%:*}"
|
|
rest="${rest#*:}"
|
|
speaker_id="${rest%%:*}"
|
|
|
|
if [[ "${name,,}" == "${speaker_name,,}" ]]; then
|
|
echo "$model:$speaker_id"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# @function list_multispeaker_voices
|
|
# @intent Display all available multi-speaker voices with descriptions
|
|
# @why Help users discover individual speakers within multi-speaker models
|
|
# @param None
|
|
# @returns None
|
|
# @exitcode Always 0
|
|
# @sideeffects Writes formatted list to stdout
|
|
# @edgecases None
|
|
# @calledby voice-manager.sh list command, /agent-vibes:list
|
|
# @calls None (pure bash array iteration)
|
|
list_multispeaker_voices() {
|
|
echo "🎭 Multi-Speaker Voices (16Speakers Model):"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
local current_model=""
|
|
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
name="${entry%%:*}"
|
|
rest="${entry#*:}"
|
|
model="${rest%%:*}"
|
|
rest="${rest#*:}"
|
|
speaker_id="${rest%%:*}"
|
|
description="${rest#*:}"
|
|
|
|
# Print section header when model changes
|
|
if [[ "$model" != "$current_model" ]]; then
|
|
if [[ -n "$current_model" ]]; then
|
|
echo ""
|
|
fi
|
|
echo " Model: $model.onnx"
|
|
current_model="$model"
|
|
fi
|
|
|
|
echo " • $name (ID: $speaker_id) - $description"
|
|
done
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
echo "Usage: /agent-vibes:switch Cori_Samuel"
|
|
echo " /agent-vibes:switch Rose_Ibex"
|
|
}
|
|
|
|
# @function get_multispeaker_description
|
|
# @intent Get description for a speaker name
|
|
# @why Provide user-friendly info about speaker characteristics
|
|
# @param $1 {string} speaker_name - Speaker name
|
|
# @returns Echoes description (e.g., "US English Female") to stdout
|
|
# @exitcode 0=speaker found, 1=speaker not found
|
|
# @sideeffects None (read-only lookup)
|
|
# @edgecases Case-insensitive matching
|
|
# @calledby voice-manager.sh switch command (for confirmation message)
|
|
# @calls None (pure bash array iteration)
|
|
get_multispeaker_description() {
|
|
local speaker_name="$1"
|
|
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
name="${entry%%:*}"
|
|
rest="${entry#*:}"
|
|
rest="${rest#*:}"
|
|
rest="${rest#*:}"
|
|
description="${rest}"
|
|
|
|
if [[ "${name,,}" == "${speaker_name,,}" ]]; then
|
|
echo "$description"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|