diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-02-09 21:27:54 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-02-09 21:27:54 +0100 |
| commit | 1ce09f162354c2933eece74bb0935638a20d1cd9 (patch) | |
| tree | 9383ad6d4b3667eece5528bfd0b7c245a22b403a | |
| parent | 0e34bd5aebe27f7cb69abacbbc0523accf14b77d (diff) | |
Add --audio-channels option to dcpomatic2_create (#2966).
| -rw-r--r-- | src/lib/create_cli.cc | 43 | ||||
| -rw-r--r-- | src/lib/create_cli.h | 1 | ||||
| -rw-r--r-- | test/create_cli_test.cc | 25 |
3 files changed, 58 insertions, 11 deletions
diff --git a/src/lib/create_cli.cc b/src/lib/create_cli.cc index c2378e603..f726aa0ae 100644 --- a/src/lib/create_cli.cc +++ b/src/lib/create_cli.cc @@ -58,6 +58,7 @@ string CreateCLI::_help = " --config <dir> directory containing config.xml and cinemas.sqlite3\n" " --twok make a 2K DCP instead of choosing a resolution based on the content\n" " --fourk make a 4K DCP instead of choosing a resolution based on the content\n" + " -a, --audio-channels <n> specify the number of audio channels in the DCP\n" " -o, --output <dir> output directory\n" " --twod make a 2D DCP\n" " --threed make a 3D DCP\n" @@ -154,6 +155,7 @@ CreateCLI::CreateCLI (int argc, char* argv[]) int dcp_frame_rate_int = 0; string template_name_string; int64_t video_bit_rate_int = 0; + optional<int> audio_channels; auto next_frame_type = VideoFrameType::TWO_D; optional<dcp::Channel> channel; optional<float> gain; @@ -227,6 +229,7 @@ CreateCLI::CreateCLI (int argc, char* argv[]) argument_option(i, argc, argv, "", "--config", &claimed, &error, &config_dir, string_to_path); argument_option(i, argc, argv, "-o", "--output", &claimed, &error, &output_dir, string_to_path); argument_option(i, argc, argv, "", "--video-bit-rate", &claimed, &error, &video_bit_rate_int); + argument_option(i, argc, argv, "-a", "--audio-channels", &claimed, &error, &audio_channels); std::function<optional<dcp::Channel> (string)> convert_channel = [](string channel) -> optional<dcp::Channel>{ if (channel == "L") { @@ -346,6 +349,34 @@ CreateCLI::CreateCLI (int argc, char* argv[]) error = String::compose("%1: video-bit-rate must be between 10 and %2 Mbit/s", argv[0], (Config::instance()->maximum_video_bit_rate(VideoEncoding::JPEG2000) / 1000000)); return; } + + /* See how many audio channels we would need to accommmodate the requested channel mappings */ + int channels_for_content_specs = 0; + for (auto cli_content: content) { + if (cli_content.channel) { + channels_for_content_specs = std::max(channels_for_content_specs, static_cast<int>(*cli_content.channel) + 1); + } + } + + /* Complain if we asked for a smaller number */ + if (audio_channels && *audio_channels < channels_for_content_specs) { + error = fmt::format("{}: cannot map audio as requested with only {} channels", argv[0], *audio_channels); + return; + } + + if (audio_channels && (*audio_channels % 2) != 0) { + error = fmt::format("{}: audio channel count must be even", argv[0]); + return; + } + + if (audio_channels) { + _audio_channels = *audio_channels; + } else { + _audio_channels = std::max(channels_for_content_specs, 6); + if (_audio_channels % 2) { + ++_audio_channels; + } + } } @@ -398,17 +429,7 @@ CreateCLI::make_film() const film->set_video_bit_rate(VideoEncoding::JPEG2000, *_video_bit_rate); } - int channels = 6; - for (auto cli_content: content) { - if (cli_content.channel) { - channels = std::max(channels, static_cast<int>(*cli_content.channel) + 1); - } - } - if (channels % 2) { - ++channels; - } - - film->set_audio_channels(channels); + film->set_audio_channels(_audio_channels); return film; } diff --git a/src/lib/create_cli.h b/src/lib/create_cli.h index 850cddea9..18115b4ca 100644 --- a/src/lib/create_cli.h +++ b/src/lib/create_cli.h @@ -73,6 +73,7 @@ private: bool _twok = false; bool _fourk = false; boost::optional<int64_t> _video_bit_rate; + int _audio_channels = 0; static std::string _help; }; diff --git a/test/create_cli_test.cc b/test/create_cli_test.cc index 7006fa6a0..ac184203d 100644 --- a/test/create_cli_test.cc +++ b/test/create_cli_test.cc @@ -196,6 +196,8 @@ BOOST_AUTO_TEST_CASE (create_cli_test) BOOST_CHECK (*cc.content[1].channel == dcp::Channel::RIGHT); BOOST_CHECK_EQUAL (cc.content[2].path, "sheila.wav"); BOOST_CHECK (!cc.content[2].channel); + auto film = cc.make_film(); + BOOST_CHECK_EQUAL(film->audio_channels(), 6); cc = run ("dcpomatic2_create --channel foo fred.wav"); BOOST_REQUIRE (cc.error); @@ -219,6 +221,29 @@ BOOST_AUTO_TEST_CASE (create_cli_test) cc = run("dcpomatic2_create -s SMPTE sheila.wav"); BOOST_CHECK(!cc.still_length); BOOST_CHECK(cc.error); + + cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel C sheila.wav --audio-channels 2"); + BOOST_REQUIRE(cc.error); + BOOST_CHECK_EQUAL(*cc.error, "dcpomatic2_create: cannot map audio as requested with only 2 channels"); + + cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel C sheila.wav --audio-channels 3"); + BOOST_REQUIRE(cc.error); + BOOST_CHECK_EQUAL(*cc.error, "dcpomatic2_create: audio channel count must be even"); + + cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel C sheila.wav"); + BOOST_CHECK(!cc.error); + film = cc.make_film(); + BOOST_CHECK_EQUAL(film->audio_channels(), 6); + + cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel HI sheila.wav"); + BOOST_CHECK(!cc.error); + film = cc.make_film(); + BOOST_CHECK_EQUAL(film->audio_channels(), 8); + + cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel C sheila.wav --audio-channels 16"); + BOOST_CHECK(!cc.error); + film = cc.make_film(); + BOOST_CHECK_EQUAL(film->audio_channels(), 16); } |
