27 #include <boost/scoped_array.hpp>
29 #include <glibmm/threads.h>
42 #include "ardour/debug.h"
91 float value = (*it)->value;
92 value = 1 - powf(value,2);
106 for (
int i = 1; i < (num_steps-1); i++) {
108 for (
int j = 0; j < i; j++) {
122 Evoral::ControlList::EventList::size_type size = curve1->
size();
125 if (size != curve2->
size()) {
135 double interp = v1 * ( 1.0-( (double)count / (
double)size) );
136 interp += v2 * ( (double)count / (
double)size );
173 AudioRegion::register_properties ()
190 #define AUDIOREGION_STATE_DEFAULT \
191 _envelope_active (Properties::envelope_active, false) \
192 , _default_fade_in (Properties::default_fade_in, true) \
193 , _default_fade_out (Properties::default_fade_out, true) \
194 , _fade_in_active (Properties::fade_in_active, true) \
195 , _fade_out_active (Properties::fade_out_active, true) \
196 , _scale_amplitude (Properties::scale_amplitude, 1.0) \
197 , _fade_in (Properties::fade_in, boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter (FadeInAutomation)))) \
198 , _inverse_fade_in (Properties::inverse_fade_in, boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter (FadeInAutomation)))) \
199 , _fade_out (Properties::fade_out, boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter (FadeOutAutomation)))) \
200 , _inverse_fade_out (Properties::inverse_fade_out, boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter (FadeOutAutomation))))
202 #define AUDIOREGION_COPY_STATE(other) \
203 _envelope_active (Properties::envelope_active, other->_envelope_active) \
204 , _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
205 , _default_fade_out (Properties::default_fade_out, other->_default_fade_out) \
206 , _fade_in_active (Properties::fade_in_active, other->_fade_in_active) \
207 , _fade_out_active (Properties::fade_out_active, other->_fade_out_active) \
208 , _scale_amplitude (Properties::scale_amplitude, other->_scale_amplitude) \
209 , _fade_in (Properties::fade_in, boost::shared_ptr<AutomationList> (new AutomationList (*other->_fade_in.val()))) \
210 , _inverse_fade_in (Properties::fade_in, boost::shared_ptr<AutomationList> (new AutomationList (*other->_inverse_fade_in.val()))) \
211 , _fade_out (Properties::fade_in, boost::shared_ptr<AutomationList> (new AutomationList (*other->_fade_out.val()))) \
212 , _inverse_fade_out (Properties::fade_in, boost::shared_ptr<AutomationList> (new AutomationList (*other->_inverse_fade_out.val())))
218 register_properties ();
220 suspend_property_changes();
221 set_default_fades ();
222 set_default_envelope ();
223 resume_property_changes();
225 listen_to_my_curves ();
226 connect_to_analysis_changed ();
227 connect_to_header_position_offset_changed ();
236 , _fade_in_suspended (0)
237 , _fade_out_suspended (0)
248 , _automatable(srcs[0]->session())
249 , _fade_in_suspended (0)
250 , _fade_out_suspended (0)
263 , _automatable (other->session())
264 , _fade_in_suspended (0)
265 , _fade_out_suspended (0)
285 , _automatable (other->session())
286 , _fade_in_suspended (0)
287 , _fade_out_suspended (0)
304 , _automatable (other->session())
305 , _fade_in_suspended (0)
306 , _fade_out_suspended (0)
323 , _automatable(srcs[0]->session())
324 , _fade_in_suspended (0)
325 , _fade_out_suspended (0)
370 for (SourceList::const_iterator i =
_sources.begin(); i !=
_sources.end(); ++i) {
378 set<boost::shared_ptr<Source> > unique_srcs;
380 for (SourceList::const_iterator i =
_sources.begin(); i !=
_sources.end(); ++i) {
385 if (unique_srcs.find (*i) == unique_srcs.end ()) {
386 unique_srcs.insert (*i);
427 if (
audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, frames_per_pixel)) {
461 buf, position, cnt, chan_n
476 uint32_t chan_n)
const
499 if (internal_offset >=
_length) {
503 if ((to_read = min (cnt,
_length - internal_offset)) == 0) {
531 if (internal_offset < fade_in_length) {
532 fade_in_limit = min (to_read, fade_in_length - internal_offset);
562 if (fade_interval_end > fade_interval_start) {
564 fade_out_limit = fade_interval_end - fade_interval_start;
565 fade_out_offset = fade_interval_start - internal_offset;
582 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
590 mixdown_buffer[n] *= gain_buffer[n];
604 if (fade_in_limit != 0) {
613 _inverse_fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
616 for (
framecnt_t n = 0; n < fade_in_limit; ++n) {
617 buf[n] *= gain_buffer[n];
622 _fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
630 _fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
632 for (
framecnt_t n = 0; n < fade_in_limit; ++n) {
633 buf[n] *= 1 - gain_buffer[n];
637 _fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
641 for (
framecnt_t n = 0; n < fade_in_limit; ++n) {
642 buf[n] += mixdown_buffer[n] * gain_buffer[n];
646 if (fade_out_limit != 0) {
653 _inverse_fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
656 for (
framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
657 buf[m] *= gain_buffer[n];
662 _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
671 _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
673 for (
framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
674 buf[m] *= 1 - gain_buffer[n];
678 _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
684 for (
framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
685 buf[m] += mixdown_buffer[m] * gain_buffer[n];
691 framecnt_t const N = to_read - fade_in_limit - fade_out_limit;
695 name(), buf, fade_in_limit, mixdown_buffer, fade_in_limit, N, cnt));
696 memcpy (buf + fade_in_limit, mixdown_buffer + fade_in_limit, N *
sizeof (
Sample));
721 if (internal_offset >= limit) {
725 framecnt_t const to_read = min (cnt, limit - internal_offset);
733 if (src->
read (buf,
_start + internal_offset, to_read) != to_read) {
743 if (
Config->get_replicate_missing_region_channels()) {
750 if (src->
read (buf,
_start + internal_offset, to_read) != to_read) {
757 memset (buf, 0,
sizeof (
Sample) * to_read);
771 snprintf (buf,
sizeof (buf),
"%u", (uint32_t)
_sources.size());
786 bool default_env =
false;
845 the_playlist->freeze ();
855 if ((prop = node.
property (
"scale-gain")) != 0) {
873 if (child->
name() ==
"Envelope") {
877 if ((prop = child->
property (
"default")) != 0 ||
_envelope->set_state (*child, version)) {
884 }
else if (child->
name() ==
"FadeIn") {
893 _fade_in->set_state (*grandchild, version);
897 if ((prop = child->
property (
"active")) != 0) {
905 }
else if (child->
name() ==
"FadeOut") {
914 _fade_out->set_state (*grandchild, version);
918 if ((prop = child->
property (
"active")) != 0) {
926 }
else if ( (child->
name() ==
"InverseFadeIn") || (child->
name() ==
"InvFadeIn") ) {
931 }
else if ( (child->
name() ==
"InverseFadeOut") || (child->
name() ==
"InvFadeOut") ) {
947 the_playlist->thaw ();
957 return _set_state (node, version, what_changed,
true);
1023 const int num_steps = 32;
1050 for (
int i = 1; i < num_steps; ++i) {
1051 const float dist = i / (num_steps + 1.f);
1052 _fade_in->fast_simple_add (len * dist, sin (dist * M_PI / 2.0));
1061 _fade_in->fast_simple_add (0.5 * len, 0.6);
1063 const double breakpoint = 0.7;
1064 for (
int i = 2; i < 9; ++i) {
1065 const float coeff = (1.f - breakpoint) * powf (0.5, i);
1105 const int num_steps = 32;
1130 for (
int i = 1; i < num_steps; ++i) {
1131 const float dist = i / (num_steps + 1.f);
1132 _fade_out->fast_simple_add (len * dist, cos (dist * M_PI / 2.0));
1141 _fade_out->fast_simple_add (0.5 * len, 0.6);
1143 const double breakpoint = 0.7;
1144 for (
int i = 2; i < 9; ++i) {
1145 const float coeff = (1.f - breakpoint) * powf (0.5, i);
1337 for (SourceList::const_iterator i =
_sources.begin(); i !=
_sources.end(); ++i) {
1339 srcs.push_back (*i);
1351 new_name += (
'0' + n + 1);
1366 v.back()->set_whole_file (
false);
1411 while (fpos < fend) {
1415 framecnt_t const to_read = min (fend - fpos, blocksize);
1452 target -= FLT_EPSILON;
1460 if (max_amplitude == target) {
1566 (*x) = (*x) + delta;
1578 if ((*x) == old_position) {
1579 (*x) = new_position;
1633 SourceList::iterator s;
1636 if (!(*s)->has_been_analysed()) {
1637 cerr <<
"For " <<
name() <<
" source " << (*s)->name() <<
" has not been analyzed\n";
1649 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1650 (*s)->transients.end(),
1653 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1654 (*s)->transients.end(),
1659 results.insert (results.end(), low, high);
1666 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1679 static bool analyse_dialog_shown =
false;
1681 if (!
Config->get_auto_analyse_audio()) {
1682 if (!analyse_dialog_shown) {
1684 You have requested an operation that requires audio analysis.\n\n\
1685 You currently have \"auto-analyse-audio\" disabled, which means \
1686 that transient data must be generated every time it is required.\n\n\
1687 If you are doing work that will require transient data on a \
1688 regular basis, you should probably enable \"auto-analyse-audio\" \
1689 then quit %1 and restart.\n\n\
1690 This dialog will not display again. But you may notice a slight delay \
1691 in this and future transient-detection operations.\n\
1693 analyse_dialog_shown =
true;
1697 bool existing_results = !results.empty();
1706 for (uint32_t i = 0; i <
n_channels(); ++i) {
1712 if (t.run (
"",
this, i, these_results)) {
1718 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1731 if (!results.empty()) {
1732 if (existing_results) {
1768 boost::scoped_array<Sample> loudest (
new Sample[block_size]);
1769 boost::scoped_array<Sample> buf (
new Sample[block_size]);
1776 bool in_silence =
false;
1779 while (pos < end && !itt.
cancel) {
1782 memset (loudest.get(), 0,
sizeof (
Sample) * block_size);
1783 for (uint32_t n = 0; n <
n_channels(); ++n) {
1786 for (
framecnt_t i = 0; i < block_size; ++i) {
1787 loudest[i] = max (loudest[i], abs (buf[i]));
1792 for (
framecnt_t i = 0; i < block_size; ++i) {
1793 bool const silence = abs (loudest[i]) < threshold;
1794 if (silence && !in_silence) {
1797 silence_start = pos + i;
1798 }
else if (!silence && in_silence) {
1801 if (pos + i - 1 - silence_start >= min_length) {
1802 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1811 if (in_silence && end - 1 - silence_start >= min_length) {
1813 silent_periods.push_back (std::make_pair (silence_start, end));
1818 return silent_periods;
1847 RegionList::iterator i;
1853 for (i = rl->begin(); i != rl->end(); ++i) {
1854 if ((*i).get() !=
this) {
1884 return min (
length(), len);
1898 return min (
length(), min (maxlen, len));
void fade_range(framepos_t, framepos_t)
virtual void resume_property_changes()
AnalysisFeatureList _transients
ARDOUR::Session & _session
LIBARDOUR_API PBD::PropertyDescriptor< bool > default_fade_in
LIBARDOUR_API PBD::PropertyDescriptor< bool > fade_out_active
LIBARDOUR_API PBD::PropertyDescriptor< bool > default_fade_out
virtual framecnt_t read_raw_internal(Sample *, framepos_t, framecnt_t, int channel) const
Evoral::Range< framepos_t > body_range() const
void add_transient(framepos_t where)
PBD::Property< bool > _default_fade_out
void set_fade_out(FadeShape, framecnt_t)
virtual framecnt_t read_peaks(PeakData *buf, framecnt_t npeaks, framecnt_t offset, framecnt_t cnt, uint32_t chan_n=0, double frames_per_pixel=1.0) const
static void cleanup_transients(AnalysisFeatureList &, float sr, float gap_msecs)
void connect_to_analysis_changed()
const std::string & value() const
void set_fade_out_length(framecnt_t)
void recompute_at_start()
LIBARDOUR_API PBD::PropertyDescriptor< layer_t > layer
bool fade_out_is_default() const
Session & session() const
void set_envelope_active(bool yn)
virtual framecnt_t read(Sample *, framepos_t pos, framecnt_t cnt, int channel) const
framepos_t latest_possible_frame() const
PBD::Property< bool > _fade_out_active
AutomationListProperty _inverse_fade_in
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
PBD::Property< gain_t > _scale_amplitude
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
static PBD::Signal1< void, std::string > Dialog
const std::string & name() const
AutomationListProperty _envelope
std::list< std::pair< frameoffset_t, frameoffset_t > > AudioIntervalResult
static void generate_inverse_power_curve(boost::shared_ptr< Evoral::ControlList > dst, boost::shared_ptr< const Evoral::ControlList > src)
uint32_t _fade_out_suspended
int separate_by_channel(ARDOUR::Session &, std::vector< boost::shared_ptr< Region > > &) const
PBD::Property< bool > _default_fade_in
LIBARDOUR_API compute_peak_t compute_peak
PBD::Signal0< void > ContentsChanged
LIBPBD_API Transmitter error
const XMLNodeList & children(const std::string &str=std::string()) const
std::ostream & endmsg(std::ostream &ostr)
LIBARDOUR_API uint64_t AudioPlayback
SessionConfiguration config
PBD::Property< framepos_t > _sync_position
EventList::const_reverse_iterator const_reverse_iterator
boost::shared_ptr< Source > source(uint32_t n=0) const
AudioRegion(boost::shared_ptr< AudioSource >)
AutomationListProperty _inverse_fade_out
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
virtual int _set_state(const XMLNode &, int version, PBD::PropertyChange &what_changed, bool send_signal)
XMLNode * add_child(const char *)
PBD::Property< bool > _left_of_split
bool fade_in_is_default() const
framecnt_t frame_rate() const
static float accurate_coefficient_to_dB(float coeff)
PBD::Property< bool > _valid_transients
std::list< XMLNode * > XMLNodeList
virtual framecnt_t read(Sample *dst, framepos_t start, framecnt_t cnt, int channel=0) const
PBD::Property< bool > _right_of_split
AutomationListProperty _fade_out
void set_fade_out_shape(FadeShape)
void invalidate_transients()
SourceList _master_sources
PBD::Property< framepos_t > _start
void source_offset_changed()
XMLProperty * property(const char *)
LIBARDOUR_API RCConfiguration * Config
static PBD::Signal0< void > HeaderPositionOffsetChanged
void set_position(framepos_t)
double maximum_amplitude(Progress *p=0) const
PBD::Property< bool > _sync_marked
std::list< framepos_t > AnalysisFeatureList
bool string_is_affirmative(const std::string &str)
boost::shared_ptr< RegionList > regions_at(framepos_t frame)
void connect_to_header_position_offset_changed()
PBD::Property< bool > _envelope_active
#define AUDIOREGION_COPY_STATE(other)
boost::shared_ptr< AudioSource > audio_source(uint32_t n=0) const
void set_fade_in_length(framecnt_t)
#define AUDIOREGION_STATE_DEFAULT
std::vector< boost::shared_ptr< Source > > SourceList
void set_fade_in(FadeShape, framecnt_t)
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > fade_out
int adjust_transients(frameoffset_t delta)
Evoral::OverlapType coverage(framepos_t start, framepos_t end) const
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > fade_in
void set_default_fade_out()
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > inverse_fade_in
#define DEBUG_TRACE(bits, str)
int get_transients(AnalysisFeatureList &, bool force_new=false)
void set_fade_out_active(bool yn)
void fast_simple_add(double when, double value)
LIBARDOUR_API void make_property_quarks()
RouteGroup::RouteGroup(Session &s, const string &n) add_property(_relative)
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r)
uint32_t _fade_in_suspended
framepos_t earliest_possible_position() const
EventList::size_type size() const
PBD::Property< std::string > _name
virtual framecnt_t master_read_at(Sample *buf, Sample *mixdown_buf, float *gain_buf, framepos_t position, framecnt_t cnt, uint32_t chan_n=0) const
static void reverse_curve(boost::shared_ptr< Evoral::ControlList > dst, boost::shared_ptr< const Evoral::ControlList > src)
void set_fade_in_shape(FadeShape)
void set_fade_in_active(bool yn)
framecnt_t verify_xfade_bounds(framecnt_t, bool start)
framepos_t position() const
LIBPBD_API uint64_t Properties
framecnt_t read_from_sources(SourceList const &, framecnt_t, Sample *, framepos_t, framecnt_t, uint32_t) const
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > inverse_fade_out
XMLProperty * add_property(const char *name, const std::string &value)
void remove_transient(framepos_t where)
void set_default_fade_in()
boost::shared_ptr< ARDOUR::Region > get_single_other_xfade_region(bool start) const
virtual XMLNode & state()
void add_child_nocopy(XMLNode &)
uint32_t n_channels() const
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
bool speed_mismatch(float) const
void register_properties()
void set_default_envelope()
void set_scale_amplitude(gain_t)
LIBARDOUR_API mix_buffers_no_gain_t mix_buffers_no_gain
void send_change(const PBD::PropertyChange &)
virtual framecnt_t read_at(Sample *buf, Sample *mixdown_buf, float *gain_buf, framepos_t position, framecnt_t cnt, uint32_t chan_n=0) const
EventList::const_iterator const_iterator
static float dB_to_coefficient(float dB)
XMLNode * child(const char *) const
int _set_state(const XMLNode &, int version, PBD::PropertyChange &what_changed, bool send_signal)
int set_transients(AnalysisFeatureList &)
framecnt_t length() const
framepos_t first_frame() const
int set_state(const XMLNode &, int version)
void post_set(const PBD::PropertyChange &)
int update_transient(framepos_t old_position, framepos_t new_position)
AudioIntervalResult find_silence(Sample, framecnt_t, InterThreadInfo &) const
LIBARDOUR_API apply_gain_to_buffer_t apply_gain_to_buffer
static boost::shared_ptr< Region > create(boost::shared_ptr< const Region > other, bool announce=false)
static void merge_curves(boost::shared_ptr< Evoral::ControlList > dst, boost::shared_ptr< const Evoral::ControlList > curve1, boost::shared_ptr< const Evoral::ControlList > curve2)
void normalize(float, float target_in_dB=0.0f)
XMLNodeList::const_iterator XMLNodeConstIterator
LIBARDOUR_API PBD::PropertyDescriptor< float > scale_amplitude
LIBARDOUR_API bool init(bool with_vst, bool try_optimization, const char *localedir)
LIBARDOUR_API PBD::PropertyDescriptor< bool > valid_transients
LIBARDOUR_API PBD::PropertyDescriptor< bool > envelope_active
bool add(PropertyBase *prop)
XMLNode & get_basic_state()
LIBARDOUR_API PBD::PropertyDescriptor< bool > fade_in_active
static void generate_db_fade(boost::shared_ptr< Evoral::ControlList > dst, double len, int num_steps, float dB_drop)
PBD::Property< bool > _fade_in_active
AutomationListProperty _fade_in
std::string string_compose(const std::string &fmt, const T1 &o1)
double atof(const string &s)
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > envelope
boost::shared_ptr< ARDOUR::Playlist > playlist() const
reverse_iterator rbegin()
boost::weak_ptr< ARDOUR::Playlist > _playlist
PBD::Property< framepos_t > _position
void suspend_property_changes()
PBD::Property< framecnt_t > _length
framepos_t last_frame() const
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
bool envelope_active() const
void listen_to_my_curves()