Allow 96kHz audio as an advanced option (#1789).
authorCarl Hetherington <cth@carlh.net>
Tue, 4 Jan 2022 23:33:28 +0000 (23:33 +0000)
committerCarl Hetherington <cth@carlh.net>
Thu, 28 Apr 2022 22:07:13 +0000 (00:07 +0200)
src/lib/config.cc
src/lib/config.h
src/lib/film.cc
src/lib/film.h
src/wx/dcp_panel.cc
src/wx/dcp_panel.h
src/wx/full_config_dialog.cc

index b6df1a88d871c25b6aefcf797a27ca4b635d87e1..36aae76de8385f028584bd0939a110ec1d073dc9 100644 (file)
@@ -98,6 +98,7 @@ Config::set_defaults ()
        _tms_password = "";
        _allow_any_dcp_frame_rate = false;
        _allow_any_container = false;
+       _allow_96khz_audio = false;
        _show_experimental_audio_processors = false;
        _language = optional<string> ();
        _default_still_length = 10;
@@ -406,6 +407,7 @@ try
        _maximum_j2k_bandwidth = f.optional_number_child<int> ("MaximumJ2KBandwidth").get_value_or (250000000);
        _allow_any_dcp_frame_rate = f.optional_bool_child ("AllowAnyDCPFrameRate").get_value_or (false);
        _allow_any_container = f.optional_bool_child ("AllowAnyContainer").get_value_or (false);
+       _allow_96khz_audio = f.optional_bool_child("Allow96kHzAudio").get_value_or(false);
        _show_experimental_audio_processors = f.optional_bool_child ("ShowExperimentalAudioProcessors").get_value_or (false);
 
        _log_types = f.optional_number_child<int> ("LogTypes").get_value_or (LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR);
@@ -784,6 +786,8 @@ Config::write_config () const
        root->add_child("AllowAnyDCPFrameRate")->add_child_text (_allow_any_dcp_frame_rate ? "1" : "0");
        /* [XML] AllowAnyContainer 1 to allow users to user any container ratio for their DCP, 0 to limit the GUI to DCI Flat/Scope */
        root->add_child("AllowAnyContainer")->add_child_text (_allow_any_container ? "1" : "0");
+       /* [XML] Allow96kHzAudio 1 to allow users to make DCPs with 96kHz audio, 0 to always make 48kHz DCPs */
+       root->add_child("Allow96kHzAudio")->add_child_text(_allow_96khz_audio ? "1" : "0");
        /* [XML] ShowExperimentalAudioProcessors 1 to offer users the (experimental) audio upmixer processors, 0 to hide them */
        root->add_child("ShowExperimentalAudioProcessors")->add_child_text (_show_experimental_audio_processors ? "1" : "0");
        /* [XML] LogTypes Types of logging to write; a bitfield where 1 is general notes, 2 warnings, 4 errors, 8 debug information related
index e9b3ec203af95e762f6271ef66aa501f36ab5a1d..1d40a3b1579e4d1b32e3353c59727ec43cdd0a1b 100644 (file)
@@ -167,6 +167,10 @@ public:
                return _allow_any_container;
        }
 
+       bool allow_96khz_audio () const {
+               return _allow_96khz_audio;
+       }
+
        bool show_experimental_audio_processors () const {
                return _show_experimental_audio_processors;
        }
@@ -651,6 +655,10 @@ public:
                maybe_set (_allow_any_container, a);
        }
 
+       void set_allow_96hhz_audio (bool a) {
+               maybe_set (_allow_96khz_audio, a);
+       }
+
        void set_show_experimental_audio_processors (bool e) {
                maybe_set (_show_experimental_audio_processors, e, SHOW_EXPERIMENTAL_AUDIO_PROCESSORS);
        }
@@ -1199,6 +1207,7 @@ private:
            https://www.dcpomatic.com/forum/viewtopic.php?f=2&t=1119&p=4468
        */
        bool _allow_any_container;
+       bool _allow_96khz_audio;
        /** Offer the upmixers in the audio processor settings */
        bool _show_experimental_audio_processors;
        boost::optional<std::string> _language;
index ef64a91d339d1d479999496477e63d727967950f..7aeb6ab770d3eecddbffa8b2def6f2e9eed834e9 100644 (file)
@@ -408,6 +408,7 @@ Film::metadata (bool with_content_paths) const
        root->add_child("Resolution")->add_child_text (resolution_to_string (_resolution));
        root->add_child("J2KBandwidth")->add_child_text (raw_convert<string> (_j2k_bandwidth));
        root->add_child("VideoFrameRate")->add_child_text (raw_convert<string> (_video_frame_rate));
+       root->add_child("AudioFrameRate")->add_child_text(raw_convert<string>(_audio_frame_rate));
        root->add_child("ISDCFDate")->add_child_text (boost::gregorian::to_iso_string (_isdcf_date));
        root->add_child("AudioChannels")->add_child_text (raw_convert<string> (_audio_channels));
        root->add_child("ThreeD")->add_child_text (_three_d ? "1" : "0");
@@ -561,6 +562,7 @@ Film::read_metadata (optional<boost::filesystem::path> path)
        _resolution = string_to_resolution (f.string_child ("Resolution"));
        _j2k_bandwidth = f.number_child<int> ("J2KBandwidth");
        _video_frame_rate = f.number_child<int> ("VideoFrameRate");
+       _audio_frame_rate = f.optional_number_child<int>("AudioFrameRate").get_value_or(48000);
        _encrypted = f.bool_child ("Encrypted");
        _audio_channels = f.number_child<int> ("AudioChannels");
        /* We used to allow odd numbers (and zero) channels, but it's just not worth
@@ -1565,14 +1567,6 @@ Film::playlist_order_changed ()
        signal_change (ChangeType::DONE, Property::CONTENT_ORDER);
 }
 
-int
-Film::audio_frame_rate () const
-{
-       /* It seems that nobody makes 96kHz DCPs at the moment, so let's avoid them.
-          See #1436.
-       */
-       return 48000;
-}
 
 void
 Film::set_sequence (bool s)
