feat(capability): 转码能力包(vendor 纯 Go AMR-NB 解码器 + 黄金向量逐样本对照 + 8 哨兵 + 注册面)
This commit is contained in:
1 parent
89715d1813
commit
4a2d276881
100 files changed
+11319
No files matched your search
@@ -0,0 +1,86 @@
|
||||
package transcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Registry 承载「哪些 源→目标 可用」(design/25 §1.3.2 第一层)。它是**包内**的
|
||||
// 编解码器注册表,与全局能力注册表(internal/capability/registry)是两件事:
|
||||
// 后者表达「agent 可选用的能力 + 门控策略」,前者表达「本能力认识哪几条路」。
|
||||
//
|
||||
// 新增一种格式 = 往这里多一个注册项(见 codecs.go 的 DefaultCodecs);
|
||||
// 并发安全。
|
||||
type Registry struct {
|
||||
mu sync.RWMutex
|
||||
codecs map[route]Codec
|
||||
}
|
||||
|
||||
// route 是「源→目标」这一对,作注册表的键。用结构体而非字符串拼接:拼接会让
|
||||
// 格式名里出现分隔符时产生歧义(`a->b` 与 `a-` + `>b`)。
|
||||
type route struct {
|
||||
from Format
|
||||
to Format
|
||||
}
|
||||
|
||||
// NewRegistry 返回一个空且并发安全的编解码器注册表。
|
||||
func NewRegistry() *Registry {
|
||||
return &Registry{codecs: make(map[route]Codec)}
|
||||
}
|
||||
|
||||
// Register 注册一条转换路。nil、源/目标为空、源等于目标都返回 ErrInvalidCodec;
|
||||
// 同一对重复注册返回 ErrDuplicate。
|
||||
func (r *Registry) Register(c Codec) error {
|
||||
if c == nil {
|
||||
return fmt.Errorf("transcode: register codec: %w: nil codec", ErrInvalidCodec)
|
||||
}
|
||||
from, to := c.From(), c.To()
|
||||
if from == "" || to == "" {
|
||||
return fmt.Errorf("transcode: register codec %q -> %q: %w: empty format", from, to, ErrInvalidCodec)
|
||||
}
|
||||
if from == to {
|
||||
return fmt.Errorf("transcode: register codec %q -> %q: %w: identity route", from, to, ErrInvalidCodec)
|
||||
}
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
key := route{from: from, to: to}
|
||||
if _, exists := r.codecs[key]; exists {
|
||||
return fmt.Errorf("transcode: register codec %q -> %q: %w", from, to, ErrDuplicate)
|
||||
}
|
||||
r.codecs[key] = c
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lookup 返回 from→to 这条路上的编解码器。没有这条路时 ok 为 false。
|
||||
func (r *Registry) Lookup(from, to Format) (Codec, bool) {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
c, ok := r.codecs[route{from: from, to: to}]
|
||||
return c, ok
|
||||
}
|
||||
|
||||
// Formats 返回当前注册涉及的全部格式(源与目标去重后的并集,已排序)。
|
||||
// 它是「发现」面:调用方据此知道本能力认识哪些格式名。
|
||||
func (r *Registry) Formats() []Format {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
seen := make(map[Format]struct{}, len(r.codecs)*2)
|
||||
for key := range r.codecs {
|
||||
seen[key.from] = struct{}{}
|
||||
seen[key.to] = struct{}{}
|
||||
}
|
||||
out := make([]Format, 0, len(seen))
|
||||
for f := range seen {
|
||||
out = append(out, f)
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool { return out[i] < out[j] })
|
||||
return out
|
||||
}
|
||||
|
||||
// Len 返回已注册的「源→目标」路数。供启动期自检与测试断言使用。
|
||||
func (r *Registry) Len() int {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
return len(r.codecs)
|
||||
}
|
||||
Reference in new issue
Block a user