From bcc4e2f7dc4cd5658e199ddacb7202b00ec72cf1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 27 Feb 2020 22:26:57 +0100 Subject: [PATCH] Add and use dB/linear conversion functions. --- src/lib/audio_buffers.cc | 5 +++-- src/lib/hints.cc | 2 +- src/lib/util.cc | 15 ++++++++++++++- src/lib/util.h | 5 ++++- src/wx/audio_dialog.cc | 4 ++-- src/wx/audio_gain_dialog.cc | 11 ++++++----- src/wx/audio_mapping_view.cc | 6 +++--- src/wx/audio_panel.cc | 2 +- src/wx/audio_plot.cc | 8 ++++---- test/torture_test.cc | 4 ++-- 10 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/lib/audio_buffers.cc b/src/lib/audio_buffers.cc index cceb12672..cfe762659 100644 --- a/src/lib/audio_buffers.cc +++ b/src/lib/audio_buffers.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2017 Carl Hetherington + Copyright (C) 2012-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ +#include "util.h" #include "audio_buffers.h" #include "dcpomatic_assert.h" #include @@ -309,7 +310,7 @@ AudioBuffers::accumulate_frames (AudioBuffers const * from, int32_t frames, int3 void AudioBuffers::apply_gain (float dB) { - float const linear = pow (10, dB / 20); + float const linear = db_to_linear (dB); for (int i = 0; i < _channels; ++i) { for (int j = 0; j < _frames; ++j) { diff --git a/src/lib/hints.cc b/src/lib/hints.cc index 6cb037ed0..3edceeee3 100644 --- a/src/lib/hints.cc +++ b/src/lib/hints.cc @@ -235,7 +235,7 @@ Hints::thread () for (size_t i = 0; i < sample_peak.size(); ++i) { float const peak = max (sample_peak[i].peak, true_peak.empty() ? 0 : true_peak[i]); - float const peak_dB = 20 * log10 (peak) + an->gain_correction (film->playlist ()); + float const peak_dB = linear_to_db(peak) + an->gain_correction(film->playlist()); if (peak_dB > -3) { ch += dcp::raw_convert (short_audio_channel_name (i)) + ", "; } diff --git a/src/lib/util.cc b/src/lib/util.cc index bbb444367..e4f552c4d 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2019 Carl Hetherington + Copyright (C) 2012-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -1171,3 +1171,16 @@ write_swaroop_chain (shared_ptr chain, boost::files } #endif + +double +db_to_linear (double db) +{ + return pow(10, db / 20); +} + +double +linear_to_db (double linear) +{ + return 20 * log10(linear); +} + diff --git a/src/lib/util.h b/src/lib/util.h index c8dcb29d6..12c79ea5a 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2019 Carl Hetherington + Copyright (C) 2012-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -128,4 +128,7 @@ vector_to_list (std::vector v) return l; } +extern double db_to_linear (double db); +extern double linear_to_db (double linear); + #endif diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 9b3a93769..2f1f1c826 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -366,7 +366,7 @@ AudioDialog::setup_statistics () } pair const peak = _analysis->overall_sample_peak (); - float const peak_dB = 20 * log10 (peak.first.peak) + _analysis->gain_correction (_playlist); + float const peak_dB = linear_to_db(peak.first.peak) + _analysis->gain_correction(_playlist); _sample_peak->SetLabel ( wxString::Format ( _("Sample peak is %.2fdB at %s on %s"), @@ -384,7 +384,7 @@ AudioDialog::setup_statistics () if (_analysis->overall_true_peak()) { float const peak = _analysis->overall_true_peak().get(); - float const peak_dB = 20 * log10 (peak) + _analysis->gain_correction (_playlist); + float const peak_dB = linear_to_db(peak) + _analysis->gain_correction(_playlist); _true_peak->SetLabel (wxString::Format (_("True peak is %.2fdB"), peak_dB)); diff --git a/src/wx/audio_gain_dialog.cc b/src/wx/audio_gain_dialog.cc index 72b3f86ca..5cd936d24 100644 --- a/src/wx/audio_gain_dialog.cc +++ b/src/wx/audio_gain_dialog.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -18,10 +18,11 @@ */ -#include -#include #include "audio_gain_dialog.h" #include "wx_util.h" +#include "lib/util.h" +#include +#include AudioGainDialog::AudioGainDialog (wxWindow* parent, int c, int d, float v) : TableDialog (parent, _("Channel gain"), 3, 1, true) @@ -34,7 +35,7 @@ AudioGainDialog::AudioGainDialog (wxWindow* parent, int c, int d, float v) _gain->SetDigits (1); _gain->SetIncrement (0.1); - _gain->SetValue (20 * log10 (v)); + _gain->SetValue (linear_to_db(v)); layout (); } @@ -46,5 +47,5 @@ AudioGainDialog::value () const return 0; } - return pow (10, _gain->GetValue () / 20); + return db_to_linear (_gain->GetValue()); } diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc index 140f18d60..937dea558 100644 --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@ -308,7 +308,7 @@ AudioMappingView::paint_indicators (wxDC& dc) ) ); - float const value_dB = 20 * log10 (_map.get(y, x)); + float const value_dB = linear_to_db(_map.get(y, x)); int const range = 18; int height = 0; if (value_dB > -range) { @@ -504,7 +504,7 @@ AudioMappingView::full () void AudioMappingView::minus6dB () { - _map.set (_menu_input, _menu_output, pow (10, -6.0 / 20)); + _map.set (_menu_input, _menu_output, db_to_linear(-6)); map_values_changed (); } @@ -599,7 +599,7 @@ AudioMappingView::motion (wxMouseEvent& ev) safe_output_channel_name(channels->second) ); } else { - float const dB = 20 * log10 (gain); + float const dB = linear_to_db(gain); s = wxString::Format ( _("Audio will be passed from %s channel %s to %s channel %s with gain %.1fdB."), _from, diff --git a/src/wx/audio_panel.cc b/src/wx/audio_panel.cc index d6137ad9f..37d6f8bb6 100644 --- a/src/wx/audio_panel.cc +++ b/src/wx/audio_panel.cc @@ -381,7 +381,7 @@ AudioPanel::peak () const playlist->add (_parent->film(), sel.front()); try { shared_ptr analysis (new AudioAnalysis(_parent->film()->audio_analysis_path(playlist))); - peak_dB = 20 * log10 (analysis->overall_sample_peak().first.peak) + analysis->gain_correction(playlist); + peak_dB = linear_to_db(analysis->overall_sample_peak().first.peak) + analysis->gain_correction(playlist); } catch (...) { } diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 3da7a50ff..0b7b29923 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -267,7 +267,7 @@ AudioPlot::y_for_linear (float p, Metrics const & metrics) const p = 1e-4; } - return metrics.height - (20 * log10(p) - _minimum) * metrics.y_scale - metrics.y_origin; + return metrics.height - (linear_to_db(p) - _minimum) * metrics.y_scale - metrics.y_origin; } void @@ -294,7 +294,7 @@ AudioPlot::plot_peak (wxGraphicsPath& path, int channel, Metrics const & metrics Point ( wxPoint (metrics.db_label_width + i * metrics.x_scale, y_for_linear (peak, metrics)), DCPTime::from_frames (i * _analysis->samples_per_point(), _analysis->sample_rate()), - 20 * log10(peak) + linear_to_db(peak) ) ); } @@ -363,7 +363,7 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel, Metrics const & metrics) Point ( wxPoint (metrics.db_label_width + i * metrics.x_scale, y_for_linear (p, metrics)), DCPTime::from_frames (i * _analysis->samples_per_point(), _analysis->sample_rate()), - 20 * log10(p) + linear_to_db(p) ) ); } @@ -397,7 +397,7 @@ AudioPlot::get_point (int channel, int point) const { AudioPoint p = _analysis->get_point (channel, point); for (int i = 0; i < AudioPoint::COUNT; ++i) { - p[i] *= pow (10, _gain_correction / 20); + p[i] *= db_to_linear(_gain_correction); } return p; diff --git a/test/torture_test.cc b/test/torture_test.cc index 10d343268..8bd541ad2 100644 --- a/test/torture_test.cc +++ b/test/torture_test.cc @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE (torture_test1) staircase->set_position (film, DCPTime::from_frames (2000, film->audio_frame_rate())); staircase->set_trim_start (ContentTime::from_frames (12, 48000)); staircase->set_trim_end (ContentTime::from_frames (35, 48000)); - staircase->audio->set_gain (20 * log10(2)); + staircase->audio->set_gain (linear_to_db(6)); /* And again at an offset of 50000 samples, trimmed both start and end, with a gain of 6dB */ staircase = content_factory("test/data/staircase.wav").front (); @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE (torture_test1) staircase->set_position (film, DCPTime::from_frames(50000, film->audio_frame_rate())); staircase->set_trim_start (ContentTime::from_frames (12, 48000)); staircase->set_trim_end (ContentTime::from_frames (35, 48000)); - staircase->audio->set_gain (20 * log10(2)); + staircase->audio->set_gain (linear_to_db(6)); /* 1s of red at 5s in */ shared_ptr red = content_factory("test/data/flat_red.png").front (); -- 2.30.2