summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
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;