summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-03-24 23:30:08 +0000
committerCarl Hetherington <cth@carlh.net>2015-03-24 23:30:08 +0000
commit86aaba4f392c35ccf28221049f87b8cdba868777 (patch)
tree9809348c4b13f1f8a0d1f3701f829cda50b98db5 /src
parent11d68f1cda11ecf5983451c10a73a37692b025bb (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.cc35
-rw-r--r--src/lib/audio_mapping.h5
-rw-r--r--src/wx/content_menu.cc45
-rw-r--r--src/wx/content_menu.h4
-rw-r--r--src/wx/content_panel.cc4
-rw-r--r--src/wx/timeline.cc15
-rw-r--r--src/wx/timeline.h1
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;