+
+ DCPOMATIC_ASSERT (c < MAX_DCP_AUDIO_CHANNELS);
+
+ _plot->set_channel_visible (c, _channel_checkbox[c]->GetValue ());
+}
+
+void
+AudioDialog::content_changed (int p)
+{
+ if (p == AudioContentProperty::AUDIO_STREAMS) {
+ try_to_load_analysis ();
+ } else if (p == AudioContentProperty::AUDIO_GAIN) {
+ if (_playlist->content().size() == 1) {
+ /* We can use a short-cut to render the effect of this
+ change, rather than recalculating everything.
+ */
+ _plot->set_gain_correction (gain_correction ());
+ setup_peak_time ();
+ } else {
+ try_to_load_analysis ();
+ }
+ }
+}
+
+void
+AudioDialog::type_clicked (wxCommandEvent& ev)
+{
+ int t = 0;
+ while (t < AudioPoint::COUNT && ev.GetEventObject() != _type_checkbox[t]) {
+ ++t;
+ }
+
+ DCPOMATIC_ASSERT (t < AudioPoint::COUNT);
+
+ _plot->set_type_visible (t, _type_checkbox[t]->GetValue ());
+}
+
+void
+AudioDialog::smoothing_changed ()
+{
+ _plot->set_smoothing (_smoothing->GetValue ());
+}
+
+void
+AudioDialog::setup_peak_time ()
+{
+ if (!_analysis || !_analysis->peak ()) {
+ return;
+ }
+
+ shared_ptr<Film> film = _film.lock ();
+ if (!film) {
+ return;
+ }
+
+ float const peak_dB = 20 * log10 (_analysis->peak().get()) + gain_correction ();
+
+ _peak_time->SetLabel (
+ wxString::Format (
+ _("Peak is %.2fdB at %s"),
+ peak_dB,
+ time_to_timecode (_analysis->peak_time().get(), film->video_frame_rate ()).data ()
+ )
+ );
+
+ if (peak_dB > -3) {
+ _peak_time->SetForegroundColour (wxColour (255, 0, 0));
+ } else {
+ _peak_time->SetForegroundColour (wxColour (0, 0, 0));
+ }
+}
+
+bool
+AudioDialog::Show (bool show)
+{
+ bool const r = wxDialog::Show (show);
+ try_to_load_analysis ();
+ return r;
+}
+
+/** @return gain correction in dB required to be added to raw gain values to render
+ * the dialog correctly.
+ */
+float
+AudioDialog::gain_correction ()
+{
+ if (_playlist->content().size() == 1 && _analysis->analysis_gain ()) {
+ /* In this case we know that the analysis was of a single piece of content and
+ we know that content's gain when the analysis was run. Hence we can work out
+ what correction is now needed to make it look `right'.
+ */
+ shared_ptr<const AudioContent> ac = dynamic_pointer_cast<const AudioContent> (_playlist->content().front ());
+ DCPOMATIC_ASSERT (ac);
+ return ac->audio_gain() - _analysis->analysis_gain().get ();
+ }
+
+ return 0.0f;