Skip to content

Conversation

@alexlivekit
Copy link
Contributor

@alexlivekit alexlivekit commented Jan 7, 2026

If we ever want a fancier version (used mostly for VAD, or Voice Activity Detection), where our noise floor is dynamically calculated (this helps indicate speech even in noisier environments), we can look at the implementation in signal-logger-adaptive.

For now, the purpose of this feature is to output whether there's any signal, voice or noise, for sanity and debugging.

@alexlivekit alexlivekit force-pushed the signal-logger branch 8 times, most recently from 2df31f9 to 0464494 Compare January 13, 2026 04:40
@alexlivekit alexlivekit marked this pull request as ready for review January 26, 2026 19:44
@alexlivekit alexlivekit requested a review from a team as a code owner January 26, 2026 19:44
// Keeps an internal state of whether we're currently transmitting signal (voice or noise), or silence.
// This implements msdk.PCM16Writer to inspect decoded packet content.
// Used to log changes betweem those states.
type SignalLogger struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider moving it to media-sdk, since it's not SIP-specific.


s.framesProcessed++
if s.framesProcessed > 10 { // Don't log any changes at first
if isSignal && isSignal != s.lastIsSignal { // silence -> signal: Immediate transition
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could potentially hit each frame, wouldn't it be too spammy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what hangoverDuration is about. It can flip to signal immediately, but to flip out of isSignal you'd need to wait at least a second of silence. Would that still be too spammy?

}

func (s *SignalLogger) WriteSample(sample msdk.PCM16Sample) error {
currentEnergy := s.MeanAbsoluteDeviation(sample)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably doesn't matter here, but energy is usually computed as a square of amplitude. Maybe rename to ampMean?

totalAbs += int64(v)
}
}
return float64(totalAbs) / float64(len(sample))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also consider calculating a median, it will be less affected by sudden spikes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would still want to use average to not filter out signal in high or low bands, which should count as signal still.

audioWriter = newMediaWriterCount(audioWriter, &p.stats.AudioInFrames, &p.stats.AudioInSamples)
}
if p.logSignalChanges {
signalLogger, err := NewSignalLogger(p.log, "input", audioWriter)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious.. why don't we return error for the setupInput path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't want to change too much, and the function currently doesn't support erroring out. Using the original audioWriter in that case doesn't actually degrade anything.

Copy link
Contributor Author

@alexlivekit alexlivekit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, other than the two nits, this is looking good imo.

Since this is gated by a feature flag, imo this is okay to land, but please test the new changes in staging before enabling for anyone else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants