Skip to content

[Agent] Implement the voice-enhancement audio filter (#395) #652

Open

Description

@matteius

Problem and evidence

The per-stream "voice enhancement" option (discussion #395) is stored and passed around, but does nothing:

  • src/video/mp4_writer_utils.c:62-70: voice_enhancement_enabled, filter_graph, filter_buffersrc_ctx and filter_buffersink_ctx exist, with the comment "the actual filter chain (afftdn / highpass / lowpass ...) is deferred to a follow-up PR — for now this is a stub".
  • src/video/mp4_writer_utils.c:~305: "(currently stubbed — discussion Feature: Audio Voice Enhancement Filter for Recordings (G.711 → AAC pipeline) #395)".
  • The setting is stored in the DB (db_streams.c), exposed through the streams API (api_handlers_streams_get.c / _modify.c) and shown in web/js/components/preact/StreamsView.jsx. The help text says it "has no effect yet".
  • libavfilter isn't linked anywhere today.

Expected behavior and scope

  • Link libavfilter, using a CMake option such as ENABLE_AUDIO_FILTERS that defaults ON when found. Add it to the Dockerfile / Debian packaging deps.
  • In transcode_audio_packet(), once the decoder frame format is known, lazily build the graph: abuffer → highpass=f=100 → lowpass=f=8000 → afftdn → aformat(<encoder sample fmt/rate/layout>) → abuffersink. Tune the defaults for speech. Push decoded frames through it before encoding, and free the graph in transcoder cleanup.
  • This only applies on the path where audio is already being transcoded. Document that passthrough (copy) audio isn't filtered, or force transcode when enhancement is on, and say which.
  • If the graph fails to build, log once and continue unfiltered. Recording must never fail because of this.
  • Update the UI help text and translations (web/public/locales/en.json) so it no longer says "no effect yet".

Acceptance criteria

  • With enhancement on, recorded audio is audibly filtered. A test can check this by comparing spectral energy below 100 Hz before and after.
  • With it off, the output is byte-for-byte the same pipeline as today.
  • A build without libavfilter compiles, and the option logs that it's unavailable.
  • No leaks under ASan (sanitizer workflow).

Validation

  • Unit test feeding generated PCM (sine plus low-frequency hum) through the transcoder with enhancement on, then asserting the hum is attenuated.
  • Run the full ctest after building all targets, plus the sanitizer CI.

Constraints and rollback

  • Watch the CPU cost on embedded profiles. afftdn is moderately expensive; consider leaving it out of the embedded profile.
  • Rollback: revert, and the opt-in goes back to being a no-op.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions