int const AudioContentProperty::STREAMS = 200;
int const AudioContentProperty::GAIN = 201;
int const AudioContentProperty::DELAY = 202;
-int const AudioContentProperty::LANGUAGE = 203;
AudioContent::AudioContent (Content* parent)
{
_gain = node->number_child<double> ("AudioGain");
_delay = node->number_child<int> ("AudioDelay");
- auto lang = node->optional_node_child ("Language");
- if (lang) {
- _language = dcp::LanguageTag (lang->content());
- }
/* Backwards compatibility */
auto r = node->optional_number_child<double>("AudioVideoFrameRate");
if (c[i]->audio->delay() != ref->delay()) {
throw JoinError (_("Content to be joined must have the same audio delay."));
}
-
- if (c[i]->audio->language() != ref->language()) {
- throw JoinError (_("Content to be joined must have the same audio language."));
- }
}
_gain = ref->gain ();
_delay = ref->delay ();
_streams = ref->streams ();
- _language = ref->language ();
}
boost::mutex::scoped_lock lm (_mutex);
node->add_child("AudioGain")->add_child_text(raw_convert<string>(_gain));
node->add_child("AudioDelay")->add_child_text(raw_convert<string>(_delay));
- if (_language) {
- node->add_child("Language")->add_child_text(_language->to_string());
- }
}
}
-void
-AudioContent::set_language (optional<dcp::LanguageTag> language)
-{
- maybe_set (_language, language, AudioContentProperty::LANGUAGE);
-}
-
-
string
AudioContent::technical_summary () const
{
#include "content_part.h"
#include "audio_stream.h"
#include "audio_mapping.h"
-#include <dcp/language_tag.h>
/** @class AudioContentProperty
static int const STREAMS;
static int const GAIN;
static int const DELAY;
- static int const LANGUAGE;
};
void set_gain (double);
void set_delay (int);
- void set_language (boost::optional<dcp::LanguageTag> langauge);
double gain () const {
boost::mutex::scoped_lock lm (_mutex);
return _delay;
}
- boost::optional<dcp::LanguageTag> language () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _language;
- }
-
std::string processing_description (std::shared_ptr<const Film> film) const;
std::vector<AudioStreamPtr> streams () const {
/** Delay to apply to audio (positive moves audio later) in milliseconds */
int _delay = 0;
std::vector<AudioStreamPtr> _streams;
- boost::optional<dcp::LanguageTag> _language;
};
#endif
boost::mutex::scoped_lock lm (_mutex);
audio = make_shared<AudioContent>(this);
}
- audio->set_language (examiner->audio_language());
auto as = make_shared<AudioStream>(examiner->audio_frame_rate(), examiner->audio_length(), examiner->audio_channels());
audio->set_stream (as);
auto m = as->mapping ();
}
root->add_child("UserExplicitContainer")->add_child_text(_user_explicit_container ? "1" : "0");
root->add_child("UserExplicitResolution")->add_child_text(_user_explicit_resolution ? "1" : "0");
+ if (_audio_language) {
+ root->add_child("AudioLanguage")->add_child_text(_audio_language->to_string());
+ }
_playlist->as_xml (root->add_child ("Playlist"), with_content_paths);
return doc;
_user_explicit_container = f.optional_bool_child("UserExplicitContainer").get_value_or(true);
_user_explicit_resolution = f.optional_bool_child("UserExplicitResolution").get_value_or(true);
+ auto audio_language = f.optional_string_child("AudioLanguage");
+ if (audio_language) {
+ _audio_language = dcp::LanguageTag(*audio_language);
+ }
+
list<string> notes;
_playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes);
}
-vector<dcp::LanguageTag>
-Film::audio_languages () const
-{
- vector<dcp::LanguageTag> result;
- for (auto i: content()) {
- if (i->audio && !i->audio->mapping().mapped_output_channels().empty() && i->audio->language()) {
- result.push_back (i->audio->language().get());
- }
- }
-
- std::sort (result.begin(), result.end());
- auto last = std::unique (result.begin(), result.end());
- result.erase (last, result.end());
- return result;
-}
-
-
pair<optional<dcp::LanguageTag>, vector<dcp::LanguageTag>>
Film::subtitle_languages () const
{
}
}
- auto audio_langs = audio_languages();
- auto audio_language = (audio_langs.empty() || !audio_langs.front().language()) ? "XX" : audio_langs.front().language()->subtag();
+ auto audio_language = (_audio_language && _audio_language->language()) ? _audio_language->language()->subtag() : "XX";
d += "_" + to_upper (audio_language);
_two_d_version_of_three_d = t;
}
+
+void
+Film::set_audio_language (optional<dcp::LanguageTag> language)
+{
+ FilmChangeSignaller ch (this, Property::AUDIO_LANGUAGE);
+ _audio_language = language;
+}
+
std::list<dcpomatic::DCPTimePeriod> reels () const;
std::list<int> mapped_audio_channels () const;
- std::vector<dcp::LanguageTag> audio_languages () const;
+
+ boost::optional<dcp::LanguageTag> audio_language () const {
+ return _audio_language;
+ }
+
std::pair<boost::optional<dcp::LanguageTag>, std::vector<dcp::LanguageTag>> subtitle_languages () const;
std::string content_summary (dcpomatic::DCPTimePeriod period) const;
return _luminance;
}
+
/* SET */
void set_directory (boost::filesystem::path);
void set_two_d_version_of_three_d (bool t);
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 add_ffoc_lfoc (Markers& markers) const;
bool _red_band = false;
bool _two_d_version_of_three_d = false;
boost::optional<dcp::Luminance> _luminance;
+ boost::optional<dcp::LanguageTag> _audio_language;
int _state_version;
}
if (film()->audio_channels()) {
- auto langs = film()->audio_languages();
+ auto lang = film()->audio_language();
_sound_asset = make_shared<dcp::SoundAsset> (
dcp::Fraction(film()->video_frame_rate(), 1),
film()->audio_frame_rate(),
film()->audio_channels(),
- langs.empty() ? dcp::LanguageTag("en-US") : langs.front(),
+ lang ? *lang : dcp::LanguageTag("en-US"),
standard
);
boost::algorithm::replace_all (text, "$TYPE", film()->dcp_content_type()->pretty_name());
boost::algorithm::replace_all (text, "$CONTAINER", film()->container()->container_nickname());
- auto audio_languages = film()->audio_languages();
- if (!audio_languages.empty()) {
- boost::algorithm::replace_all (text, "$AUDIO_LANGUAGE", audio_languages.front().description());
+ auto audio_language = film()->audio_language();
+ if (audio_language) {
+ boost::algorithm::replace_all (text, "$AUDIO_LANGUAGE", audio_language->description());
} else {
boost::algorithm::replace_all (text, "$AUDIO_LANGUAGE", _("None"));
}
#include "content_panel.h"
#include "dcpomatic_button.h"
#include "gain_calculator_dialog.h"
-#include "language_tag_widget.h"
#include "static_text.h"
#include "wx_util.h"
#include "lib/config.h"
/// TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
_delay_ms_label = create_label (this, _("ms"), false);
- _enable_language = new wxCheckBox (this, wxID_ANY, _("Language"));
- _language = new LanguageTagWidget (this, _("Language used for the dialogue in this content"), boost::none);
-
_mapping = new AudioMappingView (this, _("Content"), _("content"), _("DCP"), _("DCP"));
_sizer->Add (_mapping, 1, wxEXPAND | wxALL, 6);
_reference->Bind (wxEVT_CHECKBOX, boost::bind (&AudioPanel::reference_clicked, this));
_show->Bind (wxEVT_BUTTON, boost::bind (&AudioPanel::show_clicked, this));
_gain_calculate_button->Bind (wxEVT_BUTTON, boost::bind (&AudioPanel::gain_calculate_button_clicked, this));
- _enable_language->Bind (wxEVT_CHECKBOX, boost::bind (&AudioPanel::enable_language_clicked, this));
- _language->Changed.connect (boost::bind(&AudioPanel::language_changed, this));
_mapping_connection = _mapping->Changed.connect (boost::bind (&AudioPanel::mapping_changed, this, _1));
_active_jobs_connection = JobManager::instance()->ActiveJobsChanged.connect (boost::bind (&AudioPanel::active_jobs_changed, this, _1, _2));
s->Add (_delay_ms_label, 0, wxALIGN_CENTER_VERTICAL);
_grid->Add (s, wxGBPosition(r, 1));
++r;
-
- s = new wxBoxSizer (wxHORIZONTAL);
- s->Add (_enable_language, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, DCPOMATIC_SIZER_GAP);
- s->Add (_language->sizer(), 1, wxALIGN_CENTER_VERTICAL | wxRIGHT);
- _grid->Add (s, wxGBPosition(r, 0), wxGBSpan(1, 2), wxEXPAND);
- ++r;
}
AudioPanel::~AudioPanel ()
setup_sensitivity ();
} else if (property == ContentProperty::VIDEO_FRAME_RATE) {
setup_description ();
- } else if (property == AudioContentProperty::LANGUAGE) {
- if (ac.size() == 1 && ac.front()->audio->language()) {
- _enable_language->SetValue (true);
- _language->set (ac.front()->audio->language());
- } else {
- _enable_language->SetValue (false);
- _language->set (boost::none);
- }
}
}
film_content_changed (AudioContentProperty::STREAMS);
film_content_changed (AudioContentProperty::GAIN);
- film_content_changed (AudioContentProperty::LANGUAGE);
film_content_changed (DCPContentProperty::REFERENCE_AUDIO);
setup_sensitivity ();
_delay->wrapped()->Enable (!ref);
_mapping->Enable (!ref && single);
_description->Enable (!ref && single);
- _enable_language->Enable (!ref && single);
- _language->enable (!ref && single && _enable_language->GetValue());
}
void
}
}
-
-void
-AudioPanel::enable_language_clicked ()
-{
- setup_sensitivity ();
- auto sel = _parent->selected_audio ();
- if (sel.size() == 1) {
- sel.front()->audio->set_language (_enable_language->GetValue() ? _language->get() : boost::none);
- }
-}
-
-
-void
-AudioPanel::language_changed ()
-{
- auto sel = _parent->selected_audio ();
- if (sel.size() == 1) {
- sel.front()->audio->set_language (_language->get());
- }
-}
-
void setup_sensitivity ();
void reference_clicked ();
void add_to_grid ();
- void enable_language_clicked ();
- void language_changed ();
boost::optional<float> peak () const;
wxCheckBox* _reference;
wxStaticText* _delay_label;
wxStaticText* _delay_ms_label;
ContentSpinCtrl<AudioContent>* _delay;
- wxCheckBox* _enable_language = nullptr;
- LanguageTagWidget* _language = nullptr;
AudioMappingView* _mapping;
wxStaticText* _description;
AudioDialog* _audio_dialog;
#include "dcpomatic_spin_ctrl.h"
#include "focus_manager.h"
#include "interop_metadata_dialog.h"
+#include "language_tag_dialog.h"
#include "markers_dialog.h"
#include "smpte_metadata_dialog.h"
#include "static_text.h"
wxALIGN_CENTRE_HORIZONTAL | wxST_NO_AUTORESIZE | wxST_ELLIPSIZE_MIDDLE
);
+ _enable_audio_language = new wxCheckBox (_panel, wxID_ANY, _("Audio language"));
+ _audio_language = new wxStaticText (_panel, wxID_ANY, wxT(""));
+ _edit_audio_language = new Button (_panel, _("Edit..."));
+
_dcp_content_type_label = create_label (_panel, _("Content Type"), true);
_dcp_content_type = new wxChoice (_panel, wxID_ANY);
_standard->Bind (wxEVT_CHOICE, boost::bind(&DCPPanel::standard_changed, this));
_markers->Bind (wxEVT_BUTTON, boost::bind(&DCPPanel::markers_clicked, this));
_metadata->Bind (wxEVT_BUTTON, boost::bind(&DCPPanel::metadata_clicked, this));
+ _enable_audio_language->Bind (wxEVT_CHECKBOX, boost::bind(&DCPPanel::enable_audio_language_toggled, this));
+ _edit_audio_language->Bind (wxEVT_BUTTON, boost::bind(&DCPPanel::edit_audio_language_clicked, this));
for (auto i: DCPContentType::all()) {
_dcp_content_type->Append (std_to_wx(i->pretty_name()));
_grid->Add (_dcp_name, wxGBPosition(r, 0), wxGBSpan(1, 2), wxALIGN_CENTER_VERTICAL | wxEXPAND);
++r;
+ {
+ auto s = new wxBoxSizer (wxHORIZONTAL);
+ s->Add (_enable_audio_language, 0, wxALIGN_CENTER_VERTICAL);
+ s->Add (_audio_language, 1, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, DCPOMATIC_SIZER_GAP);
+ s->Add (_edit_audio_language, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, DCPOMATIC_SIZER_GAP);
+ _grid->Add (s, wxGBPosition(r, 0), wxGBSpan(1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL);
+ }
+ ++r;
+
add_label_to_sizer (_grid, _dcp_content_type_label, true, wxGBPosition(r, 0));
_grid->Add (_dcp_content_type, wxGBPosition(r, 1));
++r;
setup_dcp_name ();
setup_sensitivity ();
break;
+ case Film::Property::AUDIO_LANGUAGE:
+ {
+ auto al = _film->audio_language();
+ checked_set (_enable_audio_language, static_cast<bool>(al));
+ checked_set (_audio_language, al ? std_to_wx(al->to_string()) : wxT(""));
+ setup_dcp_name ();
+ setup_sensitivity ();
+ break;
+ }
case Film::Property::CONTENT_VERSIONS:
case Film::Property::VERSION_NUMBER:
case Film::Property::RELEASE_TERRITORY:
DCPPanel::film_content_changed (int property)
{
if (property == AudioContentProperty::STREAMS ||
- property == AudioContentProperty::LANGUAGE ||
property == TextContentProperty::USE ||
property == TextContentProperty::BURN ||
property == TextContentProperty::LANGUAGE ||
film_changed (Film::Property::REEL_TYPE);
film_changed (Film::Property::REEL_LENGTH);
film_changed (Film::Property::REENCODE_J2K);
+ film_changed (Film::Property::AUDIO_LANGUAGE);
set_general_sensitivity(static_cast<bool>(_film));
}
_use_isdcf_name->Enable (_generally_sensitive);
_dcp_content_type->Enable (_generally_sensitive);
_copy_isdcf_name_button->Enable (_generally_sensitive);
+ _enable_audio_language->Enable (_generally_sensitive);
+ _audio_language->Enable (_enable_audio_language->GetValue());
+ _edit_audio_language->Enable (_enable_audio_language->GetValue());
_encrypted->Enable (_generally_sensitive);
_reel_type->Enable (_generally_sensitive && _film && !_film->references_dcp_video() && !_film->references_dcp_audio());
_reel_length->Enable (_generally_sensitive && _film && _film->reel_type() == ReelType::BY_LENGTH);
}
_audio_panel_sizer->Layout();
}
+
+
+void
+DCPPanel::enable_audio_language_toggled ()
+{
+ setup_sensitivity ();
+ if (_enable_audio_language->GetValue()) {
+ auto al = wx_to_std (_audio_language->GetLabel());
+ _film->set_audio_language (al.empty() ? dcp::LanguageTag("en-US") : dcp::LanguageTag(al));
+ } else {
+ _film->set_audio_language (boost::none);
+ }
+}
+
+
+void
+DCPPanel::edit_audio_language_clicked ()
+{
+ DCPOMATIC_ASSERT (_film->audio_language());
+ auto d = new LanguageTagDialog (_panel, *_film->audio_language());
+ d->ShowModal ();
+ _film->set_audio_language(d->get());
+ d->Destroy ();
+}
+
#include "lib/film.h"
+class Button;
class wxNotebook;
class wxPanel;
class wxBoxSizer;
void markers_clicked ();
void metadata_clicked ();
void reencode_j2k_changed ();
+ void enable_audio_language_toggled ();
+ void edit_audio_language_clicked ();
void setup_frame_rate_widget ();
void setup_container ();
wxTextCtrl* _name;
wxStaticText* _dcp_name;
wxCheckBox* _use_isdcf_name;
+ wxCheckBox* _enable_audio_language = nullptr;
+ wxStaticText* _audio_language = nullptr;
+ Button* _edit_audio_language = nullptr;
wxStaticText* _container_label;
wxChoice* _container;
wxStaticText* _container_size;
auto audio = content_factory("test/data/sine_440.wav").front();
film->examine_and_add_content (audio);
BOOST_REQUIRE (!wait_for_jobs());
- BOOST_REQUIRE (audio->audio);
- audio->audio->set_language(dcp::LanguageTag("en-US"));
+ film->set_audio_language(dcp::LanguageTag("en-US"));
film->set_content_versions({"1"});
film->set_release_territory(dcp::LanguageTag::RegionSubtag("GB"));
film->set_ratings({dcp::Rating("BBFC", "PG")});
BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilm_FTR-1_F_EN-XX_GB-PG_10_2K_ST_20140704_FAC_IOP_OV");
/* Check that specifying no audio language writes XX */
- audio->audio->set_language (boost::none);
+ film->set_audio_language (boost::none);
BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilm_FTR-1_F_XX-XX_GB-PG_10_2K_ST_20140704_FAC_IOP_OV");
/* Test a long name and some different data */
audio = content_factory("test/data/sine_440.wav").front();
film->examine_and_add_content (audio);
BOOST_REQUIRE (!wait_for_jobs());
- BOOST_REQUIRE (audio->audio);
- audio->audio->set_language (dcp::LanguageTag("de-DE"));
+ film->set_audio_language (dcp::LanguageTag("de-DE"));
film->set_interop (false);
BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilmWith_TLR-2_S_DE-fr_US-R_MOS_4K_DI_20140704_PPF_SMPTE_OV");