diff options
| author | Carl Hetherington <cth@carlh.net> | 2018-03-26 22:58:01 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2018-03-26 22:58:01 +0100 |
| commit | 37c28f4c76df89bc84d773beda1bb90be1cedd1a (patch) | |
| tree | 6346c20f1b47bcac9f8c383f8bee41ca56a26de1 | |
| parent | f0192490565c72aa9838f40cbab56c4c0c60e522 (diff) | |
Bump audio analysis file version and cache drawn points in the audio plot.
| -rw-r--r-- | src/lib/audio_analysis.cc | 15 | ||||
| -rw-r--r-- | src/lib/audio_analysis.h | 8 | ||||
| -rw-r--r-- | src/wx/audio_plot.cc | 99 | ||||
| -rw-r--r-- | src/wx/audio_plot.h | 17 |
4 files changed, 86 insertions, 53 deletions
diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc index b58a3127d..78e5741e5 100644 --- a/src/lib/audio_analysis.cc +++ b/src/lib/audio_analysis.cc @@ -47,7 +47,7 @@ using boost::optional; using boost::dynamic_pointer_cast; using dcp::raw_convert; -int const AudioAnalysis::_current_state_version = 2; +int const AudioAnalysis::_current_state_version = 3; AudioAnalysis::AudioAnalysis (int channels) { @@ -90,8 +90,8 @@ AudioAnalysis::AudioAnalysis (boost::filesystem::path filename) _loudness_range = f.optional_number_child<float> ("LoudnessRange"); _analysis_gain = f.optional_number_child<double> ("AnalysisGain"); - _samples_per_point = f.optional_number_child<int64_t> ("SamplesPerPoint"); - _sample_rate = f.optional_number_child<int64_t> ("SampleRate"); + _samples_per_point = f.number_child<int64_t> ("SamplesPerPoint"); + _sample_rate = f.number_child<int64_t> ("SampleRate"); } void @@ -158,13 +158,8 @@ AudioAnalysis::write (boost::filesystem::path filename) root->add_child("AnalysisGain")->add_child_text (raw_convert<string> (_analysis_gain.get ())); } - if (_samples_per_point) { - root->add_child("SamplesPerPoint")->add_child_text (raw_convert<string> (_samples_per_point.get())); - } - - if (_sample_rate) { - root->add_child("SampleRate")->add_child_text (raw_convert<string> (_sample_rate.get())); - } + root->add_child("SamplesPerPoint")->add_child_text (raw_convert<string> (_samples_per_point)); + root->add_child("SampleRate")->add_child_text (raw_convert<string> (_sample_rate)); doc->write_to_file_formatted (filename.string ()); } diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h index 0a5e6194d..e5ee24d49 100644 --- a/src/lib/audio_analysis.h +++ b/src/lib/audio_analysis.h @@ -100,7 +100,7 @@ public: _analysis_gain = gain; } - boost::optional<int64_t> samples_per_point () const { + int64_t samples_per_point () const { return _samples_per_point; } @@ -108,7 +108,7 @@ public: _samples_per_point = spp; } - boost::optional<int> sample_rate () const { + int sample_rate () const { return _sample_rate; } @@ -131,8 +131,8 @@ private: * happened. */ boost::optional<double> _analysis_gain; - boost::optional<int64_t> _samples_per_point; - boost::optional<int> _sample_rate; + int64_t _samples_per_point; + int _sample_rate; static int const _current_state_version; }; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 493d99f5e..19e7bdac8 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -169,52 +169,45 @@ AudioPlot::paint () gc->SetPen (wxPen (wxColour (200, 200, 200))); gc->StrokePath (h_grid); - if (_analysis->samples_per_point() && _analysis->sample_rate()) { + /* Draw an x axis with marks */ - /* Draw an x axis with marks */ + wxGraphicsPath v_grid = gc->CreatePath (); - wxGraphicsPath v_grid = gc->CreatePath (); + DCPOMATIC_ASSERT (_analysis->samples_per_point() != 0.0); + double const pps = _analysis->sample_rate() * metrics.x_scale / _analysis->samples_per_point(); - DCPOMATIC_ASSERT (_analysis->samples_per_point().get() != 0.0); - double const pps = _analysis->sample_rate().get() * metrics.x_scale / _analysis->samples_per_point().get(); + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID)); - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID)); + double const mark_interval = calculate_mark_interval (rint (128 / pps)); - double const mark_interval = calculate_mark_interval (rint (128 / pps)); + DCPTime t = DCPTime::from_seconds (mark_interval); + while ((t.seconds() * pps) < data_width) { + double tc = t.seconds (); + int const h = tc / 3600; + tc -= h * 3600; + int const m = tc / 60; + tc -= m * 60; + int const s = tc; - DCPTime t = DCPTime::from_seconds (mark_interval); - while ((t.seconds() * pps) < data_width) { - double tc = t.seconds (); - int const h = tc / 3600; - tc -= h * 3600; - int const m = tc / 60; - tc -= m * 60; - int const s = tc; + wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s); + wxDouble str_width; + wxDouble str_height; + wxDouble str_descent; + wxDouble str_leading; + gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading); - wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s); - wxDouble str_width; - wxDouble str_height; - wxDouble str_descent; - wxDouble str_leading; - gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading); + int const tx = llrintf (metrics.db_label_width + t.seconds() * pps); + gc->DrawText (str, tx - str_width / 2, metrics.height - metrics.y_origin + db_label_height); - int const tx = llrintf (metrics.db_label_width + t.seconds() * pps); - gc->DrawText (str, tx - str_width / 2, metrics.height - metrics.y_origin + db_label_height); + v_grid.MoveToPoint (tx, metrics.height - metrics.y_origin + 4); + v_grid.AddLineToPoint (tx, metrics.y_origin); - v_grid.MoveToPoint (tx, metrics.height - metrics.y_origin + 4); - v_grid.AddLineToPoint (tx, metrics.y_origin); - - t += DCPTime::from_seconds (mark_interval); - } - - gc->SetPen (wxPen (wxColour (200, 200, 200))); - gc->StrokePath (v_grid); - - } else { - /* This is an old analysis without samples_per_point information */ - gc->DrawText (_("Time"), data_width, metrics.height - metrics.y_origin + db_label_height / 2); + t += DCPTime::from_seconds (mark_interval); } + gc->SetPen (wxPen (wxColour (200, 200, 200))); + gc->StrokePath (v_grid); + if (_type_visible[AudioPoint::PEAK]) { for (int c = 0; c < MAX_DCP_AUDIO_CHANNELS; ++c) { wxGraphicsPath p = gc->CreatePath (); @@ -266,7 +259,7 @@ AudioPlot::plot_peak (wxGraphicsPath& path, int channel, Metrics const & metrics return; } - path.MoveToPoint (metrics.db_label_width, y_for_linear (get_point(channel, 0)[AudioPoint::PEAK], metrics)); + _peak[channel] = PointList (); float peak = 0; int const N = _analysis->points(channel); @@ -279,7 +272,20 @@ AudioPlot::plot_peak (wxGraphicsPath& path, int channel, Metrics const & metrics peak = 0; } - path.AddLineToPoint (metrics.db_label_width + i * metrics.x_scale, y_for_linear (peak, metrics)); + _peak[channel].push_back ( + 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()), + peak + ) + ); + } + + DCPOMATIC_ASSERT (_peak.find(channel) != _peak.end()); + + path.MoveToPoint (_peak[channel][0].draw); + BOOST_FOREACH (Point const & i, _peak[channel]) { + path.AddLineToPoint (i.draw); } } @@ -290,7 +296,7 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel, Metrics const & metrics) return; } - path.MoveToPoint (metrics.db_label_width, y_for_linear (get_point(channel, 0)[AudioPoint::RMS], metrics)); + _rms[channel] = PointList(); list<float> smoothing; @@ -335,7 +341,20 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel, Metrics const & metrics) p = sqrt (p / smoothing.size ()); } - path.AddLineToPoint (metrics.db_label_width + i * metrics.x_scale, y_for_linear (p, metrics)); + _rms[channel].push_back ( + 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()), + p + ) + ); + } + + DCPOMATIC_ASSERT (_rms.find(channel) != _rms.end()); + + path.MoveToPoint (_rms[channel][0].draw); + BOOST_FOREACH (Point const & i, _rms[channel]) { + path.AddLineToPoint (i.draw); } } @@ -343,6 +362,8 @@ void AudioPlot::set_smoothing (int s) { _smoothing = s; + _rms.clear (); + _peak.clear (); Refresh (); } diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index 49f7e4ab3..203d7af8b 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -57,5 +57,22 @@ private: wxString _message; float _gain_correction; + struct Point { + Point (wxPoint draw_, DCPTime time_, float db_) + : draw(draw_) + , time(time_) + , db(db_) + {} + + wxPoint draw; + DCPTime time; + float db; + }; + + typedef std::vector<Point> PointList; + + mutable std::map<int, PointList> _peak; + mutable std::map<int, PointList> _rms; + static const int _minimum; }; |
