Files
Cyrene_v2/internal/runtime/multimodal/voice/voice.go
T
Aska 03d7050e1e
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
feat(voice): 百炼声音复刻create_voice + TTS instruction情绪驱动(主TTS-昔涟复刻音色)
2026-09-08 06:48:15 +08:00

64 lines
2.6 KiB
Go

// Package voice implements asynchronous speech-to-text and text-to-speech for
// the Cyrene runtime, following DevDocs/design/06-多模态.md §1.
//
// Voice input (STT) is transcribed to text and fed into the same agent pipeline
// as a chat message; the reply is synthesized (TTS) back to audio. Both
// directions degrade through a provider chain — cloud → local → edge-tts/espeak
// → silent — so an unavailable provider falls through to the next rung instead
// of failing the whole turn. The stub default implementations are HTTP-based and
// testable with a stdlib httptest server; real cloud/local providers remain
// adaptation points for later milestones.
package voice
import "context"
// Audio is a piece of audio data plus its encoding.
type Audio struct {
// Format is the encoding, e.g. "wav", "mp3", "ogg".
Format string
// Data is the raw audio bytes.
Data []byte
}
// STT converts audio to text.
type STT interface {
// STT transcribes audio and returns the spoken text. ctx controls
// cancellation and must be honored.
STT(ctx context.Context, audio Audio) (string, error)
}
// TTS synthesizes speech audio from text.
type TTS interface {
// TTS synthesizes audio from text. ctx controls cancellation and must be
// honored.
TTS(ctx context.Context, text string) (Audio, error)
}
// VoiceCloner creates a custom voice (声音复刻) from a public reference audio URL.
// A nil-cloner provider (no cloud rung configured) returns ErrNotConfigured.
type VoiceCloner interface {
// CloneVoice creates a custom voice and returns its voice_id. referenceURL is
// a public audio URL; prefix is the voice-name prefix (≤10 alphanumeric chars).
CloneVoice(ctx context.Context, referenceURL, prefix string) (string, error)
}
// ctxKeyTTSInstruction is the context key for a per-request TTS instruction.
// The TTS interface only carries (ctx, text), so an optional instruction is
// threaded through ctx to reach the adapter without widening the interface.
type ctxKeyTTSInstruction struct{}
// WithTTSInstruction returns ctx carrying an optional per-request TTS instruction
// (emotion/tone) that overrides the configured VOICE_TTS_INSTRUCTION for one call.
func WithTTSInstruction(ctx context.Context, instruction string) context.Context {
return context.WithValue(ctx, ctxKeyTTSInstruction{}, instruction)
}
// TTSInstructionFromContext returns the per-request TTS instruction set by
// WithTTSInstruction, or "" when none is carried.
func TTSInstructionFromContext(ctx context.Context) string {
if v, ok := ctx.Value(ctxKeyTTSInstruction{}).(string); ok {
return v
}
return ""
}