+
+void
+SndfileContent::examine (shared_ptr<Job> job)
+{
+ job->set_progress_unknown ();
+ Content::examine (job);
+
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ SndfileDecoder dec (film, shared_from_this());
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _audio_channels = dec.audio_channels ();
+ _audio_length = dec.audio_length ();
+ _audio_frame_rate = dec.audio_frame_rate ();
+ }
+
+ signal_changed (AudioContentProperty::AUDIO_CHANNELS);
+ signal_changed (AudioContentProperty::AUDIO_LENGTH);
+ signal_changed (AudioContentProperty::AUDIO_FRAME_RATE);
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ /* XXX: do this in signal_changed...? */
+ _audio_mapping = AudioMapping (_audio_channels);
+ _audio_mapping.make_default ();
+ }
+
+ signal_changed (AudioContentProperty::AUDIO_MAPPING);
+}
+
+void
+SndfileContent::as_xml (xmlpp::Node* node) const
+{
+ node->add_child("Type")->add_child_text ("Sndfile");
+ Content::as_xml (node);
+ AudioContent::as_xml (node);
+
+ node->add_child("AudioChannels")->add_child_text (lexical_cast<string> (audio_channels ()));
+ node->add_child("AudioLength")->add_child_text (lexical_cast<string> (audio_length ()));
+ node->add_child("AudioFrameRate")->add_child_text (lexical_cast<string> (content_audio_frame_rate ()));
+ _audio_mapping.as_xml (node->add_child("AudioMapping"));
+}
+
+DCPTime
+SndfileContent::full_length () const
+{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ AudioFrame const len = audio_length() * output_audio_frame_rate() / content_audio_frame_rate ();
+
+ /* XXX: this depends on whether, alongside this audio, we are running video slower or faster than
+ it should be. The calculation above works out the output audio frames assuming that we are just
+ resampling the audio: it would be incomplete if, for example, we were running this audio alongside
+ 25fps video that was being run at 24fps.
+ */
+
+ return film->audio_frames_to_time (len);
+}
+
+int
+SndfileContent::output_audio_frame_rate () const
+{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ return film->audio_frame_rate ();
+}
+
+void
+SndfileContent::set_audio_mapping (AudioMapping m)
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _audio_mapping = m;
+ }
+
+ signal_changed (AudioContentProperty::AUDIO_MAPPING);
+}