Documentation
¶
Overview ¶
Package controller drives a voice-activity detector and reports what it hears. It owns the detection state, the resampling the detector needs, and the watch for audio that stops arriving, and it reports speech starting, continuing and stopping through handlers the caller supplies.
It is separate from the pipeline processor that usually hosts it (see processor/vadproc) so that anything else needing the same detection can drive it too: a speech-to-speech service running its own detection alongside the provider's, say. It sits beside the detector rather than inside a processor for that reason.
It is its own package rather than part of audio/vad because it works in frames, and the frames package refers to vad.Params.
Index ¶
- Constants
- type Config
- type Controller
- func (c *Controller) BroadcastFrame(ctx context.Context, build func() frames.Frame)
- func (c *Controller) Cleanup()
- func (c *Controller) Params() vad.Params
- func (c *Controller) ProcessFrame(ctx context.Context, f frames.Frame) error
- func (c *Controller) PushFrame(ctx context.Context, f frames.Frame, dir processor.Direction)
- func (c *Controller) ReportParams(ctx context.Context)
- func (c *Controller) Setup(s processor.Setup) error
- func (c *Controller) Start(ctx context.Context)
- func (c *Controller) Stop()
- type Handlers
Constants ¶
const DefaultAudioIdleTimeout = time.Second
DefaultAudioIdleTimeout is how long the audio can stop arriving mid-speech before the user is taken to have stopped.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// AudioIdleTimeout is how long to wait, with the user speaking and no audio
// arriving at all, before taking the speech to have stopped. It covers the
// audio going away mid-utterance, a muted microphone being the usual case:
// the detector never sees the silence that would have ended the speech, so
// without this the user is left speaking for good.
//
// Leave it nil for DefaultAudioIdleTimeout. A zero duration turns the watch
// off, so it is a pointer rather than a plain value: the two have to be told
// apart, and a struct field cannot say which of them it was left as.
AudioIdleTimeout *time.Duration
}
Config configures a Controller.
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
Controller drives a detector over incoming audio and reports what it hears.
func New ¶
func New(analyzer vad.Analyzer, handlers Handlers, cfg Config) *Controller
New builds a Controller around analyzer. The analyzer is required.
func (*Controller) BroadcastFrame ¶
func (c *Controller) BroadcastFrame(ctx context.Context, build func() frames.Frame)
BroadcastFrame sends a frame both ways through whatever hosts the controller.
func (*Controller) Cleanup ¶
func (c *Controller) Cleanup()
Cleanup stops the idle watch and releases the detector and resampler.
func (*Controller) Params ¶
func (c *Controller) Params() vad.Params
Params returns the detection parameters in force.
func (*Controller) ProcessFrame ¶
ProcessFrame drives the detector from one frame. It acts on incoming audio and on a request to change the parameters; anything else it ignores. Its owner starts and stops it around the session with Start and Stop.
func (*Controller) ReportParams ¶
func (c *Controller) ReportParams(ctx context.Context)
ReportParams broadcasts the detection parameters in force, so a processor downstream can size its own behavior to them.
func (*Controller) Setup ¶
func (c *Controller) Setup(s processor.Setup) error
Setup configures the detector for the pipeline's input rate, which is known from the moment the controller is set up.
func (*Controller) Start ¶
func (c *Controller) Start(ctx context.Context)
Start announces the parameters the detector runs with and brings up the watch for the audio going missing. Its owner calls it on the StartFrame. It pairs with Stop.
The watch runs from here rather than from Setup because it looks for audio going missing mid-turn, and there is no audio to miss until the session starts.
func (*Controller) Stop ¶
func (c *Controller) Stop()
Stop tears the idle watch down, leaving the detector alone. Its owner calls it at the end of the session: left running, the watch reports what ending looks like rather than anything real, since no audio arrives once the session is over. The detector may be shared, so releasing it waits for Cleanup.
type Handlers ¶
type Handlers struct {
// OnSpeechStarted reports that the user began speaking.
OnSpeechStarted func(ctx context.Context)
// OnSpeechStopped reports that the user stopped speaking, including when the
// audio stopped arriving rather than going quiet.
OnSpeechStopped func(ctx context.Context)
// OnSpeechActivity reports one more chunk heard as speech. It fires for every
// such chunk, the one that started the speech included.
OnSpeechActivity func(ctx context.Context)
// OnPushFrame sends a frame through whatever hosts the controller.
OnPushFrame func(ctx context.Context, f frames.Frame, dir processor.Direction)
// OnBroadcastFrame sends a frame both ways through whatever hosts the
// controller. build is called once per direction.
OnBroadcastFrame func(ctx context.Context, build func() frames.Frame)
}
Handlers receives what the controller decides. Any of them may be nil.