@@ -1755,14 +1755,13 @@ func extractSpectralMetrics(metadata *ffmpeg.AVDictionary) spectralMetrics {
17551755// extractIntervalFrameMetrics extracts per-frame metrics for interval accumulation.
17561756// Only collects metrics that are valid per-window (aspectralstats, ebur128 windowed).
17571757// Excludes astats which provides cumulative values, not per-interval.
1758- func extractIntervalFrameMetrics (metadata * ffmpeg.AVDictionary ) intervalFrameMetrics {
1758+ func extractIntervalFrameMetrics (metadata * ffmpeg.AVDictionary , spectral spectralMetrics ) intervalFrameMetrics {
17591759 var m intervalFrameMetrics
17601760
17611761 // Peak level from astats (used for max tracking, which is valid per-interval)
17621762 m .PeakLevel , _ = getFloatMetadata (metadata , metaKeyPeakLevel )
17631763
1764- // aspectralstats metrics (valid per-window measurements)
1765- spectral := extractSpectralMetrics (metadata )
1764+ // aspectralstats metrics (valid per-window measurements, pre-extracted by caller)
17661765 m .SpectralMean = spectral .Mean
17671766 m .SpectralVariance = spectral .Variance
17681767 m .SpectralCentroid = spectral .Centroid
@@ -1795,14 +1794,14 @@ func extractIntervalFrameMetrics(metadata *ffmpeg.AVDictionary) intervalFrameMet
17951794// extractFrameMetadata extracts audio analysis metadata from a filtered frame.
17961795// Updates accumulators with spectral, astats, and ebur128 measurements.
17971796// Called from both the main processing loop and the flush loop.
1798- func extractFrameMetadata (metadata * ffmpeg.AVDictionary , acc * metadataAccumulators ) {
1797+ func extractFrameMetadata (metadata * ffmpeg.AVDictionary , acc * metadataAccumulators , spectral spectralMetrics ) {
17991798 if metadata == nil {
18001799 return
18011800 }
18021801
1803- // Extract all aspectralstats measurements (averaged across frames)
1802+ // Accumulate pre-extracted spectral metrics (averaged across frames)
18041803 // For mono audio, spectral stats are under channel .1
1805- acc .accumulateSpectral (extractSpectralMetrics ( metadata ) )
1804+ acc .accumulateSpectral (spectral )
18061805
18071806 // Extract astats measurements (cumulative, so we keep the latest)
18081807 // For mono audio, stats are under channel .1
@@ -2304,12 +2303,16 @@ func AnalyzeAudio(filename string, config *FilterChainConfig, progressCallback f
23042303 return nil , fmt .Errorf ("failed to get filtered frame: %w" , err )
23052304 }
23062305
2306+ // Extract spectral metrics once, reuse for both whole-file and interval accumulators
2307+ metadata := filteredFrame .Metadata ()
2308+ spectral := extractSpectralMetrics (metadata )
2309+
23072310 // Extract measurements from frame metadata (whole-file accumulators)
2308- extractFrameMetadata (filteredFrame . Metadata () , acc )
2311+ extractFrameMetadata (metadata , acc , spectral )
23092312
23102313 // Also accumulate into current interval for per-interval spectral data
23112314 // Filtered frames roughly correspond to input timing (just at higher sample rate)
2312- intervalAcc .add (extractIntervalFrameMetrics (filteredFrame . Metadata () ))
2315+ intervalAcc .add (extractIntervalFrameMetrics (metadata , spectral ))
23132316
23142317 ffmpeg .AVFrameUnref (filteredFrame )
23152318 }
@@ -2329,11 +2332,15 @@ func AnalyzeAudio(filename string, config *FilterChainConfig, progressCallback f
23292332 return nil , fmt .Errorf ("failed to get filtered frame: %w" , err )
23302333 }
23312334
2335+ // Extract spectral metrics once, reuse for both whole-file and interval accumulators
2336+ metadata := filteredFrame .Metadata ()
2337+ spectral := extractSpectralMetrics (metadata )
2338+
23322339 // Extract measurements from remaining frames
2333- extractFrameMetadata (filteredFrame . Metadata () , acc )
2340+ extractFrameMetadata (metadata , acc , spectral )
23342341
23352342 // Also accumulate into current interval for per-interval spectral data
2336- intervalAcc .add (extractIntervalFrameMetrics (filteredFrame . Metadata () ))
2343+ intervalAcc .add (extractIntervalFrameMetrics (metadata , spectral ))
23372344
23382345 ffmpeg .AVFrameUnref (filteredFrame )
23392346 }
0 commit comments