2 Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <libcxml/cxml.h>
21 #include "sndfile_content.h"
22 #include "sndfile_decoder.h"
24 #include "compose.hpp"
31 using std::stringstream;
33 using boost::shared_ptr;
34 using boost::lexical_cast;
36 SndfileContent::SndfileContent (shared_ptr<const Film> f, boost::filesystem::path p)
41 , _audio_frame_rate (0)
46 SndfileContent::SndfileContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
48 , AudioContent (f, node)
49 , _audio_mapping (node->node_child ("AudioMapping"), version)
51 _audio_channels = node->number_child<int> ("AudioChannels");
52 _audio_length = node->number_child<AudioFrame> ("AudioLength");
53 _audio_frame_rate = node->number_child<int> ("AudioFrameRate");
57 SndfileContent::summary () const
59 /* Get the string() here so that the name does not have quotes around it */
60 return String::compose (_("%1 [audio]"), path_summary ());
64 SndfileContent::technical_summary () const
66 return Content::technical_summary() + " - "
67 + AudioContent::technical_summary ()
72 SndfileContent::information () const
74 if (_audio_frame_rate == 0) {
80 s << String::compose (
81 _("%1 channels, %2kHz, %3 samples"),
83 content_audio_frame_rate() / 1000.0,
91 SndfileContent::valid_file (boost::filesystem::path f)
93 /* XXX: more extensions */
94 string ext = f.extension().string();
95 transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
96 return (ext == ".wav" || ext == ".aif" || ext == ".aiff");
100 SndfileContent::examine (shared_ptr<Job> job)
102 job->set_progress_unknown ();
103 Content::examine (job);
105 shared_ptr<const Film> film = _film.lock ();
108 SndfileDecoder dec (film, shared_from_this());
111 boost::mutex::scoped_lock lm (_mutex);
112 _audio_channels = dec.audio_channels ();
113 _audio_length = dec.audio_length ();
114 _audio_frame_rate = dec.audio_frame_rate ();
117 signal_changed (AudioContentProperty::AUDIO_CHANNELS);
118 signal_changed (AudioContentProperty::AUDIO_LENGTH);
119 signal_changed (AudioContentProperty::AUDIO_FRAME_RATE);
122 boost::mutex::scoped_lock lm (_mutex);
123 /* XXX: do this in signal_changed...? */
124 _audio_mapping = AudioMapping (_audio_channels);
125 _audio_mapping.make_default ();
128 signal_changed (AudioContentProperty::AUDIO_MAPPING);
132 SndfileContent::as_xml (xmlpp::Node* node) const
134 node->add_child("Type")->add_child_text ("Sndfile");
135 Content::as_xml (node);
136 AudioContent::as_xml (node);
138 node->add_child("AudioChannels")->add_child_text (lexical_cast<string> (audio_channels ()));
139 node->add_child("AudioLength")->add_child_text (lexical_cast<string> (audio_length ()));
140 node->add_child("AudioFrameRate")->add_child_text (lexical_cast<string> (content_audio_frame_rate ()));
141 _audio_mapping.as_xml (node->add_child("AudioMapping"));
145 SndfileContent::full_length () const
147 shared_ptr<const Film> film = _film.lock ();
150 AudioFrame const len = divide_with_round (audio_length() * output_audio_frame_rate(), content_audio_frame_rate ());
152 /* XXX: this depends on whether, alongside this audio, we are running video slower or faster than
153 it should be. The calculation above works out the output audio frames assuming that we are just
154 resampling the audio: it would be incomplete if, for example, we were running this audio alongside
155 25fps video that was being run at 24fps.
158 return film->audio_frames_to_time (len);
162 SndfileContent::output_audio_frame_rate () const
164 shared_ptr<const Film> film = _film.lock ();
167 return film->audio_frame_rate ();
171 SndfileContent::set_audio_mapping (AudioMapping m)
174 boost::mutex::scoped_lock lm (_mutex);
178 signal_changed (AudioContentProperty::AUDIO_MAPPING);