summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-06-03 13:17:37 +0100
committerCarl Hetherington <cth@carlh.net>2015-06-03 13:17:37 +0100
commitfa61fc99549264810e17fcd35abffe9e8ddab5b2 (patch)
tree855ce952ed8b416bbab33cd6debbd0f2b7379597 /src/lib
parent3b67c79bf4534e72a7eceaa6e566e7b7c949e4f7 (diff)
Various work on audio mapping.
Fix everything up so that the audio mapping view in the audio panel reflects the processor (or lack of).
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_content.cc29
-rw-r--r--src/lib/audio_content.h1
-rw-r--r--src/lib/audio_mapping.cc109
-rw-r--r--src/lib/audio_mapping.h36
-rw-r--r--src/lib/audio_processor.h26
-rw-r--r--src/lib/audio_stream.cc5
-rw-r--r--src/lib/ffmpeg_content.cc2
-rw-r--r--src/lib/film.cc60
-rw-r--r--src/lib/film.h4
-rw-r--r--src/lib/mid_side_decoder.cc30
-rw-r--r--src/lib/mid_side_decoder.h8
-rw-r--r--src/lib/player.cc6
-rw-r--r--src/lib/single_stream_audio_content.cc5
-rw-r--r--src/lib/upmixer_a.cc26
-rw-r--r--src/lib/upmixer_a.h4
15 files changed, 243 insertions, 108 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index 3ea31f673..b6749d20b 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -171,10 +171,10 @@ AudioContent::set_audio_mapping (AudioMapping mapping)
{
int c = 0;
BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
- AudioMapping stream_mapping (i->channels ());
+ AudioMapping stream_mapping (i->channels (), MAX_DCP_AUDIO_CHANNELS);
for (int j = 0; j < i->channels(); ++j) {
for (int k = 0; k < MAX_DCP_AUDIO_CHANNELS; ++k) {
- stream_mapping.set (j, static_cast<dcp::Channel> (k), mapping.get (c, static_cast<dcp::Channel> (k)));
+ stream_mapping.set (j, k, mapping.get (c, k));
}
++c;
}
@@ -192,16 +192,15 @@ AudioContent::audio_mapping () const
channels += i->channels ();
}
- AudioMapping merged (channels);
+ AudioMapping merged (channels, MAX_DCP_AUDIO_CHANNELS);
int c = 0;
int s = 0;
BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
AudioMapping mapping = i->mapping ();
- for (int j = 0; j < mapping.content_channels(); ++j) {
- merged.set_name (c, String::compose ("%1:%2", s + 1, j + 1));
+ for (int j = 0; j < mapping.input_channels(); ++j) {
for (int k = 0; k < MAX_DCP_AUDIO_CHANNELS; ++k) {
- merged.set (c, static_cast<dcp::Channel> (k), mapping.get (j, static_cast<dcp::Channel> (k)));
+ merged.set (c, k, mapping.get (j, k));
}
++c;
}
@@ -289,6 +288,7 @@ AudioContent::processing_description () const
return "";
}
+/** @return true if any stream in this content has a sampling rate of more than 48kHz */
bool
AudioContent::has_rate_above_48k () const
{
@@ -300,3 +300,20 @@ AudioContent::has_rate_above_48k () const
return false;
}
+
+/** @return User-visible names of each of our audio channels */
+vector<string>
+AudioContent::audio_channel_names () const
+{
+ vector<string> n;
+
+ int t = 1;
+ BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+ for (int j = 0; j < i->channels(); ++j) {
+ n.push_back (String::compose ("%1:%2", t, j + 1));
+ }
+ ++t;
+ }
+
+ return n;
+}
diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h
index 79dba9fda..63ce3d0fa 100644
--- a/src/lib/audio_content.h
+++ b/src/lib/audio_content.h
@@ -65,6 +65,7 @@ public:
boost::filesystem::path audio_analysis_path () const;
int resampled_audio_frame_rate () const;
bool has_rate_above_48k () const;
+ std::vector<std::string> audio_channel_names () const;
boost::signals2::connection analyse_audio (boost::function<void()>);
diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc
index 65eb5fc96..fc3909a8a 100644
--- a/src/lib/audio_mapping.cc
+++ b/src/lib/audio_mapping.cc
@@ -35,63 +35,52 @@ using boost::shared_ptr;
using boost::dynamic_pointer_cast;
AudioMapping::AudioMapping ()
- : _content_channels (0)
+ : _input_channels (0)
+ , _output_channels (0)
{
}
-/** Create an empty AudioMapping for a given channel count.
- * @param channels Number of channels.
+/** Create an empty AudioMapping.
+ * @param input_channels Number of input channels.
+ * @param output_channels Number of output channels.
*/
-AudioMapping::AudioMapping (int channels)
+AudioMapping::AudioMapping (int input_channels, int output_channels)
{
- setup (channels);
+ setup (input_channels, output_channels);
}
void
-AudioMapping::setup (int c)
+AudioMapping::setup (int input_channels, int output_channels)
{
- _content_channels = c;
+ _input_channels = input_channels;
+ _output_channels = output_channels;
- _gain.resize (_content_channels);
- for (int i = 0; i < _content_channels; ++i) {
- _gain[i].resize (MAX_DCP_AUDIO_CHANNELS);
+ _gain.resize (_input_channels);
+ for (int i = 0; i < _input_channels; ++i) {
+ _gain[i].resize (_output_channels);
}
- _name.resize (_content_channels);
-
make_zero ();
}
void
AudioMapping::make_zero ()
{
- for (int i = 0; i < _content_channels; ++i) {
- for (int j = 0; j < MAX_DCP_AUDIO_CHANNELS; ++j) {
+ for (int i = 0; i < _input_channels; ++i) {
+ for (int j = 0; j < _output_channels; ++j) {
_gain[i][j] = 0;
}
}
}
-void
-AudioMapping::make_default ()
+AudioMapping::AudioMapping (cxml::ConstNodePtr node, int state_version)
{
- make_zero ();
-
- if (_content_channels == 1) {
- /* Mono -> Centre */
- set (0, dcp::CENTRE, 1);
+ if (state_version < 32) {
+ setup (node->number_child<int> ("ContentChannels"), MAX_DCP_AUDIO_CHANNELS);
} else {
- /* 1:1 mapping */
- for (int i = 0; i < min (_content_channels, MAX_DCP_AUDIO_CHANNELS); ++i) {
- set (i, static_cast<dcp::Channel> (i), 1);
- }
+ setup (node->number_child<int> ("InputChannels"), node->number_child<int> ("OutputChannels"));
}
-}
-
-AudioMapping::AudioMapping (cxml::ConstNodePtr node, int state_version)
-{
- setup (node->number_child<int> ("ContentChannels"));
if (state_version <= 5) {
/* Old-style: on/off mapping */
@@ -102,38 +91,47 @@ AudioMapping::AudioMapping (cxml::ConstNodePtr node, int state_version)
} else {
list<cxml::NodePtr> const c = node->node_children ("Gain");
for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
- set (
- (*i)->number_attribute<int> ("Content"),
- static_cast<dcp::Channel> ((*i)->number_attribute<int> ("DCP")),
- raw_convert<float> ((*i)->content ())
- );
+ if (state_version < 32) {
+ set (
+ (*i)->number_attribute<int> ("Content"),
+ static_cast<dcp::Channel> ((*i)->number_attribute<int> ("DCP")),
+ raw_convert<float> ((*i)->content ())
+ );
+ } else {
+ set (
+ (*i)->number_attribute<int> ("Input"),
+ (*i)->number_attribute<int> ("Output"),
+ raw_convert<float> ((*i)->content ())
+ );
+ }
}
}
}
void
-AudioMapping::set (int c, dcp::Channel d, float g)
+AudioMapping::set (int input_channel, int output_channel, float g)
{
- _gain[c][d] = g;
+ _gain[input_channel][output_channel] = g;
}
float
-AudioMapping::get (int c, dcp::Channel d) const
+AudioMapping::get (int input_channel, int output_channel) const
{
- return _gain[c][d];
+ return _gain[input_channel][output_channel];
}
void
AudioMapping::as_xml (xmlpp::Node* node) const
{
- node->add_child ("ContentChannels")->add_child_text (raw_convert<string> (_content_channels));
+ node->add_child ("InputChannels")->add_child_text (raw_convert<string> (_input_channels));
+ node->add_child ("OutputChannels")->add_child_text (raw_convert<string> (_output_channels));
- for (int c = 0; c < _content_channels; ++c) {
- for (int d = 0; d < MAX_DCP_AUDIO_CHANNELS; ++d) {
+ for (int c = 0; c < _input_channels; ++c) {
+ for (int d = 0; d < _output_channels; ++d) {
xmlpp::Element* t = node->add_child ("Gain");
- t->set_attribute ("Content", raw_convert<string> (c));
- t->set_attribute ("DCP", raw_convert<string> (d));
- t->add_child_text (raw_convert<string> (get (c, static_cast<dcp::Channel> (d))));
+ t->set_attribute ("Input", raw_convert<string> (c));
+ t->set_attribute ("Output", raw_convert<string> (d));
+ t->add_child_text (raw_convert<string> (get (c, d)));
}
}
}
@@ -145,9 +143,10 @@ string
AudioMapping::digest () const
{
MD5Digester digester;
- digester.add (_content_channels);
- for (int i = 0; i < _content_channels; ++i) {
- for (int j = 0; j < MAX_DCP_AUDIO_CHANNELS; ++j) {
+ digester.add (_input_channels);
+ digester.add (_output_channels);
+ for (int i = 0; i < _input_channels; ++i) {
+ for (int j = 0; j < _output_channels; ++j) {
digester.add (_gain[i][j]);
}
}
@@ -155,17 +154,17 @@ AudioMapping::digest () const
return digester.get ();
}
-list<dcp::Channel>
-AudioMapping::mapped_dcp_channels () const
+list<int>
+AudioMapping::mapped_output_channels () const
{
static float const minus_96_db = 0.000015849;
- list<dcp::Channel> mapped;
+ list<int> mapped;
for (vector<vector<float> >::const_iterator i = _gain.begin(); i != _gain.end(); ++i) {
for (size_t j = 0; j < i->size(); ++j) {
if (abs ((*i)[j]) > minus_96_db) {
- mapped.push_back ((dcp::Channel) j);
+ mapped.push_back (j);
}
}
}
@@ -185,9 +184,3 @@ AudioMapping::unmap_all ()
}
}
}
-
-void
-AudioMapping::set_name (int channel, string name)
-{
- _name[channel] = name;
-}
diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h
index e37beaeb2..57169cc1e 100644
--- a/src/lib/audio_mapping.h
+++ b/src/lib/audio_mapping.h
@@ -38,49 +38,43 @@ namespace cxml {
}
/** @class AudioMapping.
- * @brief A many-to-many mapping from some content channels to DCP channels.
- *
- * The number of content channels is set on construction and fixed,
- * and then each of those content channels are mapped to each DCP channel
- * by a linear gain.
+ * @brief A many-to-many mapping of audio channels.
*/
class AudioMapping
{
public:
AudioMapping ();
- AudioMapping (int channels);
+ AudioMapping (int input_channels, int output_channels);
AudioMapping (cxml::ConstNodePtr, int);
/* Default copy constructor is fine */
void as_xml (xmlpp::Node *) const;
- void make_default ();
+ void make_zero ();
- void set (int, dcp::Channel, float);
- float get (int, dcp::Channel) const;
+ void set (int input_channel, int output_channel, float);
+ float get (int input_channel, int output_channel) const;
- int content_channels () const {
- return _content_channels;
+ int input_channels () const {
+ return _input_channels;
}
- void set_name (int channel, std::string name);
- std::string name (int channel) const {
- return _name[channel];
+ int output_channels () const {
+ return _output_channels;
}
-
+
std::string digest () const;
- std::list<dcp::Channel> mapped_dcp_channels () const;
+ std::list<int> mapped_output_channels () const;
void unmap_all ();
private:
- void setup (int);
- void make_zero ();
-
- int _content_channels;
+ void setup (int input_channels, int output_channels);
+
+ int _input_channels;
+ int _output_channels;
std::vector<std::vector<float> > _gain;
- std::vector<std::string> _name;
};
#endif
diff --git a/src/lib/audio_processor.h b/src/lib/audio_processor.h
index 610e973a0..114756f91 100644
--- a/src/lib/audio_processor.h
+++ b/src/lib/audio_processor.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
*/
+/** @file src/lib/audio_processor.h
+ * @brief AudioProcessor class.
+ */
+
#ifndef DCPOMATIC_AUDIO_PROCESSOR_H
#define DCPOMATIC_AUDIO_PROCESSOR_H
@@ -24,21 +28,39 @@
#include <boost/shared_ptr.hpp>
#include <list>
#include <string>
+#include <vector>
class AudioBuffers;
+class AudioMapping;
+/** @class AudioProcessor
+ * @brief A parent class for processors of audio data.
+ *
+ * These are used to process data before it goes into the DCP, for things like
+ * stereo -> 5.1 upmixing.
+ */
class AudioProcessor
{
public:
virtual ~AudioProcessor () {}
+ /** @return User-visible (translated) name */
virtual std::string name () const = 0;
+ /** @return An internal identifier */
virtual std::string id () const = 0;
+ /** @return Number of input channels */
virtual ChannelCount in_channels () const = 0;
- virtual int out_channels (int) const = 0;
+ /** @return Number of output channels */
+ virtual int out_channels () const = 0;
+ /** @return A clone of this AudioProcessor for operation at the specified sampling rate */
virtual boost::shared_ptr<AudioProcessor> clone (int sampling_rate) const = 0;
+ /** Process some data, returning the processed result */
virtual boost::shared_ptr<AudioBuffers> run (boost::shared_ptr<const AudioBuffers>) = 0;
virtual void flush () {}
+ /** Make the supplied audio mapping into a sensible default for this processor */
+ virtual void make_audio_mapping_default (AudioMapping& mapping) const = 0;
+ /** @return the user-visible (translated) names of each of our inputs, in order */
+ virtual std::vector<std::string> input_names () const = 0;
static std::list<AudioProcessor const *> all ();
static void setup_audio_processors ();
diff --git a/src/lib/audio_stream.cc b/src/lib/audio_stream.cc
index a4fa8bd9b..bf55e0255 100644
--- a/src/lib/audio_stream.cc
+++ b/src/lib/audio_stream.cc
@@ -19,11 +19,12 @@
#include "audio_stream.h"
#include "audio_mapping.h"
+#include "util.h"
AudioStream::AudioStream (int frame_rate, int channels)
: _frame_rate (frame_rate)
{
- _mapping = AudioMapping (channels);
+ _mapping = AudioMapping (channels, MAX_DCP_AUDIO_CHANNELS);
}
AudioStream::AudioStream (int frame_rate, AudioMapping mapping)
@@ -51,5 +52,5 @@ int
AudioStream::channels () const
{
boost::mutex::scoped_lock lm (_mutex);
- return _mapping.content_channels ();
+ return _mapping.input_channels ();
}
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc
index 1278c4c10..9dc4afab9 100644
--- a/src/lib/ffmpeg_content.cc
+++ b/src/lib/ffmpeg_content.cc
@@ -173,7 +173,7 @@ FFmpegContent::examine (shared_ptr<Job> job)
if (!_audio_streams.empty ()) {
AudioMapping m = _audio_streams.front()->mapping ();
- m.make_default ();
+ film->make_audio_mapping_default (m);
_audio_streams.front()->set_mapping (m);
}
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 0e55ec1d3..90bfad6a2 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -595,11 +595,11 @@ Film::isdcf_name (bool if_created_now) const
/* Find all mapped channels */
- list<dcp::Channel> mapped;
+ list<int> mapped;
for (ContentList::const_iterator i = cl.begin(); i != cl.end(); ++i) {
shared_ptr<const AudioContent> ac = dynamic_pointer_cast<const AudioContent> (*i);
if (ac) {
- list<dcp::Channel> c = ac->audio_mapping().mapped_dcp_channels ();
+ list<int> c = ac->audio_mapping().mapped_output_channels ();
copy (c.begin(), c.end(), back_inserter (mapped));
}
}
@@ -611,13 +611,13 @@ Film::isdcf_name (bool if_created_now) const
int non_lfe = 0;
int lfe = 0;
- for (list<dcp::Channel>::const_iterator i = mapped.begin(); i != mapped.end(); ++i) {
- if (static_cast<int> (*i) >= audio_channels()) {
+ for (list<int>::const_iterator i = mapped.begin(); i != mapped.end(); ++i) {
+ if (*i >= audio_channels()) {
/* This channel is mapped but is not included in the DCP */
continue;
}
- if ((*i) == dcp::LFE) {
+ if (static_cast<dcp::Channel> (*i) == dcp::LFE) {
++lfe;
} else {
++non_lfe;
@@ -1160,3 +1160,53 @@ Film::subtitle_language () const
return all;
}
+
+/** Change the gains of the supplied AudioMapping to make it a default
+ * for this film. The defaults are guessed based on what processor (if any)
+ * is in use and the number of input channels.
+ */
+void
+Film::make_audio_mapping_default (AudioMapping& mapping) const
+{
+ if (audio_processor ()) {
+ audio_processor()->make_audio_mapping_default (mapping);
+ } else {
+ mapping.make_zero ();
+ if (mapping.input_channels() == 1) {
+ /* Mono -> Centre */
+ mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
+ } else {
+ /* 1:1 mapping */
+ for (int i = 0; i < min (mapping.input_channels(), mapping.output_channels()); ++i) {
+ mapping.set (i, i, 1);
+ }
+ }
+ }
+}
+
+/** @return The names of the channels that audio contents' outputs are passed into;
+ * this is either the DCP or a AudioProcessor.
+ */
+vector<string>
+Film::audio_output_names () const
+{
+ if (audio_processor ()) {
+ return audio_processor()->input_names ();
+ }
+
+ vector<string> n;
+ n.push_back (_("L"));
+ n.push_back (_("R"));
+ n.push_back (_("C"));
+ n.push_back (_("Lfe"));
+ n.push_back (_("Ls"));
+ n.push_back (_("Rs"));
+ n.push_back (_("HI"));
+ n.push_back (_("VI"));
+ n.push_back (_("Lc"));
+ n.push_back (_("Rc"));
+ n.push_back (_("BsL"));
+ n.push_back (_("BsR"));
+
+ return vector<string> (n.begin(), n.begin() + audio_channels ());
+}
diff --git a/src/lib/film.h b/src/lib/film.h
index 8d7d2e0fb..6008160cd 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -48,6 +48,7 @@ class Playlist;
class AudioContent;
class Screen;
class AudioProcessor;
+class AudioMapping;
struct isdcf_name_test;
/** @class Film
@@ -137,6 +138,9 @@ public:
std::string subtitle_language () const;
+ void make_audio_mapping_default (AudioMapping & mapping) const;
+ std::vector<std::string> audio_output_names () const;
+
/** Identifiers for the parts of our state;
used for signalling changes.
*/
diff --git a/src/lib/mid_side_decoder.cc b/src/lib/mid_side_decoder.cc
index be82f6754..fe6282261 100644
--- a/src/lib/mid_side_decoder.cc
+++ b/src/lib/mid_side_decoder.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
#include "mid_side_decoder.h"
#include "audio_buffers.h"
+#include "audio_mapping.h"
#include "i18n.h"
using std::string;
+using std::min;
+using std::vector;
using boost::shared_ptr;
string
@@ -44,7 +47,7 @@ MidSideDecoder::in_channels () const
}
int
-MidSideDecoder::out_channels (int) const
+MidSideDecoder::out_channels () const
{
return 3;
}
@@ -70,3 +73,26 @@ MidSideDecoder::run (shared_ptr<const AudioBuffers> in)
return out;
}
+
+void
+MidSideDecoder::make_audio_mapping_default (AudioMapping& mapping) const
+{
+ /* Just map the first two input channels to our M/S */
+ mapping.make_zero ();
+ for (int i = 0; i < min (2, mapping.input_channels()); ++i) {
+ mapping.set (i, i, 1);
+ }
+}
+
+vector<string>
+MidSideDecoder::input_names () const
+{
+ vector<string> n;
+
+ /// TRANSLATORS: this is the name of the `mid' channel for mid-side decoding
+ n.push_back (_("Mid"));
+ /// TRANSLATORS: this is the name of the `side' channel for mid-side decoding
+ n.push_back (_("Side"));
+
+ return n;
+}
diff --git a/src/lib/mid_side_decoder.h b/src/lib/mid_side_decoder.h
index dac6cb7d9..197c7b33b 100644
--- a/src/lib/mid_side_decoder.h
+++ b/src/lib/mid_side_decoder.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,9 +25,9 @@ public:
std::string name () const;
std::string id () const;
ChannelCount in_channels () const;
- int out_channels (int) const;
+ int out_channels () const;
boost::shared_ptr<AudioProcessor> clone (int) const;
boost::shared_ptr<AudioBuffers> run (boost::shared_ptr<const AudioBuffers>);
+ void make_audio_mapping_default (AudioMapping& mapping) const;
+ std::vector<std::string> input_names () const;
};
-
-
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 1a55a8472..ac5a70570 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -455,14 +455,14 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate)
shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), all.audio->frames()));
dcp_mapped->make_silent ();
AudioMapping map = j->mapping ();
- for (int i = 0; i < map.content_channels(); ++i) {
+ for (int i = 0; i < map.input_channels(); ++i) {
for (int j = 0; j < _film->audio_channels(); ++j) {
- if (map.get (i, static_cast<dcp::Channel> (j)) > 0) {
+ if (map.get (i, j) > 0) {
dcp_mapped->accumulate_channel (
all.audio.get(),
i,
j,
- map.get (i, static_cast<dcp::Channel> (j))
+ map.get (i, j)
);
}
}
diff --git a/src/lib/single_stream_audio_content.cc b/src/lib/single_stream_audio_content.cc
index a38ef0e1e..f978fa423 100644
--- a/src/lib/single_stream_audio_content.cc
+++ b/src/lib/single_stream_audio_content.cc
@@ -60,11 +60,14 @@ SingleStreamAudioContent::as_xml (xmlpp::Node* node) const
void
SingleStreamAudioContent::take_from_audio_examiner (shared_ptr<AudioExaminer> examiner)
{
+ shared_ptr<const Film> film = _film.lock ();
+ DCPOMATIC_ASSERT (film);
+
{
boost::mutex::scoped_lock lm (_mutex);
_audio_stream.reset (new AudioStream (examiner->audio_frame_rate(), examiner->audio_channels ()));
AudioMapping m = _audio_stream->mapping ();
- m.make_default ();
+ film->make_audio_mapping_default (m);
_audio_stream->set_mapping (m);
}
diff --git a/src/lib/upmixer_a.cc b/src/lib/upmixer_a.cc
index dce08fe37..1edc0104d 100644
--- a/src/lib/upmixer_a.cc
+++ b/src/lib/upmixer_a.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
#include "upmixer_a.h"
#include "audio_buffers.h"
+#include "audio_mapping.h"
#include "i18n.h"
using std::string;
+using std::min;
+using std::vector;
using boost::shared_ptr;
UpmixerA::UpmixerA (int sampling_rate)
@@ -56,7 +59,7 @@ UpmixerA::in_channels () const
}
int
-UpmixerA::out_channels (int) const
+UpmixerA::out_channels () const
{
return 6;
}
@@ -107,3 +110,22 @@ UpmixerA::flush ()
_ls.flush ();
_rs.flush ();
}
+
+void
+UpmixerA::make_audio_mapping_default (AudioMapping& mapping) const
+{
+ /* Just map the first two input channels to our L/R */
+ mapping.make_zero ();
+ for (int i = 0; i < min (2, mapping.input_channels()); ++i) {
+ mapping.set (i, i, 1);
+ }
+}
+
+vector<string>
+UpmixerA::input_names () const
+{
+ vector<string> n;
+ n.push_back (_("Upmix L"));
+ n.push_back (_("Upmix R"));
+ return n;
+}
diff --git a/src/lib/upmixer_a.h b/src/lib/upmixer_a.h
index 32e3f5fb6..9a927b0cf 100644
--- a/src/lib/upmixer_a.h
+++ b/src/lib/upmixer_a.h
@@ -28,10 +28,12 @@ public:
std::string name () const;
std::string id () const;
ChannelCount in_channels () const;
- int out_channels (int) const;
+ int out_channels () const;
boost::shared_ptr<AudioProcessor> clone (int) const;
boost::shared_ptr<AudioBuffers> run (boost::shared_ptr<const AudioBuffers>);
void flush ();
+ void make_audio_mapping_default (AudioMapping& mapping) const;
+ std::vector<std::string> input_names () const;
private:
BandPassAudioFilter _left;