Skip to content

Conversation

@flexiondotorg
Copy link
Contributor

Summary

Reduce CPU and memory usage in the processing pipeline by removing duplicated work
and reusing heavy-weight objects. These changes target hotspots in Pass 1 and the
loudnorm passes to improve throughput and lower peak memory allocations.

Changes

  • Reuse spectral metrics to avoid duplicate extraction (internal/processor)
  • Use binary search to find start interval for analysis to speed up region lookup
  • Avoid redundant sorts in silence and room-tone detection routines
  • Measure silence and speech regions in a single file open to reduce IO overhead
  • Reuse AVFrame across loudnorm passes to reduce per-pass allocations

Testing

  • Run just test to exercise unit tests
  • Benchmark processing a representative test file and compare runtime/memory
    against main (measure overall processing time and peak RSS)
  • Run CLI on a small sample audio file to verify no functional regressions

Related Issues

- Allocate a single filteredFrame and reuse it in:
  - measureWithLoudnorm
  - applyLoudnormAndMeasure
- Remove repeated ffmpeg.AVFrameAlloc()/AVFrameFree() calls; defer a single
  ffmpeg.AVFrameFree and use AVFrameUnref between iterations
- Reduces heap churn and CPU overhead during measurement/encoding loops,
  improving throughput and lowering memory pressure
- Add MeasureOutputRegions to run silence and speech measurements using
one
  audio reader, avoiding repeated file open/demux/decode cycles.
- Introduce measureOutputSilenceRegionFromReader and
  measureOutputSpeechRegionFromReader to allow reusing an open reader.
- Update Pass 2 and normalisation (Pass 3/4) flows to call
  MeasureOutputRegions and attach returned samples to measurements.
- Add Reader.Seek to internal/audio/reader.go and use it to rewind the
  reader between measurements when needed.
- Preserve non-fatal behaviour: measurement failures are logged as
warnings
  and do not abort processing.

Reduces I/O and decoding overhead during region measurements, improving
performance and latency for multi-pass processing without behaviour
changes.

Signed-off-by: Martin Wimpress <martin@wimpress.org>
- Add computeSilenceMedians to precompute RMS and spectral flux medians
  used by multiple silence/room-tone detection steps.
- Update estimateNoiseFloorAndThreshold and
  findSilenceCandidatesFromIntervals to accept precomputed medians.
- Precompute medians once in AnalyzeAudio and pass them into detection
  functions to eliminate repeated O(n log n) sorts and extra
allocations.
- Reduce CPU work and memory allocations for long recordings; no change
  to detection thresholds or observable behaviour.

Signed-off-by: Martin Wimpress <martin@wimpress.org>
- Replace linear scan with sort.Search for O(log n) lookup when locating
  the first interval at or after the requested start time.
- Add clarifying comment that intervals are already sorted by timestamp
from
  the collection loop in AnalyzeAudio.
- Adjust out-of-range check to return nil when startIdx >=
len(intervals).

Reduces CPU work in analyzer for large interval lists without changing
behaviour.

Signed-off-by: Martin Wimpress <martin@wimpress.org>
- Extract spectral metrics once per filtered frame and reuse for
accumulators
- Add spectral parameter to extractIntervalFrameMetrics and
extractFrameMetadata
- Replace repeated extractSpectralMetrics calls with single extraction
per frame
- No functional change; reduces CPU work and allocations during analysis

Signed-off-by: Martin Wimpress <martin@wimpress.org>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 4 files

Confidence score: 3/5

  • Potential panic in internal/processor/analyzer.go if AnalyzeAudio calls computeSilenceMedians with an empty interval slice; this is a user-visible crash risk on certain inputs.
  • Score reflects a concrete runtime failure risk (severity 6/10) despite being a single issue.
  • Pay close attention to internal/processor/analyzer.go - add guarding for empty interval slices before computeSilenceMedians.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="internal/processor/analyzer.go">

<violation number="1" location="internal/processor/analyzer.go:2371">
P2: Guard against empty interval slices before calling computeSilenceMedians; otherwise AnalyzeAudio can panic on inputs that yield zero interval samples.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

- Return zero-value silenceMedians when searchIntervals is empty
- Prevent index errors in computeSilenceMedians and callers that assume
  a non-empty result

Signed-off-by: Martin Wimpress <martin@wimpress.org>
@flexiondotorg flexiondotorg merged commit fa4c51a into main Feb 6, 2026
5 checks passed
@flexiondotorg flexiondotorg deleted the perf branch February 6, 2026 19:07
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.

1 participant