summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorBen Loftis <ben@harrisonconsoles.com>2018-02-11 09:39:36 -0600
committerBen Loftis <ben@harrisonconsoles.com>2018-02-11 09:39:36 -0600
commite6da4c4846cd3097e2393f0e43016b870e7cf592 (patch)
treef54b4f56ab2b39a4c91bb5e6e0141031b8731566 /libs/ardour
parent11e50fe0c5f441f8d017529a62ac4c8eeb6403c2 (diff)
SoloSelection: libardour part.
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/playlist.h7
-rw-r--r--libs/ardour/ardour/region.h4
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/session.h5
-rw-r--r--libs/ardour/audio_playlist.cc5
-rw-r--r--libs/ardour/audioregion.cc14
-rw-r--r--libs/ardour/midi_playlist.cc6
-rw-r--r--libs/ardour/midi_region.cc1
-rw-r--r--libs/ardour/playlist.cc29
-rw-r--r--libs/ardour/region.cc20
-rw-r--r--libs/ardour/route.cc6
-rw-r--r--libs/ardour/session_transport.cc58
12 files changed, 152 insertions, 5 deletions
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 91ddecb711..a8fabd7e65 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -115,6 +115,11 @@ public:
bool frozen() const { return _frozen; }
void set_frozen (bool yn);
+ void AddToSoloSelectedList(const Region*);
+ void RemoveFromSoloSelectedList(const Region*);
+ bool SoloSelectedListIncludes(const Region*);
+ bool SoloSelectedActive();
+
bool hidden() const { return _hidden; }
bool empty() const;
@@ -294,6 +299,8 @@ public:
bool pending_contents_change;
bool pending_layering;
+ std::set<const Region*> _soloSelectedRegions;
+
/** Movements of time ranges caused by region moves; note that
* region trims are not included in this list; it is used to
* do automation-follows-regions.
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index a147a6163a..b536aa16a9 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -113,6 +113,8 @@ public:
samplecnt_t length () const { return _length; }
layer_t layer () const { return _layer; }
+ void set_selected_for_solo(bool yn);
+
samplecnt_t source_length(uint32_t n) const;
uint32_t max_source_level () const;
@@ -413,6 +415,8 @@ protected:
samplepos_t _transient_analysis_start;
samplepos_t _transient_analysis_end;
+ bool _soloSelected;
+
private:
void mid_thaw (const PBD::PropertyChange&);
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 078bf30cb3..138f8a9d71 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -354,6 +354,8 @@ public:
PBD::Signal0<void> denormal_protection_changed;
PBD::Signal0<void> comment_changed;
+ bool is_track();
+
/** track numbers - assigned by session
* nubers > 0 indicate tracks (audio+midi)
* nubers < 0 indicate busses
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index db2d8fdcbe..4cf725ae2f 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -861,6 +861,9 @@ public:
bool solo_isolated() const { return _solo_isolated_cnt > 0; }
void cancel_all_solo ();
+ bool solo_selection_active();
+ void solo_selection( StripableList&, bool );
+
static const SessionEvent::RTeventCallback rt_cleanup;
void clear_all_solo_state (boost::shared_ptr<RouteList>);
@@ -2114,6 +2117,8 @@ private:
void rewire_midi_selection_ports ();
boost::weak_ptr<MidiTrack> current_midi_target;
+ StripableList _soloSelection; //the items that are soloe'd during a solo-selection operation; need to unsolo after the roll
+
CoreSelection* _selection;
bool _global_locate_pending;
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 64d47491d7..329a09eba4 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -211,6 +211,11 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, sa
if ( ar->muted() )
continue;
+ /* check for the case of solo_selection */
+ bool force_transparent = ( _session.solo_selection_active() && SoloSelectedActive() && !SoloSelectedListIncludes( (const Region*) &(**i) ) );
+ if ( force_transparent )
+ continue;
+
/* Work out which bits of this region need to be read;
first, trim to the range we are reading...
*/
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 94b931982a..1f8bbafcbc 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -509,7 +509,11 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
return 0; /* read nothing */
}
-
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (!pl){
+ return 0;
+ }
+
/* COMPUTE DETAILS OF ANY FADES INVOLVED IN THIS READ */
/* Amount (length) of fade in that we are dealing with in this read */
@@ -605,10 +609,12 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
* "buf" contains data from lower regions already. So this operation
* fades out the existing material.
*/
+
+ bool is_opaque = opaque();
if (fade_in_limit != 0) {
- if (opaque()) {
+ if (is_opaque) {
if (_inverse_fade_in) {
/* explicit inverse fade in curve (e.g. for constant
@@ -652,7 +658,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
samplecnt_t const curve_offset = fade_interval_start - (_length - _fade_out->back()->when);
- if (opaque()) {
+ if (is_opaque) {
if (_inverse_fade_out) {
_inverse_fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
@@ -695,7 +701,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
samplecnt_t const N = to_read - fade_in_limit - fade_out_limit;
if (N > 0) {
- if (opaque ()) {
+ if (is_opaque) {
DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("Region %1 memcpy into buf @ %2 + %3, from mixdown buffer @ %4 + %5, len = %6 cnt was %7\n",
name(), buf, fade_in_limit, mixdown_buffer, fade_in_limit, N, cnt));
memcpy (buf + fade_in_limit, mixdown_buffer + fade_in_limit, N * sizeof (Sample));
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 6afde35427..39d964a753 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -134,6 +134,12 @@ MidiPlaylist::read (Evoral::EventSink<samplepos_t>& dst,
std::vector< boost::shared_ptr<Region> > regs;
std::vector< boost::shared_ptr<Region> > ended;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+
+ /* check for the case of solo_selection */
+ bool force_transparent = ( _session.solo_selection_active() && SoloSelectedActive() && !SoloSelectedListIncludes( (const Region*) &(**i) ) );
+ if ( force_transparent )
+ continue;
+
switch ((*i)->coverage (start, end)) {
case Evoral::OverlapStart:
case Evoral::OverlapInternal:
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index ebadc9cd5e..14cd6d80b0 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -39,6 +39,7 @@
#include "ardour/midi_region.h"
#include "ardour/midi_ring_buffer.h"
#include "ardour/midi_source.h"
+#include "ardour/playlist.h"
#include "ardour/region_factory.h"
#include "ardour/session.h"
#include "ardour/source_factory.h"
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index b93ac55326..c3b91f3f45 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1517,6 +1517,35 @@ Playlist::duplicate_ranges (std::list<AudioRange>& ranges, float times)
_splicing = old_sp;
}
+void
+Playlist::AddToSoloSelectedList(const Region* r)
+{
+ _soloSelectedRegions.insert (r);
+}
+
+
+void
+Playlist::RemoveFromSoloSelectedList(const Region* r)
+{
+ _soloSelectedRegions.erase (r);
+}
+
+
+bool
+Playlist::SoloSelectedListIncludes(const Region* r)
+{
+ std::set<const Region*>::iterator i = _soloSelectedRegions.find(r);
+
+ return ( i != _soloSelectedRegions.end() );
+}
+
+bool
+Playlist::SoloSelectedActive()
+{
+ return !_soloSelectedRegions.empty();
+}
+
+
void
Playlist::possibly_splice (samplepos_t at, samplecnt_t distance, boost::shared_ptr<Region> exclude)
{
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 37244c0634..fd7a693128 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -216,6 +216,7 @@ Region::register_properties ()
, _transients (other->_transients) \
, _transient_analysis_start (other->_transient_analysis_start) \
, _transient_analysis_end (other->_transient_analysis_end) \
+ , _soloSelected (false) \
, _muted (Properties::muted, other->_muted) \
, _opaque (Properties::opaque, other->_opaque) \
, _locked (Properties::locked, other->_locked) \
@@ -439,6 +440,25 @@ Region::set_name (const std::string& str)
}
void
+Region::set_selected_for_solo(bool yn)
+{
+ if ( _soloSelected != yn) {
+
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (pl){
+ if (yn) {
+ pl->AddToSoloSelectedList(this);
+ } else {
+ pl->RemoveFromSoloSelectedList(this);
+ }
+ }
+
+ _soloSelected = yn;
+ }
+
+}
+
+void
Region::set_length (samplecnt_t len, const int32_t sub_num)
{
//cerr << "Region::set_length() len = " << len << endl;
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index ee31b2a4e7..2c3c14c940 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -5041,7 +5041,11 @@ Route::the_instrument_unlocked () const
return boost::shared_ptr<Processor>();
}
-
+bool
+Route::is_track()
+{
+ return dynamic_cast<Track*>(this) != 0;
+}
void
Route::non_realtime_locate (samplepos_t pos)
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 10eea5d3bf..59c4e22f16 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -43,6 +43,7 @@
#include "ardour/debug.h"
#include "ardour/disk_reader.h"
#include "ardour/location.h"
+#include "ardour/playlist.h"
#include "ardour/profile.h"
#include "ardour/scene_changer.h"
#include "ardour/session.h"
@@ -267,6 +268,58 @@ Session::request_cancel_play_range ()
}
+bool
+Session::solo_selection_active ()
+{
+ if ( _soloSelection.empty() ) {
+ return false;
+ }
+ return true;
+}
+
+void
+Session::solo_selection ( StripableList &list, bool new_state )
+{
+ boost::shared_ptr<ControlList> solo_list (new ControlList);
+ boost::shared_ptr<ControlList> unsolo_list (new ControlList);
+
+ if (new_state)
+ _soloSelection = list;
+ else
+ _soloSelection.clear();
+
+ boost::shared_ptr<RouteList> rl = get_routes();
+
+ for (ARDOUR::RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+
+ if ( !(*i)->is_track() ) {
+ continue;
+ }
+
+ boost::shared_ptr<Stripable> s (*i);
+
+ bool found = (std::find(list.begin(), list.end(), s) != list.end());
+ if ( new_state && found ) {
+
+ solo_list->push_back (s->solo_control());
+
+ //must invalidate playlists on selected tracks, so only selected regions get heard
+ boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
+ if (track) {
+ boost::shared_ptr<Playlist> playlist = track->playlist();
+ if (playlist) {
+ playlist->ContentsChanged();
+ }
+ }
+ } else {
+ unsolo_list->push_back (s->solo_control());
+ }
+ }
+
+ set_controls (solo_list, 1.0, Controllable::NoGroup);
+ set_controls (unsolo_list, 0.0, Controllable::NoGroup);
+}
+
void
Session::realtime_stop (bool abort, bool clear_state)
{
@@ -312,6 +365,11 @@ Session::realtime_stop (bool abort, bool clear_state)
_clear_event_type (SessionEvent::RangeStop);
_clear_event_type (SessionEvent::RangeLocate);
+ //clear our solo-selection, if there is one
+ if ( solo_selection_active() ) {
+ solo_selection ( _soloSelection, false );
+ }
+
/* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
disable_record (true, (!Config->get_latched_record_enable() && clear_state));