SoloSelection: libardour part.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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&);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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...
|
||||
*/
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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) \
|
||||
@@ -438,6 +439,25 @@ Region::set_name (const std::string& str)
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user