@@ -2160,6 +2154,14 @@ Film::set_audio_language (optional<dcp::LanguageTag> language)
 }
 
 
+void
+Film::set_audio_frame_rate (int rate)
+{
+       FilmChangeSignaller ch (this, Property::AUDIO_FRAME_RATE);
+       _audio_frame_rate = rate;
+}
+
+
 bool
 Film::has_sign_language_video_channel () const
 {
index 1d1034775d6042943fbc1c923e33c3d0cf5482a3..e9c043b72f6899ca65c1c008e57119d02e6d8dc1 100644 (file)
@@ -152,8 +152,6 @@ public:
 
        std::vector<CPLSummary> cpls () const;
 
-       int audio_frame_rate () const;
-
        std::list<DCPTextTrack> closed_caption_tracks () const;
 
        uint64_t required_disk_space () const;
@@ -233,6 +231,7 @@ public:
                ENCRYPTED,
                J2K_BANDWIDTH,
                VIDEO_FRAME_RATE,
+               AUDIO_FRAME_RATE,
                AUDIO_CHANNELS,
                /** The setting of _three_d has changed */
                THREE_D,
@@ -417,6 +416,10 @@ public:
                return _isdcf_date;
        }
 
+       int audio_frame_rate () const {
+               return _audio_frame_rate;
+       }
+
        /* SET */
 
        void set_directory (boost::filesystem::path);
@@ -463,6 +466,7 @@ public:
        void set_distributor (boost::optional<std::string> d = boost::none);
        void set_luminance (boost::optional<dcp::Luminance> l = boost::none);
        void set_audio_language (boost::optional<dcp::LanguageTag> language);
+       void set_audio_frame_rate (int rate);
 
        void add_ffoc_lfoc (Markers& markers) const;
 
@@ -570,6 +574,7 @@ private:
        bool _two_d_version_of_three_d = false;
        boost::optional<dcp::Luminance> _luminance;
        boost::optional<dcp::LanguageTag> _audio_language;
+       int _audio_frame_rate = 48000;
 
        int _state_version;
 
index ab6bd22b5ab0534c764691a0edc0e8ad75c49415..e4cc0c558626b646a3209bdde7445d31306125a7 100644 (file)
@@ -479,6 +479,9 @@ DCPPanel::film_changed (Film::Property p)
                setup_sensitivity ();
                break;
        }
+       case Film::Property::AUDIO_FRAME_RATE:
+               checked_set (_audio_sample_rate, _film->audio_frame_rate() == 48000 ? 0 : 1);
+               break;
        case Film::Property::CONTENT_VERSIONS:
        case Film::Property::VERSION_NUMBER:
        case Film::Property::RELEASE_TERRITORY:
@@ -624,6 +627,7 @@ DCPPanel::set_film (shared_ptr<Film> film)
        film_changed (Film::Property::REEL_LENGTH);
        film_changed (Film::Property::REENCODE_J2K);
        film_changed (Film::Property::AUDIO_LANGUAGE);
+       film_changed (Film::Property::AUDIO_FRAME_RATE);
 
        set_general_sensitivity(static_cast<bool>(_film));
 }
@@ -892,6 +896,9 @@ DCPPanel::make_audio_panel ()
        _audio_channels = new wxChoice (panel, wxID_ANY);
        setup_audio_channels_choice (_audio_channels, minimum_allowed_audio_channels ());
 
+       _audio_sample_rate_label = create_label (panel, _("Sample rate"), true);
+       _audio_sample_rate = new wxChoice (panel, wxID_ANY);
+
        _processor_label = create_label (panel, _("Processor"), true);
        _audio_processor = new wxChoice (panel, wxID_ANY);
        add_audio_processors ();
