diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-07-06 23:23:26 +0200 |
|---|---|---|
| committer | cah <cth@carlh.net> | 2025-07-10 22:49:00 +0200 |
| commit | 4e244c8a4b34268445123b7d6df54ff303561fa5 (patch) | |
| tree | 54b92d242ea518ee0e9d55c20265d5ab963fc7a0 /src | |
| parent | a564301f86068484d98d329971f59b10c7de892e (diff) | |
Allow audio processors to pass through HI/VI/DBox etc (#3020).
Previously you couldn't map these things if you were using a processor.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/audio_processor.cc | 63 | ||||
| -rw-r--r-- | src/lib/audio_processor.h | 7 | ||||
| -rw-r--r-- | src/lib/film.cc | 23 | ||||
| -rw-r--r-- | src/lib/mid_side_decoder.cc | 19 | ||||
| -rw-r--r-- | src/lib/mid_side_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/upmixer_a.cc | 2 | ||||
| -rw-r--r-- | src/lib/upmixer_a.h | 4 | ||||
| -rw-r--r-- | src/lib/upmixer_b.cc | 2 | ||||
| -rw-r--r-- | src/lib/upmixer_b.h | 4 |
9 files changed, 115 insertions, 13 deletions
diff --git a/src/lib/audio_processor.cc b/src/lib/audio_processor.cc index e13ba017b..26c906635 100644 --- a/src/lib/audio_processor.cc +++ b/src/lib/audio_processor.cc @@ -25,7 +25,10 @@ #include "upmixer_a.h" #include "upmixer_b.h" +#include "i18n.h" + +using std::shared_ptr; using std::string; using std::unique_ptr; using std::vector; @@ -96,3 +99,63 @@ AudioProcessor::all() return raw; } + + +shared_ptr<AudioBuffers> +AudioProcessor::run(std::shared_ptr<const AudioBuffers> in, int channels) +{ + auto out = do_run(in, std::min(channels, out_channels())); + + if (out->channels() < channels) { + out->set_channels(channels); + } + + for (auto const pass: pass_through()) { + if (static_cast<int>(pass) < channels && static_cast<int>(pass) < out->channels()) { + out->copy_channel_from(in.get(), static_cast<int>(pass), static_cast<int>(pass)); + } + } + + return out; +} + + +void +AudioProcessor::make_audio_mapping_default(AudioMapping& mapping) const +{ + mapping.make_zero(); + + auto const channels = std::min(mapping.input_channels(), mapping.output_channels()); + + for (auto pass: pass_through()) { + if (static_cast<int>(pass) < channels) { + mapping.set(pass, static_cast<int>(pass), 1); + } + } +} + + +vector<NamedChannel> +AudioProcessor::input_names() const +{ + return { + NamedChannel(_("HI"), 6), + NamedChannel(_("VI"), 7), + NamedChannel(_("DBP"), 13), + NamedChannel(_("DBS"), 14), + NamedChannel(_("Sign"), 15) + }; +} + + +vector<dcp::Channel> +AudioProcessor::pass_through() +{ + return { + dcp::Channel::HI, + dcp::Channel::VI, + dcp::Channel::MOTION_DATA, + dcp::Channel::SYNC_SIGNAL, + dcp::Channel::SIGN_LANGUAGE + }; +} diff --git a/src/lib/audio_processor.h b/src/lib/audio_processor.h index 2c3df3add..f469f07c0 100644 --- a/src/lib/audio_processor.h +++ b/src/lib/audio_processor.h @@ -29,6 +29,7 @@ #include "named_channel.h" +#include <dcp/types.h> #include <memory> #include <string> #include <vector> @@ -58,7 +59,7 @@ public: /** @return A clone of this AudioProcessor for operation at the specified sampling rate */ virtual std::shared_ptr<AudioProcessor> clone(int sampling_rate) const = 0; /** Process some data, returning the processed result truncated or padded to `channels' */ - virtual std::shared_ptr<AudioBuffers> run(std::shared_ptr<const AudioBuffers>, int channels) = 0; + std::shared_ptr<AudioBuffers> run(std::shared_ptr<const AudioBuffers>, int channels); 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; @@ -69,6 +70,10 @@ public: static std::vector<AudioProcessor const *> visible(); static void setup_audio_processors(); static AudioProcessor const * from_id(std::string); + static std::vector<dcp::Channel> pass_through(); + +protected: + virtual std::shared_ptr<AudioBuffers> do_run(std::shared_ptr<const AudioBuffers>, int channels) = 0; private: static std::vector<std::unique_ptr<const AudioProcessor>> _experimental; diff --git a/src/lib/film.cc b/src/lib/film.cc index 58699743b..b73c2bac6 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -791,10 +791,23 @@ Film::mapped_audio_channels() const list<int> mapped; if (audio_processor()) { - /* Processors are mapped 1:1 to DCP outputs so we can work out mappings from there */ + /* Assume all a processor's declared output channels are mapped */ for (int i = 0; i < audio_processor()->out_channels(); ++i) { mapped.push_back(i); } + + /* Check to see if channels that the processor passes through are mapped */ + auto pass = AudioProcessor::pass_through(); + for (auto i: content()) { + if (i->audio) { + for (auto c: i->audio->mapping().mapped_output_channels()) { + if (std::find(pass.begin(), pass.end(), dcp::Channel(c)) != pass.end()) { + mapped.push_back(c); + } + } + } + } + } else { for (auto i: content()) { if (i->audio) { @@ -1885,7 +1898,13 @@ vector<NamedChannel> Film::audio_output_channel_names() const { if (audio_processor()) { - return audio_processor()->input_names(); + vector<NamedChannel> channels; + for (auto input: audio_processor()->input_names()) { + if (input.index < audio_channels()) { + channels.push_back(input); + } + } + return channels; } DCPOMATIC_ASSERT(MAX_DCP_AUDIO_CHANNELS == 16); diff --git a/src/lib/mid_side_decoder.cc b/src/lib/mid_side_decoder.cc index 695e4cad7..719dbce92 100644 --- a/src/lib/mid_side_decoder.cc +++ b/src/lib/mid_side_decoder.cc @@ -62,7 +62,7 @@ MidSideDecoder::clone(int) const shared_ptr<AudioBuffers> -MidSideDecoder::run(shared_ptr<const AudioBuffers> in, int channels) +MidSideDecoder::do_run(shared_ptr<const AudioBuffers> in, int channels) { int const N = min(channels, 3); auto out = make_shared<AudioBuffers>(channels, in->frames()); @@ -88,9 +88,12 @@ MidSideDecoder::run(shared_ptr<const AudioBuffers> in, int channels) 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) { + AudioProcessor::make_audio_mapping_default(mapping); + + auto const inputs = mapping.input_channels(); + + /* Map the first two input channels to our M/S */ + for (int i = 0; i < min(2, inputs); ++i) { mapping.set(i, i, 1); } } @@ -99,8 +102,14 @@ MidSideDecoder::make_audio_mapping_default(AudioMapping& mapping) const vector<NamedChannel> MidSideDecoder::input_names() const { - return { + vector<NamedChannel> names = { NamedChannel(_("Left"), 0), NamedChannel(_("Right"), 1) }; + + for (auto name: AudioProcessor::input_names()) { + names.push_back(name); + } + + return names; } diff --git a/src/lib/mid_side_decoder.h b/src/lib/mid_side_decoder.h index 34c3eecb5..0505d5953 100644 --- a/src/lib/mid_side_decoder.h +++ b/src/lib/mid_side_decoder.h @@ -29,7 +29,9 @@ public: std::string id() const override; int out_channels() const override; std::shared_ptr<AudioProcessor> clone(int) const override; - std::shared_ptr<AudioBuffers> run(std::shared_ptr<const AudioBuffers>, int channels) override; void make_audio_mapping_default(AudioMapping& mapping) const override; std::vector<NamedChannel> input_names() const override; + +protected: + std::shared_ptr<AudioBuffers> do_run(std::shared_ptr<const AudioBuffers>, int channels) override; }; diff --git a/src/lib/upmixer_a.cc b/src/lib/upmixer_a.cc index d87546a76..6eaaf0a52 100644 --- a/src/lib/upmixer_a.cc +++ b/src/lib/upmixer_a.cc @@ -74,7 +74,7 @@ UpmixerA::clone(int sampling_rate) const shared_ptr<AudioBuffers> -UpmixerA::run(shared_ptr<const AudioBuffers> in, int channels) +UpmixerA::do_run(shared_ptr<const AudioBuffers> in, int channels) { /* Input L and R */ auto in_L = in->channel(0); diff --git a/src/lib/upmixer_a.h b/src/lib/upmixer_a.h index 9b1e09ee5..fef6af056 100644 --- a/src/lib/upmixer_a.h +++ b/src/lib/upmixer_a.h @@ -40,11 +40,13 @@ public: std::string id() const override; int out_channels() const override; std::shared_ptr<AudioProcessor> clone(int) const override; - std::shared_ptr<AudioBuffers> run(std::shared_ptr<const AudioBuffers>, int channels) override; void flush() override; void make_audio_mapping_default(AudioMapping& mapping) const override; std::vector<NamedChannel> input_names() const override; +protected: + std::shared_ptr<AudioBuffers> do_run(std::shared_ptr<const AudioBuffers>, int channels) override; + private: BandPassAudioFilter _left; BandPassAudioFilter _right; diff --git a/src/lib/upmixer_b.cc b/src/lib/upmixer_b.cc index 40bed6b6e..1e084d03f 100644 --- a/src/lib/upmixer_b.cc +++ b/src/lib/upmixer_b.cc @@ -70,7 +70,7 @@ UpmixerB::clone(int sampling_rate) const shared_ptr<AudioBuffers> -UpmixerB::run(shared_ptr<const AudioBuffers> in, int channels) +UpmixerB::do_run(shared_ptr<const AudioBuffers> in, int channels) { auto out = make_shared<AudioBuffers>(channels, in->frames()); diff --git a/src/lib/upmixer_b.h b/src/lib/upmixer_b.h index 6ac310bdb..1fc89f704 100644 --- a/src/lib/upmixer_b.h +++ b/src/lib/upmixer_b.h @@ -38,11 +38,13 @@ public: std::string id() const override; int out_channels() const override; std::shared_ptr<AudioProcessor> clone(int) const override; - std::shared_ptr<AudioBuffers> run(std::shared_ptr<const AudioBuffers>, int channels) override; void flush() override; void make_audio_mapping_default(AudioMapping& mapping) const override; std::vector<NamedChannel> input_names() const override; +protected: + std::shared_ptr<AudioBuffers> do_run(std::shared_ptr<const AudioBuffers>, int channels) override; + private: LowPassAudioFilter _lfe; AudioDelay _delay; |
