summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-07-13 20:44:45 +0100
committerCarl Hetherington <cth@carlh.net>2014-07-13 20:44:45 +0100
commit3ddd928233130695d7f4eeee47a71409d8c04de7 (patch)
tree9f616a27fc6492b30536a2a366cf9e7211a87a3d /src/lib
parente8c5f14cb6736bdfa3610b2559c6c331c1c56984 (diff)
Very basic audio processing framework.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_content.cc40
-rw-r--r--src/lib/audio_content.h11
-rw-r--r--src/lib/audio_decoder.cc11
-rw-r--r--src/lib/audio_decoder.h1
-rw-r--r--src/lib/audio_mapping.cc2
-rw-r--r--src/lib/audio_processor.cc50
-rw-r--r--src/lib/audio_processor.h50
-rw-r--r--src/lib/channel_count.h49
-rw-r--r--src/lib/mid_side_decoder.cc72
-rw-r--r--src/lib/mid_side_decoder.h33
-rw-r--r--src/lib/util.cc2
-rw-r--r--src/lib/wscript2
12 files changed, 321 insertions, 2 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index 6317aa4cb..d02728b00 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -26,6 +26,7 @@
#include "exceptions.h"
#include "config.h"
#include "frame_rate_change.h"
+#include "audio_processor.h"
#include "i18n.h"
@@ -42,11 +43,13 @@ int const AudioContentProperty::AUDIO_FRAME_RATE = 202;
int const AudioContentProperty::AUDIO_GAIN = 203;
int const AudioContentProperty::AUDIO_DELAY = 204;
int const AudioContentProperty::AUDIO_MAPPING = 205;
+int const AudioContentProperty::AUDIO_PROCESSOR = 206;
AudioContent::AudioContent (shared_ptr<const Film> f)
: Content (f)
, _audio_gain (0)
, _audio_delay (Config::instance()->default_audio_delay ())
+ , _audio_processor (0)
{
}
@@ -55,6 +58,7 @@ AudioContent::AudioContent (shared_ptr<const Film> f, DCPTime s)
: Content (f, s)
, _audio_gain (0)
, _audio_delay (Config::instance()->default_audio_delay ())
+ , _audio_processor (0)
{
}
@@ -63,15 +67,20 @@ AudioContent::AudioContent (shared_ptr<const Film> f, boost::filesystem::path p)
: Content (f, p)
, _audio_gain (0)
, _audio_delay (Config::instance()->default_audio_delay ())
+ , _audio_processor (0)
{
}
AudioContent::AudioContent (shared_ptr<const Film> f, cxml::ConstNodePtr node)
: Content (f, node)
+ , _audio_processor (0)
{
_audio_gain = node->number_child<float> ("AudioGain");
_audio_delay = node->number_child<int> ("AudioDelay");
+ if (node->optional_string_child ("AudioProcessor")) {
+ _audio_processor = AudioProcessor::from_id (node->string_child ("AudioProcessor"));
+ }
}
AudioContent::AudioContent (shared_ptr<const Film> f, vector<shared_ptr<Content> > c)
@@ -94,6 +103,7 @@ AudioContent::AudioContent (shared_ptr<const Film> f, vector<shared_ptr<Content>
_audio_gain = ref->audio_gain ();
_audio_delay = ref->audio_delay ();
+ _audio_processor = ref->audio_processor ();
}
void
@@ -102,6 +112,9 @@ AudioContent::as_xml (xmlpp::Node* node) const
boost::mutex::scoped_lock lm (_mutex);
node->add_child("AudioGain")->add_child_text (raw_convert<string> (_audio_gain));
node->add_child("AudioDelay")->add_child_text (raw_convert<string> (_audio_delay));
+ if (_audio_processor) {
+ node->add_child("AudioProcessor")->add_child_text (_audio_processor->id ());
+ }
}
@@ -127,6 +140,22 @@ AudioContent::set_audio_delay (int d)
signal_changed (AudioContentProperty::AUDIO_DELAY);
}
+void
+AudioContent::set_audio_processor (AudioProcessor const * p)
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _audio_processor = p;
+ }
+
+ /* The channel count might have changed, so reset the mapping */
+ AudioMapping m (processed_audio_channels ());
+ m.make_default ();
+ set_audio_mapping (m);
+
+ signal_changed (AudioContentProperty::AUDIO_PROCESSOR);
+}
+
boost::signals2::connection
AudioContent::analyse_audio (boost::function<void()> finished)
{
@@ -196,3 +225,14 @@ AudioContent::resampled_audio_frame_rate () const
return rint (t);
}
+
+int
+AudioContent::processed_audio_channels () const
+{
+ if (!audio_processor ()) {
+ return audio_channels ();
+ }
+
+ return audio_processor()->out_channels (audio_channels ());
+}
+
diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h
index 131ced61a..540839d69 100644
--- a/src/lib/audio_content.h
+++ b/src/lib/audio_content.h
@@ -31,6 +31,8 @@ namespace cxml {
class Node;
}
+class AudioProcessor;
+
class AudioContentProperty
{
public:
@@ -40,6 +42,7 @@ public:
static int const AUDIO_GAIN;
static int const AUDIO_DELAY;
static int const AUDIO_MAPPING;
+ static int const AUDIO_PROCESSOR;
};
/** @class AudioContent
@@ -70,11 +73,13 @@ public:
virtual boost::filesystem::path audio_analysis_path () const;
int resampled_audio_frame_rate () const;
+ int processed_audio_channels () const;
boost::signals2::connection analyse_audio (boost::function<void()>);
void set_audio_gain (double);
void set_audio_delay (int);
+ void set_audio_processor (AudioProcessor const *);
double audio_gain () const {
boost::mutex::scoped_lock lm (_mutex);
@@ -86,11 +91,17 @@ public:
return _audio_delay;
}
+ AudioProcessor const * audio_processor () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _audio_processor;
+ }
+
private:
/** Gain to apply to audio in dB */
double _audio_gain;
/** Delay to apply to audio (positive moves audio later) in milliseconds */
int _audio_delay;
+ AudioProcessor const * _audio_processor;
};
#endif
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc
index 97a088791..19f31d30a 100644
--- a/src/lib/audio_decoder.cc
+++ b/src/lib/audio_decoder.cc
@@ -24,6 +24,7 @@
#include "resampler.h"
#include "util.h"
#include "film.h"
+#include "audio_processor.h"
#include "i18n.h"
@@ -43,13 +44,17 @@ AudioDecoder::AudioDecoder (shared_ptr<const AudioContent> content)
_resampler.reset (new Resampler (content->audio_frame_rate(), content->resampled_audio_frame_rate(), content->audio_channels ()));
}
+ if (content->audio_processor ()) {
+ _processor = content->audio_processor()->clone ();
+ }
+
reset_decoded_audio ();
}
void
AudioDecoder::reset_decoded_audio ()
{
- _decoded_audio = ContentAudio (shared_ptr<AudioBuffers> (new AudioBuffers (_audio_content->audio_channels(), 0)), 0);
+ _decoded_audio = ContentAudio (shared_ptr<AudioBuffers> (new AudioBuffers (_audio_content->processed_audio_channels(), 0)), 0);
}
shared_ptr<ContentAudio>
@@ -125,6 +130,10 @@ AudioDecoder::audio (shared_ptr<const AudioBuffers> data, ContentTime time)
data = _resampler->run (data);
}
+ if (_processor) {
+ data = _processor->run (data);
+ }
+
AudioFrame const frame_rate = _audio_content->resampled_audio_frame_rate ();
if (_seek_reference) {
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index 0553d7c81..045efc002 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -61,6 +61,7 @@ protected:
boost::shared_ptr<const AudioContent> _audio_content;
boost::shared_ptr<Resampler> _resampler;
+ boost::shared_ptr<AudioProcessor> _processor;
boost::optional<AudioFrame> _audio_position;
/** Currently-available decoded audio data */
ContentAudio _decoded_audio;
diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc
index b3757c5f1..e86e2e2ac 100644
--- a/src/lib/audio_mapping.cc
+++ b/src/lib/audio_mapping.cc
@@ -40,7 +40,7 @@ AudioMapping::AudioMapping ()
}
-/** Create a default AudioMapping for a given channel count.
+/** Create an empty AudioMapping for a given channel count.
* @param channels Number of channels.
*/
AudioMapping::AudioMapping (int channels)
diff --git a/src/lib/audio_processor.cc b/src/lib/audio_processor.cc
new file mode 100644
index 000000000..27146806b
--- /dev/null
+++ b/src/lib/audio_processor.cc
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2014 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "audio_processor.h"
+#include "mid_side_decoder.h"
+
+using std::string;
+using std::list;
+
+list<AudioProcessor const *> AudioProcessor::_all;
+
+void
+AudioProcessor::setup_audio_processors ()
+{
+ _all.push_back (new MidSideDecoder ());
+}
+
+AudioProcessor const *
+AudioProcessor::from_id (string id)
+{
+ for (list<AudioProcessor const *>::const_iterator i = _all.begin(); i != _all.end(); ++i) {
+ if ((*i)->id() == id) {
+ return *i;
+ }
+ }
+
+ return 0;
+}
+
+list<AudioProcessor const *>
+AudioProcessor::all ()
+{
+ return _all;
+}
diff --git a/src/lib/audio_processor.h b/src/lib/audio_processor.h
new file mode 100644
index 000000000..7ff9f0ec6
--- /dev/null
+++ b/src/lib/audio_processor.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2014 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef DCPOMATIC_AUDIO_PROCESSOR_H
+#define DCPOMATIC_AUDIO_PROCESSOR_H
+
+#include <list>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include "channel_count.h"
+
+class AudioBuffers;
+
+class AudioProcessor
+{
+public:
+ virtual ~AudioProcessor () {}
+
+ virtual std::string name () const = 0;
+ virtual std::string id () const = 0;
+ virtual ChannelCount in_channels () const = 0;
+ virtual int out_channels (int) const = 0;
+ virtual boost::shared_ptr<AudioProcessor> clone () const = 0;
+ virtual boost::shared_ptr<AudioBuffers> run (boost::shared_ptr<const AudioBuffers>) = 0;
+
+ static std::list<AudioProcessor const *> all ();
+ static void setup_audio_processors ();
+ static AudioProcessor const * from_id (std::string);
+
+private:
+ static std::list<AudioProcessor const *> _all;
+};
+
+#endif
diff --git a/src/lib/channel_count.h b/src/lib/channel_count.h
new file mode 100644
index 000000000..4247fc063
--- /dev/null
+++ b/src/lib/channel_count.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2014 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef DCPOMATIC_CHANNEL_COUNT_H
+#define DCPOMATIC_CHANNEL_COUNT_H
+
+class ChannelCount
+{
+public:
+ ChannelCount ()
+ : min (0)
+ , max (0)
+ {}
+
+ ChannelCount (int n)
+ : min (n)
+ , max (n)
+ {}
+
+ ChannelCount (int min_, int max_)
+ : min (min_)
+ , max (max_)
+ {}
+
+ bool includes (int c) {
+ return min <= c && c <= max;
+ }
+
+ int min;
+ int max;
+};
+
+#endif
diff --git a/src/lib/mid_side_decoder.cc b/src/lib/mid_side_decoder.cc
new file mode 100644
index 000000000..a518a4389
--- /dev/null
+++ b/src/lib/mid_side_decoder.cc
@@ -0,0 +1,72 @@
+/*
+ Copyright (C) 2014 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "mid_side_decoder.h"
+#include "audio_buffers.h"
+
+#include "i18n.h"
+
+using std::string;
+using boost::shared_ptr;
+
+string
+MidSideDecoder::name () const
+{
+ return _("Mid-side decoder");
+}
+
+string
+MidSideDecoder::id () const
+{
+ return N_("mid-side-decoder");
+}
+
+ChannelCount
+MidSideDecoder::in_channels () const
+{
+ return ChannelCount (2);
+}
+
+int
+MidSideDecoder::out_channels (int) const
+{
+ return 3;
+}
+
+shared_ptr<AudioProcessor>
+MidSideDecoder::clone () const
+{
+ return shared_ptr<AudioProcessor> (new MidSideDecoder ());
+}
+
+shared_ptr<AudioBuffers>
+MidSideDecoder::run (shared_ptr<const AudioBuffers> in)
+{
+ shared_ptr<AudioBuffers> out (new AudioBuffers (3, in->frames ()));
+ for (int i = 0; i < in->frames(); ++i) {
+ float const left = in->data()[0][i];
+ float const right = in->data()[1][i];
+ float const mid = (left + right) / 2;
+ out->data()[0][i] = left - mid;
+ out->data()[1][i] = right - mid;
+ out->data()[2][i] = mid;
+ }
+
+ return out;
+}
diff --git a/src/lib/mid_side_decoder.h b/src/lib/mid_side_decoder.h
new file mode 100644
index 000000000..a6d2721b6
--- /dev/null
+++ b/src/lib/mid_side_decoder.h
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2014 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "audio_processor.h"
+
+class MidSideDecoder : public AudioProcessor
+{
+public:
+ std::string name () const;
+ std::string id () const;
+ ChannelCount in_channels () const;
+ int out_channels (int) const;
+ boost::shared_ptr<AudioProcessor> clone () const;
+ boost::shared_ptr<AudioBuffers> run (boost::shared_ptr<const AudioBuffers>);
+};
+
+
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 55df5cc83..dd39e286e 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -72,6 +72,7 @@ extern "C" {
#include "video_content.h"
#include "rect.h"
#include "md5_digester.h"
+#include "audio_processor.h"
#ifdef DCPOMATIC_WINDOWS
#include "stack.hpp"
#endif
@@ -336,6 +337,7 @@ dcpomatic_setup ()
Scaler::setup_scalers ();
Filter::setup_filters ();
SoundProcessor::setup_sound_processors ();
+ AudioProcessor::setup_audio_processors ();
ui_thread = boost::this_thread::get_id ();
}
diff --git a/src/lib/wscript b/src/lib/wscript
index d96bb7f96..60150f4da 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -8,6 +8,7 @@ sources = """
audio_content.cc
audio_decoder.cc
audio_mapping.cc
+ audio_processor.cc
cinema.cc
colour_conversion.cc
config.cc
@@ -55,6 +56,7 @@ sources = """
log.cc
magick_image_proxy.cc
md5_digester.cc
+ mid_side_decoder.cc
player.cc
player_video.cc
playlist.cc