Files
Cyrene_v2/internal/capability/transcode/amrnb/simd_amd64.go
T
AskaEth 4a2d276881
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
feat(capability): 转码能力包(vendor 纯 Go AMR-NB 解码器 + 黄金向量逐样本对照 + 8 哨兵 + 注册面)
2026-10-05 13:02:28 +08:00

47 lines
1.3 KiB
Go

//go:build amd64
package amrnb
import "golang.org/x/sys/cpu"
var useAVX2 = cpu.X86.HasAVX2
// firRaw computes dst[o] = sum_t x[o+t]*coef[t] (wrapping int32). On AVX2 it
// vectorises across 8 outputs per iteration; otherwise it falls back.
func firRaw(dst []int32, x []int16, coef []int16) {
if useAVX2 && len(dst) >= 8 && len(coef) <= maxFIRTaps {
var c32 [maxFIRTaps]int32
for i, c := range coef {
c32[i] = int32(c)
}
firRawAVX2(dst, x, c32[:len(coef)])
return
}
firRawGeneric(dst, x, coef)
}
// maxFIRTaps bounds the stack-resident sign-extended coefficient buffer. It
// covers the longest FIR used: the open-loop pitch correlation window, which
// spans a whole frame (L_FRAME = 160 taps).
const maxFIRTaps = 256
// firRawAVX2 is implemented in simd_amd64.s. coef32 holds sign-extended taps.
//
//go:noescape
func firRawAVX2(dst []int32, x []int16, coef32 []int32)
// firDot computes the wrapping-int32 dot product sum_i a[i]*b[i] over len(a)
// elements. On AVX2 it uses VPMADDWD across 16 int16 per iteration; otherwise it
// falls back.
func firDot(a, b []int16) int32 {
if useAVX2 && len(a) >= 16 {
return firDotAVX2(a, b)
}
return firDotGeneric(a, b)
}
// firDotAVX2 is implemented in simd_amd64.s. It reads len(a) int16 from a and b.
//
//go:noescape
func firDotAVX2(a, b []int16) int32