diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-03-24 23:30:08 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-03-24 23:30:08 +0000 |
| commit | 86aaba4f392c35ccf28221049f87b8cdba868777 (patch) | |
| tree | 9809348c4b13f1f8a0d1f3701f829cda50b98db5 /src | |
| parent | 11d68f1cda11ecf5983451c10a73a37692b025bb (diff) | |
Hand-apply a2f81da6d9afc5d3b5e647e1e05ca5d4507af42c from master;
allow "deletion" of the audio part of a FFmpeg file from the
timeline; delete unmaps the audio (#316).
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/audio_mapping.cc | 35 | ||||
| -rw-r--r-- | src/lib/audio_mapping.h | 5 | ||||
| -rw-r--r-- | src/wx/content_menu.cc | 45 | ||||
| -rw-r--r-- | src/wx/content_menu.h | 4 | ||||
| -rw-r--r-- | src/wx/content_panel.cc | 4 | ||||
| -rw-r--r-- | src/wx/timeline.cc | 15 | ||||
| -rw-r--r-- | src/wx/timeline.h | 1 |
7 files changed, 99 insertions, 10 deletions
diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 5b3e36f25..35e4c036c 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2015 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 @@ -30,6 +30,7 @@ using std::make_pair; using std::pair; using std::string; using std::min; +using std::vector; using boost::shared_ptr; using boost::dynamic_pointer_cast; using dcp::raw_convert; @@ -144,3 +145,35 @@ AudioMapping::digest () const return digester.get (); } + +list<dcp::Channel> +AudioMapping::mapped_dcp_channels () const +{ + static float const minus_96_db = 0.000015849; + + list<dcp::Channel> mapped; + + for (vector<vector<float> >::const_iterator i = _gain.begin(); i != _gain.end(); ++i) { + for (size_t j = 0; j < i->size(); ++j) { + if (abs ((*i)[j]) > minus_96_db) { + mapped.push_back ((dcp::Channel) j); + } + } + } + + mapped.sort (); + mapped.unique (); + + return mapped; +} + +void +AudioMapping::unmap_all () +{ + for (vector<vector<float> >::iterator i = _gain.begin(); i != _gain.end(); ++i) { + for (vector<float>::iterator j = i->begin(); j != i->end(); ++j) { + *j = 0; + } + } +} + diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index fdb23df8b..bac2b10b0 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2015 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 @@ -65,6 +65,9 @@ public: } std::string digest () const; + + std::list<dcp::Channel> mapped_dcp_channels () const; + void unmap_all (); private: void setup (int); diff --git a/src/wx/content_menu.cc b/src/wx/content_menu.cc index 749337b75..23767bbe7 100644 --- a/src/wx/content_menu.cc +++ b/src/wx/content_menu.cc @@ -30,6 +30,8 @@ #include "content_menu.h" #include "repeat_dialog.h" #include "wx_util.h" +#include "timeline_video_content_view.h" +#include "timeline_audio_content_view.h" using std::cout; using std::vector; @@ -72,10 +74,11 @@ ContentMenu::~ContentMenu () } void -ContentMenu::popup (weak_ptr<Film> f, ContentList c, wxPoint p) +ContentMenu::popup (weak_ptr<Film> f, ContentList c, TimelineContentViewList v, wxPoint p) { _film = f; _content = c; + _views = v; _repeat->Enable (!_content.empty ()); int n = 0; @@ -123,6 +126,7 @@ ContentMenu::repeat () d->Destroy (); _content.clear (); + _views.clear (); } void @@ -166,9 +170,46 @@ ContentMenu::remove () return; } - film->playlist()->remove (_content); + /* We are removing from the timeline if _views is not empty */ + bool handled = false; + if (!_views.empty ()) { + /* Special case: we only remove FFmpegContent if its video view is selected; + if not, and its audio view is selected, we unmap the audio. + */ + for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { + shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i); + if (!fc) { + continue; + } + + shared_ptr<TimelineVideoContentView> video; + shared_ptr<TimelineAudioContentView> audio; + + for (TimelineContentViewList::iterator i = _views.begin(); i != _views.end(); ++i) { + shared_ptr<TimelineVideoContentView> v = dynamic_pointer_cast<TimelineVideoContentView> (*i); + shared_ptr<TimelineAudioContentView> a = dynamic_pointer_cast<TimelineAudioContentView> (*i); + if (v && v->content() == fc) { + video = v; + } else if (a && a->content() == fc) { + audio = a; + } + } + + if (!video && audio) { + AudioMapping m = fc->audio_mapping (); + m.unmap_all (); + fc->set_audio_mapping (m); + handled = true; + } + } + } + + if (!handled) { + film->playlist()->remove (_content); + } _content.clear (); + _views.clear (); } void diff --git a/src/wx/content_menu.h b/src/wx/content_menu.h index 996091f0c..5f2a7f7b6 100644 --- a/src/wx/content_menu.h +++ b/src/wx/content_menu.h @@ -23,6 +23,7 @@ #include <wx/wx.h> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> +#include "timeline_content_view.h" #include "lib/types.h" class Film; @@ -33,7 +34,7 @@ public: ContentMenu (wxWindow* p); ~ContentMenu (); - void popup (boost::weak_ptr<Film>, ContentList, wxPoint); + void popup (boost::weak_ptr<Film>, ContentList, TimelineContentViewList, wxPoint); private: void repeat (); @@ -49,6 +50,7 @@ private: boost::weak_ptr<Film> _film; wxWindow* _parent; ContentList _content; + TimelineContentViewList _views; wxMenuItem* _repeat; wxMenuItem* _join; wxMenuItem* _find_missing; diff --git a/src/wx/content_panel.cc b/src/wx/content_panel.cc index 8bcf46f5c..30c03538b 100644 --- a/src/wx/content_panel.cc +++ b/src/wx/content_panel.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2015 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 @@ -335,7 +335,7 @@ ContentPanel::timeline_clicked () void ContentPanel::right_click (wxListEvent& ev) { - _menu->popup (_film, selected (), ev.GetPoint ()); + _menu->popup (_film, selected (), TimelineContentViewList (), ev.GetPoint ()); } /** Set up broad sensitivity based on the type of content that is selected */ diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 6ed91e098..2c032b8d3 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -93,7 +93,12 @@ void Timeline::playlist_changed () { ensure_ui_thread (); - + recreate_views (); +} + +void +Timeline::recreate_views () +{ shared_ptr<const Film> fl = _film.lock (); if (!fl) { return; @@ -108,7 +113,9 @@ Timeline::playlist_changed () if (dynamic_pointer_cast<VideoContent> (*i)) { _views.push_back (shared_ptr<TimelineView> (new TimelineVideoContentView (*this, *i))); } - if (dynamic_pointer_cast<AudioContent> (*i)) { + + shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (*i); + if (ac && !ac->audio_mapping().mapped_dcp_channels().empty ()) { _views.push_back (shared_ptr<TimelineView> (new TimelineAudioContentView (*this, *i))); } @@ -132,6 +139,8 @@ Timeline::playlist_content_changed (int property) assign_tracks (); setup_pixels_per_second (); Refresh (); + } else if (property == AudioContentProperty::AUDIO_MAPPING) { + recreate_views (); } } @@ -303,7 +312,7 @@ Timeline::right_down (wxMouseEvent& ev) cv->set_selected (true); } - _menu.popup (_film, selected_content (), ev.GetPosition ()); + _menu.popup (_film, selected_content (), selected_views (), ev.GetPosition ()); } void diff --git a/src/wx/timeline.h b/src/wx/timeline.h index 66f982c4a..cab0ea0e0 100644 --- a/src/wx/timeline.h +++ b/src/wx/timeline.h @@ -84,6 +84,7 @@ private: void assign_tracks (); void set_position_from_event (wxMouseEvent &); void clear_selection (); + void recreate_views (); boost::shared_ptr<TimelineView> event_to_view (wxMouseEvent &); TimelineContentViewList selected_views () const; |
