set_default_envelope ();
listen_to_my_curves ();
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
}
/** Constructor for use by derived types only */
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
{
init ();
+ assert (_sources.size() == _master_sources.size());
}
/** Basic AudioRegion constructor (one channel) */
}
init ();
+ assert (_sources.size() == _master_sources.size());
}
/* Basic AudioRegion constructor (one channel) */
}
init ();
+ assert (_sources.size() == _master_sources.size());
}
/** Basic AudioRegion constructor (many channels) */
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
{
init ();
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
+ assert (_sources.size() == _master_sources.size());
}
/** Create a new AudioRegion, that is part of an existing one */
, _fade_out (new AutomationList(*other->_fade_out))
, _envelope (new AutomationList(*other->_envelope, offset, offset + length))
{
- set<boost::shared_ptr<Source> > unique_srcs;
-
- for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
- _sources.push_back (*i);
-
- pair<set<boost::shared_ptr<Source> >::iterator,bool> result;
-
- result = unique_srcs.insert (*i);
-
- if (result.second) {
- boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
- if (afs) {
- afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
- }
- }
- }
+ connect_to_header_position_offset_changed ();
/* return to default fades if the existing ones are too long */
assert(_type == DataType::AUDIO);
listen_to_my_curves ();
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
+
+ assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
set_default_fades ();
listen_to_my_curves ();
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
+
+ assert (_sources.size() == _master_sources.size());
}
-AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs,
+AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& /*srcs*/,
nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (other, length, name, layer, flags)
, _automatable (other->session())
{
/* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
- set<boost::shared_ptr<AudioSource> > unique_srcs;
-
- for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
-
- _sources.push_back (*i);
- _master_sources.push_back (*i);
+ for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
if (afs) {
_fade_out_disabled = 0;
listen_to_my_curves ();
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
+
+ assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
}
assert(_type == DataType::AUDIO);
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
+
+ assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
}
assert(_type == DataType::AUDIO);
- listen_to_my_sources ();
+ connect_to_analysis_changed ();
+ assert (_sources.size() == _master_sources.size());
}
AudioRegion::~AudioRegion ()
}
void
-AudioRegion::listen_to_my_sources ()
+AudioRegion::connect_to_analysis_changed ()
{
for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
(*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
}
}
+void
+AudioRegion::connect_to_header_position_offset_changed ()
+{
+ set<boost::shared_ptr<Source> > unique_srcs;
+
+ for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
+
+ if (unique_srcs.find (*i) == unique_srcs.end ()) {
+ unique_srcs.insert (*i);
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
+ if (afs) {
+ afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
+ }
+ }
+ }
+}
+
void
AudioRegion::listen_to_my_curves ()
{
}
nframes_t
-AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
+AudioRegion::_read_at (const SourceList& /*srcs*/, nframes_t limit,
Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
sframes_t position, nframes_t cnt,
uint32_t chan_n,
- nframes_t read_frames,
- nframes_t skip_frames,
+ nframes_t /*read_frames*/,
+ nframes_t /*skip_frames*/,
ReadOps rops) const
{
nframes_t internal_offset;
/* fade in */
- if ((_flags & FadeIn) && Config->get_use_region_fades()) {
+ if ((_flags & FadeIn) && _session.config.get_use_region_fades()) {
nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
/* fade out */
- if ((_flags & FadeOut) && Config->get_use_region_fades()) {
+ if ((_flags & FadeOut) && _session.config.get_use_region_fades()) {
/* see if some part of this read is within the fade out */
_flags = Flag (_flags & ~Region::RightOfSplit);
}
+ /* leave this flag setting in place, no matter what */
+
+ if ((old_flags & DoNotSendPropertyChanges)) {
+ _flags = Flag (_flags | DoNotSendPropertyChanges);
+ }
+
+ /* find out if any flags changed that we signal about */
+
if ((old_flags ^ _flags) & Muted) {
what_changed = Change (what_changed|MuteChanged);
}
void
AudioRegion::set_default_fade_in ()
{
+ _fade_in_disabled = 0;
set_fade_in (Linear, 64);
}
void
AudioRegion::set_default_fade_out ()
{
+ _fade_out_disabled = 0;
set_fade_out (Linear, 64);
}
void
AudioRegion::set_default_fades ()
{
- _fade_in_disabled = 0;
- _fade_out_disabled = 0;
set_default_fade_in ();
set_default_fade_out ();
}
}
int
-AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<Region> >& v) const
+AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
{
SourceList srcs;
string new_name;
}
nframes_t
-AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt) const
+AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt, int channel) const
{
- return audio_source()->read (buf, pos, cnt);
+ return audio_source()->read (buf, pos, cnt, channel);
}
int
-AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
+AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
{
// TODO EXPORT
// const nframes_t blocksize = 4096;
/* read it in */
- if (read_raw_internal (buf, fpos, to_read) != to_read) {
+ if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
return;
}
return 0;
}
+/** Find areas of `silence' within a region.
+ *
+ * @param threshold Threshold below which signal is considered silence (as a sample value)
+ * @param min_length Minimum length of silent period to be reported.
+ * @return Silent periods; first of pair is the offset within the region, second is the length of the period
+ */
+
+std::list<std::pair<nframes_t, nframes_t> >
+AudioRegion::find_silence (Sample threshold, nframes_t min_length) const
+{
+ nframes_t const block_size = 64 * 1024;
+ Sample loudest[block_size];
+ Sample buf[block_size];
+
+ nframes_t pos = _start;
+ nframes_t const end = _start + _length - 1;
+
+ std::list<std::pair<nframes_t, nframes_t> > silent_periods;
+
+ bool in_silence = false;
+ nframes_t silence_start = 0;
+ bool silence;
+
+ while (pos < end) {
+
+ /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
+ memset (loudest, 0, sizeof (Sample) * block_size);
+ for (uint32_t n = 0; n < n_channels(); ++n) {
+
+ read_raw_internal (buf, pos, block_size, n);
+ for (nframes_t i = 0; i < block_size; ++i) {
+ loudest[i] = max (loudest[i], abs (buf[i]));
+ }
+ }
+
+ /* now look for silence */
+ for (nframes_t i = 0; i < block_size; ++i) {
+ silence = abs (loudest[i]) < threshold;
+ if (silence && !in_silence) {
+ /* non-silence to silence */
+ in_silence = true;
+ silence_start = pos + i;
+ } else if (!silence && in_silence) {
+ /* silence to non-silence */
+ in_silence = false;
+ if (pos + i - 1 - silence_start >= min_length) {
+ silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
+ }
+ }
+ }
+
+ pos += block_size;
+ }
+
+ if (in_silence && end - 1 - silence_start >= min_length) {
+ /* last block was silent, so finish off the last period */
+ silent_periods.push_back (std::make_pair (silence_start, end));
+ }
+
+ return silent_periods;
+}
+
+
extern "C" {
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)