@@ -899,9 +906,13 @@ DCPPanel::make_audio_panel ()
        _show_audio = new Button (panel, _("Show graph of audio levels..."));
 
        _audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DCPPanel::audio_channels_changed, this));
+       _audio_sample_rate->Bind (wxEVT_CHOICE, boost::bind(&DCPPanel::audio_sample_rate_changed, this));
        _audio_processor->Bind (wxEVT_CHOICE, boost::bind (&DCPPanel::audio_processor_changed, this));
        _show_audio->Bind (wxEVT_BUTTON, boost::bind (&DCPPanel::show_audio_clicked, this));
 
+       _audio_sample_rate->Append (_("48kHz"));
+       _audio_sample_rate->Append (_("96kHz"));
+
        add_audio_panel_to_grid ();
 
        return panel;
@@ -917,6 +928,10 @@ DCPPanel::add_audio_panel_to_grid ()
        _audio_grid->Add (_audio_channels, wxGBPosition (r, 1));
        ++r;
 
+       add_label_to_sizer (_audio_grid, _audio_sample_rate_label, true, wxGBPosition(r, 0));
+       _audio_grid->Add (_audio_sample_rate, wxGBPosition(r, 1));
+       ++r;
+
        add_label_to_sizer (_audio_grid, _processor_label, true, wxGBPosition (r, 0));
        _audio_grid->Add (_audio_processor, wxGBPosition (r, 1));
        ++r;
@@ -1019,3 +1034,10 @@ DCPPanel::edit_audio_language_clicked ()
        d->Destroy ();
 }
 
+
+void
+DCPPanel::audio_sample_rate_changed ()
+{
+       _film->set_audio_frame_rate (_audio_sample_rate->GetSelection() == 0 ? 48000 : 96000);
+}
+
index 9da7a692989074821dacd99114e9d5071ea99b65..2e7555487d5a273a5ff0b88f8d8b2849adc53fdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2022 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -88,6 +88,7 @@ private:
        void reencode_j2k_changed ();
        void enable_audio_language_toggled ();
        void edit_audio_language_clicked ();
+       void audio_sample_rate_changed ();
 
        void setup_frame_rate_widget ();
        void setup_container ();
@@ -136,6 +137,8 @@ private:
        wxSizer* _frame_rate_sizer;
        wxStaticText* _channels_label;
        wxChoice* _audio_channels;
+       wxStaticText* _audio_sample_rate_label;
+       wxChoice* _audio_sample_rate;
        wxStaticText* _processor_label;
        wxChoice* _audio_processor;
        wxButton* _show_audio;
index c13ec7ed0c8b678259566326466d87c00f16e3dd..e39a10f09632516a15952bd0653954b6fee07adc 100644 (file)
@@ -1420,10 +1420,11 @@ private:
 
                _allow_any_container = new CheckBox (_panel, _("Allow full-frame and non-standard container ratios"));
                table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
-               table->AddSpacer (0);
-
                restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
                restart->SetFont (font);
+
+               _allow_96khz_audio = new CheckBox (_panel, _("Allow creation of DCPs with 96kHz audio"));
+               table->Add (_allow_96khz_audio, 1, wxEXPAND | wxALL);
                table->AddSpacer (0);
 
                _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
@@ -1528,6 +1529,7 @@ private:
                _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
                _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
                _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
+               _allow_96khz_audio->Bind (wxEVT_CHECKBOX, boost::bind(&AdvancedPage::allow_96khz_audio_changed, this));
                _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
                _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
                _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
@@ -1563,6 +1565,7 @@ private:
                }
                checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
                checked_set (_allow_any_container, config->allow_any_container ());
+               checked_set (_allow_96khz_audio, config->allow_96khz_audio());
                checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
                checked_set (_only_servers_encode, config->only_servers_encode ());
                checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
@@ -1610,6 +1613,11 @@ private:
                Config::instance()->set_allow_any_container(_allow_any_container->GetValue());
        }
 
+       void allow_96khz_audio_changed ()
+       {
+               Config::instance()->set_allow_96hhz_audio(_allow_96khz_audio->GetValue());
+       }
+
        void show_experimental_audio_processors_changed ()
        {
                Config::instance()->set_show_experimental_audio_processors(_show_experimental_audio_processors->GetValue());
@@ -1678,6 +1686,7 @@ private:
        wxSpinCtrl* _frames_in_memory_multiplier = nullptr;
        wxCheckBox* _allow_any_dcp_frame_rate = nullptr;
        wxCheckBox* _allow_any_container = nullptr;
+       wxCheckBox* _allow_96khz_audio = nullptr;
        wxCheckBox* _show_experimental_audio_processors = nullptr;
        wxCheckBox* _only_servers_encode = nullptr;
        NameFormatEditor* _dcp_metadata_filename_format = nullptr;