r128.integr_start();
locut.init(FILTER_HPF, 2);
+
+ // hlen=16 is pretty low quality, but we use quite a bit of CPU otherwise,
+ // and there's a limit to how important the peak meter is.
+ peak_resampler.setup(OUTPUT_FREQUENCY, OUTPUT_FREQUENCY * 4, /*num_channels=*/2, /*hlen=*/16);
}
Mixer::~Mixer()
}
}
-float find_peak(const vector<float> &samples)
+float find_peak(const float *samples, size_t num_samples)
{
float m = fabs(samples[0]);
- for (size_t i = 1; i < samples.size(); ++i) {
+ for (size_t i = 1; i < num_samples; ++i) {
m = std::max(m, fabs(samples[i]));
}
return m;
// printf("limiter=%+5.1f compressor=%+5.1f\n", 20.0*log10(limiter_att), 20.0*log10(compressor_att));
- // Find peak and R128 levels.
- peak = max<float>(peak, find_peak(samples_out));
+ // Upsample 4x to find interpolated peak.
+ peak_resampler.inp_data = samples_out.data();
+ peak_resampler.inp_count = samples_out.size() / 2;
+
+ vector<float> interpolated_samples_out;
+ interpolated_samples_out.resize(samples_out.size());
+ while (peak_resampler.inp_count > 0) { // About four iterations.
+ peak_resampler.out_data = &interpolated_samples_out[0];
+ peak_resampler.out_count = interpolated_samples_out.size() / 2;
+ peak_resampler.process();
+ size_t out_stereo_samples = interpolated_samples_out.size() / 2 - peak_resampler.out_count;
+ peak = max<float>(peak, find_peak(interpolated_samples_out.data(), out_stereo_samples * 2));
+ }
+
+ // Find R128 levels.
vector<float> left, right;
deinterleave_samples(samples_out, &left, &right);
float *ptrs[] = { left.data(), right.data() };
void Mixer::reset_meters()
{
+ peak_resampler.reset();
peak = 0.0f;
r128.reset();
r128.integr_start();
#include <movit/effect_chain.h>
#include <movit/flat_input.h>
+#include <zita-resampler/resampler.h>
#include <atomic>
#include <condition_variable>
#include <cstddef>
audio_level_callback_t audio_level_callback = nullptr;
Ebu_r128_proc r128;
- // TODO: Implement oversampled peak detection.
+ Resampler peak_resampler;
std::atomic<float> peak{0.0f};
StereoFilter locut; // Default cutoff 150 Hz, 24 dB/oct.