diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-06 23:57:46 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-06 23:57:46 +0100 |
| commit | c921cfe23b593d7c367ad76094308c5f08037374 (patch) | |
| tree | d010137615eb3817e57edaf0b0753ef924569965 /src/lib | |
| parent | 8750efb9e072cf3b42e6c3c29521c7031c0b5dfd (diff) | |
Various work on audio channel mapping.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/analyse_audio_job.cc | 4 | ||||
| -rw-r--r-- | src/lib/audio_mapping.cc | 100 | ||||
| -rw-r--r-- | src/lib/audio_mapping.h | 52 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 3 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 3 | ||||
| -rw-r--r-- | src/lib/film.cc | 16 | ||||
| -rw-r--r-- | src/lib/film.h | 12 | ||||
| -rw-r--r-- | src/lib/imagemagick_content.cc | 2 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 45 | ||||
| -rw-r--r-- | src/lib/playlist.h | 3 | ||||
| -rw-r--r-- | src/lib/sndfile_content.cc | 7 | ||||
| -rw-r--r-- | src/lib/writer.cc | 6 |
12 files changed, 165 insertions, 88 deletions
diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 5ef6515dd..50096d7c1 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -57,8 +57,8 @@ AnalyseAudioJob::run () _samples_per_point = max (int64_t (1), _film->audio_length() / _num_points); - _current.resize (_film->audio_channels ()); - _analysis.reset (new AudioAnalysis (_film->audio_channels())); + _current.resize (MAX_AUDIO_CHANNELS); + _analysis.reset (new AudioAnalysis (MAX_AUDIO_CHANNELS)); while (!player->pass()) { set_progress (float (_done) / _film->audio_length ()); diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 3fc423e10..48cc23307 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -19,85 +19,77 @@ #include "audio_mapping.h" -using std::map; -using boost::optional; - -AutomaticAudioMapping::AutomaticAudioMapping (int c) - : _source_channels (c) +using std::list; +using std::cout; +using std::make_pair; +using std::pair; +using boost::shared_ptr; + +void +AudioMapping::add (Channel c, libdcp::Channel d) { - + _content_to_dcp.push_back (make_pair (c, d)); } -optional<libdcp::Channel> -AutomaticAudioMapping::source_to_dcp (int c) const +/* XXX: this is grotty */ +int +AudioMapping::dcp_channels () const { - if (c >= _source_channels) { - return optional<libdcp::Channel> (); + for (list<pair<Channel, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (((int) i->second) > 2) { + return 6; + } } - if (_source_channels == 1) { - /* mono sources to centre */ - return libdcp::CENTRE; - } - - return static_cast<libdcp::Channel> (c); + return 2; } -optional<int> -AutomaticAudioMapping::dcp_to_source (libdcp::Channel c) const +list<AudioMapping::Channel> +AudioMapping::dcp_to_content (libdcp::Channel d) const { - if (_source_channels == 1) { - if (c == libdcp::CENTRE) { - return 0; - } else { - return optional<int> (); + list<AudioMapping::Channel> c; + for (list<pair<Channel, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (i->second == d) { + c.push_back (i->first); } } - if (static_cast<int> (c) >= _source_channels) { - return optional<int> (); - } - - return static_cast<int> (c); + return c; } -int -AutomaticAudioMapping::dcp_channels () const +list<AudioMapping::Channel> +AudioMapping::content_channels () const { - if (_source_channels == 1) { - /* The source is mono, so to put the mono channel into - the centre we need to generate a 5.1 soundtrack. - */ - return 6; + list<AudioMapping::Channel> c; + for (list<pair<Channel, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (find (c.begin(), c.end(), i->first) == c.end ()) { + c.push_back (i->first); + } } - return _source_channels; + return c; } -optional<int> -ConfiguredAudioMapping::dcp_to_source (libdcp::Channel c) const +list<libdcp::Channel> +AudioMapping::content_to_dcp (Channel c) const { - map<int, libdcp::Channel>::const_iterator i = _source_to_dcp.begin (); - while (i != _source_to_dcp.end() && i->second != c) { - ++i; - } - - if (i == _source_to_dcp.end ()) { - return boost::none; + list<libdcp::Channel> d; + for (list<pair<Channel, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (i->first == c) { + d.push_back (i->second); + } } - return i->first; + return d; } -optional<libdcp::Channel> -ConfiguredAudioMapping::source_to_dcp (int c) const +bool +operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b) { - map<int, libdcp::Channel>::const_iterator i = _source_to_dcp.find (c); - if (i == _source_to_dcp.end ()) { - return boost::none; - } - - return i->second; + shared_ptr<const AudioContent> sa = a.content.lock (); + shared_ptr<const AudioContent> sb = b.content.lock (); + return sa == sb && a.index == b.index; } + diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index 8804bde06..10ac20b48 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -17,37 +17,43 @@ */ -#include <vector> -#include <map> -#include <boost/optional.hpp> +#ifndef DVDOMATIC_AUDIO_MAPPING_H +#define DVDOMATIC_AUDIO_MAPPING_H + +#include <list> +#include <string> #include <libdcp/types.h> +#include <boost/shared_ptr.hpp> +#include "audio_content.h" class AudioMapping { public: - virtual boost::optional<libdcp::Channel> source_to_dcp (int c) const = 0; - virtual boost::optional<int> dcp_to_source (libdcp::Channel c) const = 0; -}; - -class AutomaticAudioMapping : public AudioMapping -{ -public: - AutomaticAudioMapping (int); + struct Channel { + Channel (boost::weak_ptr<const AudioContent> c, int i) + : content (c) + , index (i) + {} + + boost::weak_ptr<const AudioContent> content; + int index; + }; + + void add (Channel, libdcp::Channel); - boost::optional<libdcp::Channel> source_to_dcp (int c) const; - boost::optional<int> dcp_to_source (libdcp::Channel c) const; int dcp_channels () const; - -private: - int _source_channels; -}; + std::list<Channel> dcp_to_content (libdcp::Channel) const; + std::list<std::pair<Channel, libdcp::Channel> > content_to_dcp () const { + return _content_to_dcp; + } -class ConfiguredAudioMapping : public AudioMapping -{ -public: - boost::optional<libdcp::Channel> source_to_dcp (int c) const; - boost::optional<int> dcp_to_source (libdcp::Channel c) const; + std::list<Channel> content_channels () const; + std::list<libdcp::Channel> content_to_dcp (Channel) const; private: - std::map<int, libdcp::Channel> _source_to_dcp; + std::list<std::pair<Channel, libdcp::Channel> > _content_to_dcp; }; + +extern bool operator== (AudioMapping::Channel const &, AudioMapping::Channel const &); + +#endif diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index a0b88e33e..0542587a0 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -427,6 +427,8 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr<const AudioBuffers> data) { +#if 0 + XXX AutomaticAudioMapping m (_film->audio_channels ()); if (m.dcp_channels() != _film->audio_channels()) { @@ -444,6 +446,7 @@ Encoder::write_audio (shared_ptr<const AudioBuffers> data) data = b; } +#endif _writer->write (data); } diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index cc95105e5..d36abe2c3 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -152,12 +152,13 @@ FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool quick) signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); signal_changed (FFmpegContentProperty::AUDIO_STREAMS); signal_changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (AudioContentProperty::AUDIO_CHANNELS); } string FFmpegContent::summary () const { - return String::compose (_("Movie: %1"), file().filename ()); + return String::compose (_("Movie: %1"), file().filename().string()); } string diff --git a/src/lib/film.cc b/src/lib/film.cc index 69d2a28e2..b1f740ec2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -960,6 +960,7 @@ Film::signal_changed (Property p) case Film::CONTENT: _playlist->setup (content ()); set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); + set_audio_mapping (_playlist->default_audio_mapping ()); break; default: break; @@ -1236,11 +1237,24 @@ Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) } void +Film::set_audio_mapping (AudioMapping m) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _audio_mapping = m; + } + + signal_changed (AUDIO_MAPPING); +} + +void Film::content_changed (boost::weak_ptr<Content> c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); - } + } else if (p == AudioContentProperty::AUDIO_CHANNELS) { + set_audio_mapping (_playlist->default_audio_mapping ()); + } if (ui_signaller) { ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); diff --git a/src/lib/film.h b/src/lib/film.h index 9c5f561e6..532d32bdc 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -36,6 +36,7 @@ #include "dci_metadata.h" #include "types.h" #include "ffmpeg_content.h" +#include "audio_mapping.h" class DCPContentType; class Format; @@ -146,7 +147,8 @@ public: COLOUR_LUT, J2K_BANDWIDTH, DCI_METADATA, - DCP_FRAME_RATE + DCP_FRAME_RATE, + AUDIO_MAPPING }; @@ -262,6 +264,11 @@ public: return _dcp_frame_rate; } + AudioMapping audio_mapping () const { + boost::mutex::scoped_lock lm (_state_mutex); + return _audio_mapping; + } + /* SET */ void set_directory (std::string); @@ -294,6 +301,7 @@ public: void set_dci_metadata (DCIMetadata); void set_dcp_frame_rate (int); void set_dci_date_today (); + void set_audio_mapping (AudioMapping); /** Emitted when some property has of the Film has changed */ mutable boost::signals2::signal<void (Property)> Changed; @@ -314,6 +322,7 @@ private: void read_metadata (); void content_changed (boost::weak_ptr<Content>, int); boost::shared_ptr<FFmpegContent> ffmpeg () const; + void setup_default_audio_mapping (); /** Log to write to */ boost::shared_ptr<Log> _log; @@ -378,6 +387,7 @@ private: int _dcp_frame_rate; /** The date that we should use in a DCI name */ boost::gregorian::date _dci_date; + AudioMapping _audio_mapping; /** true if our state has changed since we last saved it */ mutable bool _dirty; diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 912c180a8..59fde40bb 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -45,7 +45,7 @@ ImageMagickContent::ImageMagickContent (shared_ptr<const cxml::Node> node) string ImageMagickContent::summary () const { - return String::compose (_("Image: %1"), file().filename ()); + return String::compose (_("Image: %1"), file().filename().string()); } bool diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index e0220ef6f..3f7905fa9 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -30,6 +30,7 @@ using std::list; using std::cout; using std::vector; +using std::min; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -224,3 +225,47 @@ Playlist::content_changed (weak_ptr<Content> c, int p) { ContentChanged (c, p); } + +AudioMapping +Playlist::default_audio_mapping () const +{ + AudioMapping m; + + switch (_audio_from) { + case AUDIO_NONE: + break; + case AUDIO_FFMPEG: + if (_ffmpeg->audio_channels() == 1) { + /* Map mono sources to centre */ + m.add (AudioMapping::Channel (_ffmpeg, 0), libdcp::CENTRE); + } else { + int const N = min (_ffmpeg->audio_channels (), MAX_AUDIO_CHANNELS); + /* Otherwise just start with a 1:1 mapping */ + for (int i = 0; i < N; ++i) { + m.add (AudioMapping::Channel (_ffmpeg, i), (libdcp::Channel) i); + } + } + break; + + case AUDIO_SNDFILE: + { + int n = 0; + for (list<shared_ptr<const SndfileContent> >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + cout << "sndfile " << (*i)->audio_channels() << "\n"; + for (int j = 0; j < (*i)->audio_channels(); ++j) { + m.add (AudioMapping::Channel (*i, j), (libdcp::Channel) n); + ++n; + if (n >= MAX_AUDIO_CHANNELS) { + break; + } + } + if (n >= MAX_AUDIO_CHANNELS) { + break; + } + } + break; + } + } + + return m; +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 1a24a0227..1d189cb07 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -25,6 +25,7 @@ #include "video_sink.h" #include "audio_sink.h" #include "ffmpeg_content.h" +#include "audio_mapping.h" class Content; class FFmpegContent; @@ -53,6 +54,8 @@ public: libdcp::Size video_size () const; ContentVideoFrame video_length () const; + AudioMapping default_audio_mapping () const; + enum VideoFrom { VIDEO_NONE, VIDEO_FFMPEG, diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index ee4f21eef..539b0dfb5 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -27,12 +27,16 @@ using std::string; using std::stringstream; +using std::cout; using boost::shared_ptr; using boost::lexical_cast; SndfileContent::SndfileContent (boost::filesystem::path f) : Content (f) , AudioContent (f) + , _audio_channels (0) + , _audio_length (0) + , _audio_frame_rate (0) { } @@ -49,7 +53,7 @@ SndfileContent::SndfileContent (shared_ptr<const cxml::Node> node) string SndfileContent::summary () const { - return String::compose (_("Sound file: %1"), file().filename ()); + return String::compose (_("Sound file: %1"), file().filename().string()); } string @@ -115,3 +119,4 @@ SndfileContent::as_xml (xmlpp::Node* node) const node->add_child("AudioLength")->add_child_text (lexical_cast<string> (_audio_length)); node->add_child("AudioFrameRate")->add_child_text (lexical_cast<string> (_audio_frame_rate)); } + diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 6df1a1f21..7258826ba 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -78,15 +78,13 @@ Writer::Writer (shared_ptr<Film> f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - AutomaticAudioMapping m (_film->audio_channels ()); - - if (m.dcp_channels() > 0) { + if (_film->audio_channels() > 0) { _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), N_("audio.mxf"), _film->dcp_frame_rate (), - m.dcp_channels (), + _film->audio_mapping().dcp_channels (), dcp_audio_sample_rate (_film->audio_frame_rate()) ) ); |
