From 67decc42f09865b698485817c243211e9082485e Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 6 Aug 2026 03:00:21 +0400 Subject: [PATCH] sweep: name voice-daemon magic numbers, drop dead keep-alive vars (V-581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mavsttd/whisper_handler.go: name the no_speech_prob confidence-zeroing floor (0.9) and the whisper thread count (4), both previously bare literals with no reason attached. mavttsd/piper_handler.go: name piper's render rate (22050) and the canonical wire rate (16000) used by the resampler, instead of repeating the two numbers inline four times. mavenclient/main.go: remove the strconv/io/net/time imports and their `var _ = ...` keep-alive lines — dead weight with no caller, not future scaffolding. Behaviour-preserving; no test changed. go test -race ./internal/... ./cmd/... is green. --- cmd/mavenclient/main.go | 10 ---------- cmd/mavsttd/whisper_handler.go | 16 ++++++++++++++-- cmd/mavttsd/piper_handler.go | 17 +++++++++++++---- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/cmd/mavenclient/main.go b/cmd/mavenclient/main.go index 6427f0c..bb4b839 100644 --- a/cmd/mavenclient/main.go +++ b/cmd/mavenclient/main.go @@ -31,15 +31,11 @@ import ( "errors" "flag" "fmt" - "io" "log" - "net" "os" "os/signal" "path/filepath" - "strconv" "syscall" - "time" "github.com/kami/maven/internal/audio" "github.com/kami/maven/internal/voice" @@ -155,9 +151,3 @@ func writeWAV(path string, a audio.Audio) error { // jsonUnmarshal — kept local rather than pulling encoding/json into main.go // top-level space. func jsonUnmarshal(b []byte, v any) error { return json.Unmarshal(b, v) } - -// keep strconv + io + net + time alive for future duration/size helpers. -var _ = strconv.Atoi -var _ io.Reader = (io.Reader)(nil) -var _ = net.IPv4 -var _ = time.Second diff --git a/cmd/mavsttd/whisper_handler.go b/cmd/mavsttd/whisper_handler.go index bc58cbd..f4a9c00 100644 --- a/cmd/mavsttd/whisper_handler.go +++ b/cmd/mavsttd/whisper_handler.go @@ -22,6 +22,18 @@ import ( // to it before sending, so it's also the rate the silence gate assumes. const whisperSampleRate = 16000 +// whisperThreads — greedy decode is single-pass and this is a laptop CPU +// (homesrv), not a server box; 4 was picked to leave headroom for the rest +// of the daemons sharing the machine, not measured against a latency target. +const whisperThreads = 4 + +// noSpeechFloor — whisper's own no_speech_prob past this point means the +// segment it transcribed is not speech (the model still emits token +// probabilities for silence/noise, so a high avgLogProb-derived confidence +// can coexist with a segment that should be zero). Read as "at least 90% +// sure this was not speech." +const noSpeechFloor = 0.9 + type whisperHandler struct { ctx *C.struct_whisper_context minMs int // clips shorter than this are dropped (hallucination bait) @@ -101,7 +113,7 @@ func (h *whisperHandler) Transcribe(ctx context.Context, req worker.TranscribeRe params.print_realtime = false params.print_timestamps = false params.print_special = false - params.n_threads = C.int(4) + params.n_threads = C.int(whisperThreads) params.single_segment = true lang := C.CString(req.Lang) @@ -162,7 +174,7 @@ func (h *whisperHandler) Transcribe(ctx context.Context, req worker.TranscribeRe } noSpeechProb := float64(C.whisper_full_get_segment_no_speech_prob(h.ctx, 0)) - if noSpeechProb > 0.9 { + if noSpeechProb > noSpeechFloor { confidence = 0 } diff --git a/cmd/mavttsd/piper_handler.go b/cmd/mavttsd/piper_handler.go index a80a618..160d0b0 100644 --- a/cmd/mavttsd/piper_handler.go +++ b/cmd/mavttsd/piper_handler.go @@ -116,18 +116,27 @@ func (h *piperHandler) Synthesize(ctx context.Context, req worker.SynthesizeReq) }, nil } -// resample22050To16000 converts raw 16-bit PCM from 22050 Hz to 16000 Hz -// using linear interpolation. +// piperSampleRate is the rate piper's onnx voices render at (ru_RU-irina and +// the other models this daemon has been pointed at). targetSampleRate is the +// canonical maven wire rate (audio.PCM16kMono) that every downstream +// consumer — playback, the voice wire, whisper on the way back in — expects. +const ( + piperSampleRate = 22050 + targetSampleRate = 16000 +) + +// resample22050To16000 converts raw 16-bit PCM from piperSampleRate to +// targetSampleRate using linear interpolation. func resample22050To16000(input []byte) []byte { if len(input) < 2 { return nil } nSamples := len(input) / 2 - outSamples := int(float64(nSamples) * 16000.0 / 22050.0) + outSamples := int(float64(nSamples) * float64(targetSampleRate) / float64(piperSampleRate)) output := make([]byte, outSamples*2) - ratio := 22050.0 / 16000.0 + ratio := float64(piperSampleRate) / float64(targetSampleRate) for i := 0; i < outSamples; i++ { srcPos := float64(i) * ratio