+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
AudioContent::AudioContent (shared_ptr<const cxml::Node> node)
: Content (node)
{
-
}
AudioContent::AudioContent (AudioContent const & o)
{
}
+
+void
+AudioContent::as_xml (xmlpp::Node* node) const
+{
+
+}
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
#define DCPOMATIC_AUDIO_CONTENT_H
#include "content.h"
-#include "util.h"
+#include "audio_mapping.h"
namespace cxml {
class Node;
AudioContent (boost::shared_ptr<const cxml::Node>);
AudioContent (AudioContent const &);
+ void as_xml (xmlpp::Node *) const;
+
virtual int audio_channels () const = 0;
virtual ContentAudioFrame audio_length () const = 0;
virtual int content_audio_frame_rate () const = 0;
virtual int output_audio_frame_rate (boost::shared_ptr<const Film>) const = 0;
+ virtual AudioMapping audio_mapping () const = 0;
};
#endif
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
*/
#include <boost/lexical_cast.hpp>
+#include <libxml++/libxml++.h>
#include <libcxml/cxml.h>
#include "audio_mapping.h"
using boost::lexical_cast;
using boost::dynamic_pointer_cast;
-void
-AudioMapping::add (int c, libdcp::Channel d)
+AudioMapping::AudioMapping ()
{
- _content_to_dcp.push_back (make_pair (c, d));
+
}
-/* XXX: this is grotty */
-int
-AudioMapping::dcp_channels () const
+/** Create a default AudioMapping for a given channel count.
+ * @param c Number of channels.
+ */
+AudioMapping::AudioMapping (int c)
{
- for (list<pair<int, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) {
- if (((int) i->second) >= 2) {
- return 6;
+ if (c == 1) {
+ /* Mono -> Centre */
+ add (0, libdcp::CENTRE);
+ } else {
+ /* 1:1 mapping */
+ for (int i = 0; i < c; ++i) {
+ add (i, static_cast<libdcp::Channel> (i));
}
}
+}
+
+AudioMapping::AudioMapping (shared_ptr<const cxml::Node> node)
+{
+ list<shared_ptr<cxml::Node> > const c = node->node_children ("Map");
+ for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) {
+ add ((*i)->number_child<int> ("ContentIndex"), static_cast<libdcp::Channel> ((*i)->number_child<int> ("DCP")));
+ }
+}
- return 2;
+void
+AudioMapping::add (int c, libdcp::Channel d)
+{
+ _content_to_dcp.push_back (make_pair (c, d));
}
list<int>
t->add_child ("DCP")->add_child_text (lexical_cast<string> (i->second));
}
}
-
-void
-AudioMapping::set_from_xml (shared_ptr<const cxml::Node> node)
-{
- list<shared_ptr<cxml::Node> > const c = node->node_children ("Map");
- for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) {
- add ((*i)->number_child<int> ("ContentIndex"), static_cast<libdcp::Channel> ((*i)->number_child<int> ("DCP")));
- }
-}
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
#define DCPOMATIC_AUDIO_MAPPING_H
#include <list>
-#include <string>
#include <libdcp/types.h>
#include <boost/shared_ptr.hpp>
-#include "audio_content.h"
+
+namespace xmlpp {
+ class Node;
+}
+
+namespace cxml {
+ class Node;
+}
class AudioMapping
{
public:
+ AudioMapping ();
+ AudioMapping (int);
+ AudioMapping (boost::shared_ptr<const cxml::Node>);
+
void as_xml (xmlpp::Node *) const;
- void set_from_xml (boost::shared_ptr<const cxml::Node>);
void add (int, libdcp::Channel);
- int dcp_channels () const;
std::list<int> dcp_to_content (libdcp::Channel) const;
std::list<std::pair<int, libdcp::Channel> > content_to_dcp () const {
return _content_to_dcp;
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
node->add_child("Type")->add_child_text ("FFmpeg");
Content::as_xml (node);
VideoContent::as_xml (node);
+ AudioContent::as_xml (node);
boost::mutex::scoped_lock lm (_mutex);
}
FFmpegAudioStream::FFmpegAudioStream (shared_ptr<const cxml::Node> node)
+ : mapping (node->node_child ("Mapping"))
{
name = node->string_child ("Name");
id = node->number_child<int> ("Id");
root->add_child("Id")->add_child_text (lexical_cast<string> (id));
root->add_child("FrameRate")->add_child_text (lexical_cast<string> (frame_rate));
root->add_child("Channels")->add_child_text (lexical_cast<string> (channels));
+ mapping.as_xml (root->add_child("Mapping"));
}
/** Construct a SubtitleStream from a value returned from to_string().
FrameRateConversion frc (video_frame_rate (), film->dcp_video_frame_rate ());
return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate ();
}
+
+AudioMapping
+FFmpegContent::audio_mapping () const
+{
+ if (!_audio_stream) {
+ return AudioMapping ();
+ }
+
+ return _audio_stream->mapping;
+}
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
, id (i)
, frame_rate (f)
, channels (c)
+ , mapping (c)
{}
FFmpegAudioStream (boost::shared_ptr<const cxml::Node>);
int id;
int frame_rate;
int channels;
+ AudioMapping mapping;
};
extern bool operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b);
ContentAudioFrame audio_length () const;
int content_audio_frame_rate () const;
int output_audio_frame_rate (boost::shared_ptr<const Film>) const;
+ AudioMapping audio_mapping () const;
std::vector<FFmpegSubtitleStream> subtitle_streams () const {
boost::mutex::scoped_lock lm (_mutex);
_audio_streams.push_back (
FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channels)
);
-
+
} else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
_subtitle_streams.push_back (FFmpegSubtitleStream (stream_name (s), i));
}
J2K_BANDWIDTH,
DCI_METADATA,
DCP_VIDEO_FRAME_RATE,
- AUDIO_MAPPING
};
void read_metadata ();
void playlist_changed ();
void playlist_content_changed (boost::weak_ptr<Content>, int);
- void setup_default_audio_mapping ();
std::string filename_safe_name () const;
/** Log to write to */
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
_audio_channels = node->number_child<int> ("AudioChannels");
_audio_length = node->number_child<ContentAudioFrame> ("AudioLength");
_audio_frame_rate = node->number_child<int> ("AudioFrameRate");
+ _mapping = AudioMapping (node->node_child ("Mapping"));
}
string
_audio_channels = dec.audio_channels ();
_audio_length = dec.audio_length ();
_audio_frame_rate = dec.audio_frame_rate ();
+ _mapping = AudioMapping (_audio_channels);
}
signal_changed (AudioContentProperty::AUDIO_CHANNELS);
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> (_audio_frame_rate));
+ _mapping.as_xml (node->add_child("Mapping"));
}
int
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
int output_audio_frame_rate (boost::shared_ptr<const Film>) const;
+ AudioMapping audio_mapping () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _mapping;
+ }
+
static bool valid_file (boost::filesystem::path);
private:
int _audio_channels;
ContentAudioFrame _audio_length;
int _audio_frame_rate;
+ AudioMapping _mapping;
};
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
#include <boost/signals2.hpp>
#include <wx/wx.h>
#include <wx/grid.h>
+#include "lib/audio_mapping.h"
class AudioMappingView : public wxPanel
{
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
#include "lib/ffmpeg_content.h"
#include "ffmpeg_content_dialog.h"
#include "wx_util.h"
+#include "audio_mapping_view.h"
using std::vector;
using std::string;
grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6);
grid->AddSpacer (0);
+ _audio_mapping = new AudioMappingView (this);
+ grid->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6);
+ grid->AddSpacer (0);
+
_audio_stream->Clear ();
vector<FFmpegAudioStream> a = content->audio_streams ();
for (vector<FFmpegAudioStream>::iterator i = a.begin(); i != a.end(); ++i) {
_subtitle_stream->SetSelection (wxNOT_FOUND);
}
+ _audio_mapping->set_mapping (content->audio_mapping ());
+
wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6);
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
class wxSpinCtrl;
class FFmpegContent;
+class AudioMappingView;
class FFmpegContentDialog : public wxDialog
{
wxChoice* _audio_stream;
wxStaticText* _audio_description;
wxChoice* _subtitle_stream;
+ AudioMappingView* _audio_mapping;
};
#include "audio_dialog.h"
#include "imagemagick_content_dialog.h"
#include "ffmpeg_content_dialog.h"
-#include "audio_mapping_view.h"
#include "timeline_dialog.h"
using std::string;
grid->Add (s);
}
- _audio_mapping = new AudioMappingView (_audio_panel);
- _audio_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6);
-
_audio_gain->SetRange (-60, 60);
_audio_delay->SetRange (-1000, 1000);
}
film_changed (Film::J2K_BANDWIDTH);
film_changed (Film::DCI_METADATA);
film_changed (Film::DCP_VIDEO_FRAME_RATE);
- film_changed (Film::AUDIO_MAPPING);
film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::SUBTITLE_STREAMS);
film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::SUBTITLE_STREAM);
class wxListEvent;
class Film;
class AudioDialog;
-class AudioMappingView;
class TimelineDialog;
/** @class FilmEditor
wxButton* _audio_gain_calculate_button;
wxButton* _show_audio;
wxSpinCtrl* _audio_delay;
- AudioMappingView* _audio_mapping;
wxCheckBox* _with_subtitles;
wxSpinCtrl* _subtitle_offset;
wxSpinCtrl* _subtitle_scale;
+/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
+
/*
Copyright (C) 2012 Carl Hetherington <cth@carlh.net>