+ auto doc = make_shared<xmlpp::Document>();
+ xmlpp::Element* root = doc->create_root_node ("AudioAnalysis");
+
+ root->add_child("Version")->add_child_text(raw_convert<string>(_current_state_version));
+
+ for (auto& i: _data) {
+ auto channel = root->add_child ("Channel");
+ for (auto& j: i) {
+ j.as_xml (channel->add_child ("Point"));
+ }
+ }
+
+ for (size_t i = 0; i < _sample_peak.size(); ++i) {
+ auto n = root->add_child("SamplePeak");
+ n->add_child_text (raw_convert<string> (_sample_peak[i].peak));
+ n->set_attribute ("Time", raw_convert<string> (_sample_peak[i].time.get()));
+ }
+
+ for (auto i: _true_peak) {
+ root->add_child("TruePeak")->add_child_text (raw_convert<string> (i));
+ }
+
+ if (_integrated_loudness) {
+ root->add_child("IntegratedLoudness")->add_child_text (raw_convert<string> (_integrated_loudness.get ()));
+ }
+
+ if (_loudness_range) {
+ root->add_child("LoudnessRange")->add_child_text (raw_convert<string> (_loudness_range.get ()));
+ }
+
+ if (_analysis_gain) {
+ root->add_child("AnalysisGain")->add_child_text (raw_convert<string> (_analysis_gain.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));
+
+ if (_leqm) {
+ root->add_child("Leqm")->add_child_text(raw_convert<string>(*_leqm));
+ }
+
+ doc->write_to_file_formatted (filename.string ());
+}
+
+
+float
+AudioAnalysis::gain_correction (shared_ptr<const Playlist> playlist)
+{
+ if (playlist->content().size() == 1 && 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'.
+ */
+ DCPOMATIC_ASSERT (playlist->content().front()->audio);
+ return playlist->content().front()->audio->gain() - analysis_gain().get();
+ }
+
+ return 0.0f;
+}