mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
Make source length a dynamic thing.
Update MIDI region length (actually and visually) when position changes. git-svn-id: svn://localhost/ardour2/branches/3.0@4644 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
bed0d89337
commit
c9582da233
28 changed files with 144 additions and 74 deletions
|
|
@ -699,7 +699,7 @@ AudioStreamView::update_rec_regions ()
|
||||||
|
|
||||||
if (nlen != region->length()) {
|
if (nlen != region->length()) {
|
||||||
|
|
||||||
if (region->source(0)->length() >= region->start() + nlen) {
|
if (region->source_length(0) >= region->start() + nlen) {
|
||||||
|
|
||||||
region->freeze ();
|
region->freeze ();
|
||||||
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
||||||
|
|
|
||||||
|
|
@ -732,8 +732,8 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
|
||||||
|
|
||||||
region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
|
region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
|
||||||
|
|
||||||
regions.push_back (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
|
regions.push_back (RegionFactory::create (sources, 0, sources[0]->length(pos), region_name, 0,
|
||||||
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
|
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
|
||||||
|
|
||||||
} else if (target_regions == -1 || target_regions > 1) {
|
} else if (target_regions == -1 || target_regions > 1) {
|
||||||
|
|
||||||
|
|
@ -750,8 +750,8 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
|
||||||
|
|
||||||
region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n);
|
region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n);
|
||||||
|
|
||||||
regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
|
regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(pos), region_name, 0,
|
||||||
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
|
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
|
||||||
|
|
||||||
/* don't do duplicate of the entire source if that's what is going on here */
|
/* don't do duplicate of the entire source if that's what is going on here */
|
||||||
|
|
||||||
if (region->start() == 0 && region->length() == region->source()->length()) {
|
if (region->start() == 0 && region->length() == region->source_length(0)) {
|
||||||
/* XXX should link(2) to create a new inode with "path" */
|
/* XXX should link(2) to create a new inode with "path" */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -989,7 +989,7 @@ Editor::region_list_sorter (TreeModel::iterator a, TreeModel::iterator b)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BySourceFileLength:
|
case BySourceFileLength:
|
||||||
cmp = region1->source()->length() - region2->source()->length();
|
cmp = region1->source_length(0) - region2->source_length(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BySourceFileCreationDate:
|
case BySourceFileCreationDate:
|
||||||
|
|
|
||||||
|
|
@ -685,6 +685,7 @@ MidiRegionView::region_resized (Change what_changed)
|
||||||
RegionView::region_resized(what_changed);
|
RegionView::region_resized(what_changed);
|
||||||
|
|
||||||
if (what_changed & ARDOUR::PositionChanged) {
|
if (what_changed & ARDOUR::PositionChanged) {
|
||||||
|
set_duration(_region->length(), 0);
|
||||||
if (_enable_display) {
|
if (_enable_display) {
|
||||||
redisplay_model();
|
redisplay_model();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -594,7 +594,7 @@ MidiStreamView::update_rec_regions (boost::shared_ptr<MidiModel> data, nframes_t
|
||||||
|
|
||||||
if (nlen != region->length()) {
|
if (nlen != region->length()) {
|
||||||
|
|
||||||
if (region->source(0)->length() >= region->position() + nlen) {
|
if (region->source_length(0) >= region->position() + nlen) {
|
||||||
|
|
||||||
region->freeze ();
|
region->freeze ();
|
||||||
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,9 @@ SoundFileBox::audition ()
|
||||||
|
|
||||||
afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
|
afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
|
||||||
string rname = region_name_from_path (afs->path(), false);
|
string rname = region_name_from_path (afs->path(), false);
|
||||||
r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false));
|
r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0,
|
||||||
|
srclist[0]->length(srclist[0]->timeline_position()),
|
||||||
|
rname, 0, Region::DefaultFlags, false));
|
||||||
|
|
||||||
_session->audition_region(r);
|
_session->audition_region(r);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ Analyser::work ()
|
||||||
|
|
||||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
|
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
|
||||||
|
|
||||||
if (afs && afs->length()) {
|
if (afs && afs->length(afs->timeline_position())) {
|
||||||
analyse_audio_file_source (afs);
|
analyse_audio_file_source (afs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -116,4 +116,3 @@ Analyser::analyse_audio_file_source (boost::shared_ptr<AudioFileSource> src)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,9 @@ class AudioSource : virtual public Source,
|
||||||
|
|
||||||
nframes64_t readable_length() const { return _length; }
|
nframes64_t readable_length() const { return _length; }
|
||||||
uint32_t n_channels() const { return 1; }
|
uint32_t n_channels() const { return 1; }
|
||||||
|
|
||||||
|
sframes_t length (sframes_t pos) const;
|
||||||
|
void update_length (sframes_t pos, sframes_t cnt);
|
||||||
|
|
||||||
virtual nframes_t available_peaks (double zoom) const;
|
virtual nframes_t available_peaks (double zoom) const;
|
||||||
|
|
||||||
|
|
@ -108,6 +111,7 @@ class AudioSource : virtual public Source,
|
||||||
static bool _build_missing_peakfiles;
|
static bool _build_missing_peakfiles;
|
||||||
static bool _build_peakfiles;
|
static bool _build_peakfiles;
|
||||||
|
|
||||||
|
sframes_t _length;
|
||||||
bool _peaks_built;
|
bool _peaks_built;
|
||||||
mutable Glib::Mutex _peaks_ready_lock;
|
mutable Glib::Mutex _peaks_ready_lock;
|
||||||
Glib::ustring peakpath;
|
Glib::ustring peakpath;
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ class Crossfade : public ARDOUR::AudioRegion
|
||||||
AutomationList& fade_in() { return _fade_in; }
|
AutomationList& fade_in() { return _fade_in; }
|
||||||
AutomationList& fade_out() { return _fade_out; }
|
AutomationList& fade_out() { return _fade_out; }
|
||||||
|
|
||||||
nframes_t set_length (nframes_t);
|
nframes_t set_xfade_length (nframes_t);
|
||||||
|
|
||||||
bool is_dependent() const { return true; }
|
bool is_dependent() const { return true; }
|
||||||
bool depends_on (boost::shared_ptr<Region> other) const {
|
bool depends_on (boost::shared_ptr<Region> other) const {
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ class MidiRegion : public Region
|
||||||
|
|
||||||
void recompute_at_start ();
|
void recompute_at_start ();
|
||||||
void recompute_at_end ();
|
void recompute_at_end ();
|
||||||
|
|
||||||
|
void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
|
||||||
|
|
||||||
void switch_source(boost::shared_ptr<Source> source);
|
void switch_source(boost::shared_ptr<Source> source);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,9 @@ class MidiSource : virtual public Source
|
||||||
|
|
||||||
virtual void append_event_unlocked_frames(const Evoral::Event<nframes_t>& ev,
|
virtual void append_event_unlocked_frames(const Evoral::Event<nframes_t>& ev,
|
||||||
sframes_t position) = 0;
|
sframes_t position) = 0;
|
||||||
|
|
||||||
|
virtual sframes_t length (sframes_t pos) const;
|
||||||
|
virtual void update_length (sframes_t pos, sframes_t cnt);
|
||||||
|
|
||||||
virtual void mark_streaming_midi_write_started (NoteMode mode, sframes_t start_time);
|
virtual void mark_streaming_midi_write_started (NoteMode mode, sframes_t start_time);
|
||||||
virtual void mark_streaming_write_started ();
|
virtual void mark_streaming_write_started ();
|
||||||
|
|
@ -118,15 +121,18 @@ class MidiSource : virtual public Source
|
||||||
sframes_t position,
|
sframes_t position,
|
||||||
nframes_t cnt) = 0;
|
nframes_t cnt) = 0;
|
||||||
|
|
||||||
std::string _captured_for;
|
std::string _captured_for;
|
||||||
mutable uint32_t _read_data_count; ///< modified in read()
|
mutable uint32_t _read_data_count; ///< modified in read()
|
||||||
mutable uint32_t _write_data_count; ///< modified in write()
|
mutable uint32_t _write_data_count; ///< modified in write()
|
||||||
|
|
||||||
boost::shared_ptr<MidiModel> _model;
|
boost::shared_ptr<MidiModel> _model;
|
||||||
bool _writing;
|
bool _writing;
|
||||||
|
|
||||||
mutable Evoral::Sequence<double>::const_iterator _model_iter;
|
mutable Evoral::Sequence<double>::const_iterator _model_iter;
|
||||||
mutable sframes_t _last_read_end;
|
|
||||||
|
mutable double _length_beats;
|
||||||
|
mutable sframes_t _last_read_end;
|
||||||
|
sframes_t _last_write_end;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool file_changed (std::string path);
|
bool file_changed (std::string path);
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,8 @@ class Region
|
||||||
nframes_t length() const { return _length; }
|
nframes_t length() const { return _length; }
|
||||||
layer_t layer () const { return _layer; }
|
layer_t layer () const { return _layer; }
|
||||||
|
|
||||||
|
sframes_t source_length(uint32_t n) const;
|
||||||
|
|
||||||
/* these two are valid ONLY during a StateChanged signal handler */
|
/* these two are valid ONLY during a StateChanged signal handler */
|
||||||
|
|
||||||
nframes_t last_position() const { return _last_position; }
|
nframes_t last_position() const { return _last_position; }
|
||||||
|
|
@ -288,7 +290,7 @@ class Region
|
||||||
void send_change (Change);
|
void send_change (Change);
|
||||||
|
|
||||||
void trim_to_internal (nframes_t position, nframes_t length, void *src);
|
void trim_to_internal (nframes_t position, nframes_t length, void *src);
|
||||||
void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
|
virtual void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
|
||||||
|
|
||||||
bool copied() const { return _flags & Copied; }
|
bool copied() const { return _flags & Copied; }
|
||||||
void maybe_uncopy ();
|
void maybe_uncopy ();
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ class Source : public SessionObject, public boost::noncopyable
|
||||||
time_t timestamp() const { return _timestamp; }
|
time_t timestamp() const { return _timestamp; }
|
||||||
void stamp (time_t when) { _timestamp = when; }
|
void stamp (time_t when) { _timestamp = when; }
|
||||||
|
|
||||||
sframes_t length() const { return _length; }
|
virtual sframes_t length (sframes_t pos) const = 0;
|
||||||
|
virtual void update_length (sframes_t pos, sframes_t cnt) = 0;
|
||||||
|
|
||||||
virtual const Glib::ustring& path() const = 0;
|
virtual const Glib::ustring& path() const = 0;
|
||||||
|
|
||||||
|
|
@ -104,10 +105,8 @@ class Source : public SessionObject, public boost::noncopyable
|
||||||
std::string get_transients_path() const;
|
std::string get_transients_path() const;
|
||||||
int load_transients (const std::string&);
|
int load_transients (const std::string&);
|
||||||
|
|
||||||
void update_length (sframes_t pos, sframes_t cnt);
|
sframes_t timeline_position() const { return _timeline_position; }
|
||||||
|
virtual void set_timeline_position (sframes_t pos);
|
||||||
int64_t timeline_position() const { return _timeline_position; }
|
|
||||||
virtual void set_timeline_position (int64_t pos);
|
|
||||||
|
|
||||||
void set_allow_remove_if_empty (bool yn);
|
void set_allow_remove_if_empty (bool yn);
|
||||||
|
|
||||||
|
|
@ -118,8 +117,7 @@ class Source : public SessionObject, public boost::noncopyable
|
||||||
DataType _type;
|
DataType _type;
|
||||||
Flag _flags;
|
Flag _flags;
|
||||||
time_t _timestamp;
|
time_t _timestamp;
|
||||||
sframes_t _length;
|
sframes_t _timeline_position;
|
||||||
int64_t _timeline_position;
|
|
||||||
bool _analysed;
|
bool _analysed;
|
||||||
mutable Glib::Mutex _lock;
|
mutable Glib::Mutex _lock;
|
||||||
mutable Glib::Mutex _analysis_lock;
|
mutable Glib::Mutex _analysis_lock;
|
||||||
|
|
|
||||||
|
|
@ -2373,9 +2373,9 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
|
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
|
||||||
pending_sources, 0, first_fs->length(),
|
pending_sources, 0, first_fs->length(first_fs->timeline_position()),
|
||||||
region_name_from_path (first_fs->name(), true), 0,
|
region_name_from_path (first_fs->name(), true), 0,
|
||||||
Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
|
Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
|
||||||
region->special_set_position (0);
|
region->special_set_position (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2389,7 +2389,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
|
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
|
||||||
pending_sources, 0, first_fs->length(),
|
pending_sources, 0, first_fs->length(first_fs->timeline_position()),
|
||||||
region_name_from_path (first_fs->name(), true)));
|
region_name_from_path (first_fs->name(), true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -897,10 +897,11 @@ AudioTrack::freeze (InterThreadInfo& itt)
|
||||||
|
|
||||||
/* create a new region from all filesources, keep it private */
|
/* create a new region from all filesources, keep it private */
|
||||||
|
|
||||||
boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(),
|
boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0,
|
||||||
region_name, 0,
|
srcs[0]->length(srcs[0]->timeline_position()),
|
||||||
(Region::Flag) (Region::WholeFile|Region::DefaultFlags),
|
region_name, 0,
|
||||||
false));
|
(Region::Flag) (Region::WholeFile|Region::DefaultFlags),
|
||||||
|
false));
|
||||||
|
|
||||||
new_playlist->set_orig_diskstream_id (diskstream->id());
|
new_playlist->set_orig_diskstream_id (diskstream->id());
|
||||||
new_playlist->add_region (region, _session.current_start_frame());
|
new_playlist->add_region (region, _session.current_start_frame());
|
||||||
|
|
|
||||||
|
|
@ -348,14 +348,18 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
|
||||||
nframes_t read_frames, nframes_t skip_frames) const
|
nframes_t read_frames, nframes_t skip_frames) const
|
||||||
{
|
{
|
||||||
/* regular diskstream/butler read complete with fades etc */
|
/* regular diskstream/butler read complete with fades etc */
|
||||||
return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
|
return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
|
||||||
|
file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
|
||||||
}
|
}
|
||||||
|
|
||||||
nframes_t
|
nframes_t
|
||||||
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
|
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
|
||||||
sframes_t position, nframes_t cnt, uint32_t chan_n) const
|
sframes_t position, nframes_t cnt, uint32_t chan_n) const
|
||||||
{
|
{
|
||||||
return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
|
return _read_at (_master_sources,
|
||||||
|
_master_sources.front()->length(_master_sources.front()->timeline_position()),
|
||||||
|
buf, mixdown_buffer, gain_buffer,
|
||||||
|
position, cnt, chan_n, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nframes_t
|
nframes_t
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ bool AudioSource::_build_peakfiles = false;
|
||||||
|
|
||||||
AudioSource::AudioSource (Session& s, ustring name)
|
AudioSource::AudioSource (Session& s, ustring name)
|
||||||
: Source (s, DataType::AUDIO, name)
|
: Source (s, DataType::AUDIO, name)
|
||||||
|
, _length (0)
|
||||||
{
|
{
|
||||||
_peaks_built = false;
|
_peaks_built = false;
|
||||||
_peak_byte_max = 0;
|
_peak_byte_max = 0;
|
||||||
|
|
@ -70,6 +71,7 @@ AudioSource::AudioSource (Session& s, ustring name)
|
||||||
|
|
||||||
AudioSource::AudioSource (Session& s, const XMLNode& node)
|
AudioSource::AudioSource (Session& s, const XMLNode& node)
|
||||||
: Source (s, node)
|
: Source (s, node)
|
||||||
|
, _length (0)
|
||||||
{
|
{
|
||||||
|
|
||||||
_peaks_built = false;
|
_peaks_built = false;
|
||||||
|
|
@ -125,6 +127,21 @@ AudioSource::set_state (const XMLNode& node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sframes_t
|
||||||
|
AudioSource::length (sframes_t pos) const
|
||||||
|
{
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSource::update_length (sframes_t pos, sframes_t cnt)
|
||||||
|
{
|
||||||
|
if (pos + cnt > _length) {
|
||||||
|
_length = pos + cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
PEAK FILE STUFF
|
PEAK FILE STUFF
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
@ -211,7 +228,7 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
|
||||||
|
|
||||||
/* we found it in the peaks dir, so check it out */
|
/* we found it in the peaks dir, so check it out */
|
||||||
|
|
||||||
if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
|
if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) {
|
||||||
// empty
|
// empty
|
||||||
_peaks_built = false;
|
_peaks_built = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -895,10 +912,8 @@ AudioSource::file_changed (ustring path)
|
||||||
nframes_t
|
nframes_t
|
||||||
AudioSource::available_peaks (double zoom_factor) const
|
AudioSource::available_peaks (double zoom_factor) const
|
||||||
{
|
{
|
||||||
off_t end;
|
|
||||||
|
|
||||||
if (zoom_factor < _FPP) {
|
if (zoom_factor < _FPP) {
|
||||||
return length(); // peak data will come from the audio file
|
return length(_timeline_position); // peak data will come from the audio file
|
||||||
}
|
}
|
||||||
|
|
||||||
/* peak data comes from peakfile, but the filesize might not represent
|
/* peak data comes from peakfile, but the filesize might not represent
|
||||||
|
|
@ -907,7 +922,7 @@ AudioSource::available_peaks (double zoom_factor) const
|
||||||
but _peak_byte_max only monotonically increases after initialization.
|
but _peak_byte_max only monotonically increases after initialization.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
end = _peak_byte_max;
|
off_t end = _peak_byte_max;
|
||||||
|
|
||||||
return (end/sizeof(PeakData)) * _FPP;
|
return (end/sizeof(PeakData)) * _FPP;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ Crossfade::Crossfade (boost::shared_ptr<Crossfade> orig, boost::shared_ptr<Audio
|
||||||
layer_relation = (int32_t) (_in->layer() - _out->layer());
|
layer_relation = (int32_t) (_in->layer() - _out->layer());
|
||||||
|
|
||||||
// Let's make sure the fade isn't too long
|
// Let's make sure the fade isn't too long
|
||||||
set_length(_length);
|
set_xfade_length(_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -869,16 +869,16 @@ Crossfade::set_follow_overlap (bool yn)
|
||||||
_follow_overlap = yn;
|
_follow_overlap = yn;
|
||||||
|
|
||||||
if (!yn) {
|
if (!yn) {
|
||||||
set_length (_short_xfade_length);
|
set_xfade_length (_short_xfade_length);
|
||||||
} else {
|
} else {
|
||||||
set_length (_out->first_frame() + _out->length() - _in->first_frame());
|
set_xfade_length (_out->first_frame() + _out->length() - _in->first_frame());
|
||||||
}
|
}
|
||||||
|
|
||||||
StateChanged (FollowOverlapChanged);
|
StateChanged (FollowOverlapChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
nframes_t
|
nframes_t
|
||||||
Crossfade::set_length (nframes_t len)
|
Crossfade::set_xfade_length (nframes_t len)
|
||||||
{
|
{
|
||||||
nframes_t limit = 0;
|
nframes_t limit = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,13 +77,12 @@ FileSource::removable () const
|
||||||
{
|
{
|
||||||
return (_flags & Removable)
|
return (_flags & Removable)
|
||||||
&& ( (_flags & RemoveAtDestroy)
|
&& ( (_flags & RemoveAtDestroy)
|
||||||
|| ((_flags & RemovableIfEmpty) && length() == 0));
|
|| ((_flags & RemovableIfEmpty) && length(timeline_position()) == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
FileSource::init (const ustring& pathstr, bool must_exist)
|
FileSource::init (const ustring& pathstr, bool must_exist)
|
||||||
{
|
{
|
||||||
_length = 0;
|
|
||||||
_timeline_position = 0;
|
_timeline_position = 0;
|
||||||
|
|
||||||
if (!find (_type, pathstr, must_exist, _file_is_new, _channel)) {
|
if (!find (_type, pathstr, must_exist, _file_is_new, _channel)) {
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,19 @@ MidiRegion::~MidiRegion ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiRegion::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
|
||||||
|
{
|
||||||
|
BeatsFramesConverter old_converter(_session, _position - _start);
|
||||||
|
double length_beats = old_converter.from(_length);
|
||||||
|
|
||||||
|
Region::set_position_internal(pos, allow_bbt_recompute);
|
||||||
|
|
||||||
|
BeatsFramesConverter new_converter(_session, pos - _start);
|
||||||
|
|
||||||
|
set_length(new_converter.to(length_beats), 0);
|
||||||
|
}
|
||||||
|
|
||||||
nframes_t
|
nframes_t
|
||||||
MidiRegion::read_at (MidiRingBuffer<nframes_t>& out, sframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
|
MidiRegion::read_at (MidiRingBuffer<nframes_t>& out, sframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,9 @@ MidiSource::MidiSource (Session& s, string name, Source::Flag flags)
|
||||||
, _read_data_count(0)
|
, _read_data_count(0)
|
||||||
, _write_data_count(0)
|
, _write_data_count(0)
|
||||||
, _writing (false)
|
, _writing (false)
|
||||||
|
, _length_beats(0.0)
|
||||||
, _last_read_end(0)
|
, _last_read_end(0)
|
||||||
|
, _last_write_end(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +65,9 @@ MidiSource::MidiSource (Session& s, const XMLNode& node)
|
||||||
, _read_data_count(0)
|
, _read_data_count(0)
|
||||||
, _write_data_count(0)
|
, _write_data_count(0)
|
||||||
, _writing (false)
|
, _writing (false)
|
||||||
|
, _length_beats(0.0)
|
||||||
, _last_read_end(0)
|
, _last_read_end(0)
|
||||||
|
, _last_write_end(0)
|
||||||
{
|
{
|
||||||
_read_data_count = 0;
|
_read_data_count = 0;
|
||||||
_write_data_count = 0;
|
_write_data_count = 0;
|
||||||
|
|
@ -101,6 +105,19 @@ MidiSource::set_state (const XMLNode& node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sframes_t
|
||||||
|
MidiSource::length (sframes_t pos) const
|
||||||
|
{
|
||||||
|
BeatsFramesConverter converter(_session, pos);
|
||||||
|
return converter.to(_length_beats);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiSource::update_length (sframes_t pos, sframes_t cnt)
|
||||||
|
{
|
||||||
|
// You're not the boss of me!
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiSource::invalidate ()
|
MidiSource::invalidate ()
|
||||||
{
|
{
|
||||||
|
|
@ -150,7 +167,9 @@ nframes_t
|
||||||
MidiSource::midi_write (MidiRingBuffer<nframes_t>& dst, sframes_t position, nframes_t cnt)
|
MidiSource::midi_write (MidiRingBuffer<nframes_t>& dst, sframes_t position, nframes_t cnt)
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lm (_lock);
|
Glib::Mutex::Lock lm (_lock);
|
||||||
return write_unlocked (dst, position, cnt);
|
const nframes_t ret = write_unlocked (dst, position, cnt);
|
||||||
|
_last_write_end = position + cnt;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -172,17 +191,21 @@ MidiSource::mark_streaming_midi_write_started (NoteMode mode, sframes_t start_fr
|
||||||
_model->set_note_mode(mode);
|
_model->set_note_mode(mode);
|
||||||
_model->start_write();
|
_model->start_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_last_write_end = start_frame;
|
||||||
_writing = true;
|
_writing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiSource::mark_streaming_write_started ()
|
MidiSource::mark_streaming_write_started ()
|
||||||
{
|
{
|
||||||
|
sframes_t start_frame = _session.transport_frame();
|
||||||
|
|
||||||
if (_model) {
|
if (_model) {
|
||||||
_model->start_write();
|
_model->start_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_last_write_end = start_frame;
|
||||||
_writing = true;
|
_writing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,7 +213,7 @@ void
|
||||||
MidiSource::mark_streaming_write_completed ()
|
MidiSource::mark_streaming_write_completed ()
|
||||||
{
|
{
|
||||||
if (_model) {
|
if (_model) {
|
||||||
_model->end_write(false); // FIXME: param?
|
_model->end_write(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_writing = false;
|
_writing = false;
|
||||||
|
|
|
||||||
|
|
@ -1534,6 +1534,12 @@ Region::source_equivalent (boost::shared_ptr<const Region> other) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sframes_t
|
||||||
|
Region::source_length(uint32_t n) const
|
||||||
|
{
|
||||||
|
return _sources[n]->length(_position - _start);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Region::verify_length (nframes_t len)
|
Region::verify_length (nframes_t len)
|
||||||
{
|
{
|
||||||
|
|
@ -1544,7 +1550,7 @@ Region::verify_length (nframes_t len)
|
||||||
nframes_t maxlen = 0;
|
nframes_t maxlen = 0;
|
||||||
|
|
||||||
for (uint32_t n=0; n < _sources.size(); ++n) {
|
for (uint32_t n=0; n < _sources.size(); ++n) {
|
||||||
maxlen = max (maxlen, (nframes_t)_sources[n]->length() - _start);
|
maxlen = max (maxlen, (nframes_t)source_length(n) - _start);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = min (len, maxlen);
|
len = min (len, maxlen);
|
||||||
|
|
@ -1562,7 +1568,7 @@ Region::verify_start_and_length (nframes_t new_start, nframes_t& new_length)
|
||||||
nframes_t maxlen = 0;
|
nframes_t maxlen = 0;
|
||||||
|
|
||||||
for (uint32_t n=0; n < _sources.size(); ++n) {
|
for (uint32_t n=0; n < _sources.size(); ++n) {
|
||||||
maxlen = max (maxlen, (nframes_t)_sources[n]->length() - new_start);
|
maxlen = max (maxlen, (nframes_t)source_length(n) - new_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_length = min (new_length, maxlen);
|
new_length = min (new_length, maxlen);
|
||||||
|
|
@ -1578,7 +1584,7 @@ Region::verify_start (nframes_t pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t n=0; n < _sources.size(); ++n) {
|
for (uint32_t n=0; n < _sources.size(); ++n) {
|
||||||
if (pos > _sources[n]->length() - _length) {
|
if (pos > source_length(n) - _length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1593,8 +1599,8 @@ Region::verify_start_mutable (nframes_t& new_start)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t n=0; n < _sources.size(); ++n) {
|
for (uint32_t n=0; n < _sources.size(); ++n) {
|
||||||
if (new_start > _sources[n]->length() - _length) {
|
if (new_start > source_length(n) - _length) {
|
||||||
new_start = _sources[n]->length() - _length;
|
new_start = source_length(n) - _length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
|
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
|
||||||
AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(), name, layer, flags);
|
AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(srcs.front()->timeline_position()), name, layer, flags);
|
||||||
boost::shared_ptr<AudioRegion> arp (ar);
|
boost::shared_ptr<AudioRegion> arp (ar);
|
||||||
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
|
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
|
||||||
if (announce) {
|
if (announce) {
|
||||||
|
|
|
||||||
|
|
@ -4087,8 +4087,9 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
|
||||||
|
|
||||||
/* construct a region to represent the bounced material */
|
/* construct a region to represent the bounced material */
|
||||||
|
|
||||||
result = RegionFactory::create (srcs, 0, srcs.front()->length(),
|
result = RegionFactory::create (srcs, 0,
|
||||||
region_name_from_path (srcs.front()->name(), true));
|
srcs.front()->length(srcs.front()->timeline_position()),
|
||||||
|
region_name_from_path (srcs.front()->name(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
||||||
|
|
@ -995,7 +995,7 @@ Session::state(bool full_state)
|
||||||
boost::shared_ptr<AudioFileSource> fs;
|
boost::shared_ptr<AudioFileSource> fs;
|
||||||
if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
|
if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
|
||||||
if (!fs->destructive()) {
|
if (!fs->destructive()) {
|
||||||
if (fs->length() == 0) {
|
if (fs->length(fs->timeline_position()) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2560,7 +2560,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
|
||||||
capture files.
|
capture files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!i->second->used() && i->second->length() > 0) {
|
if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
|
||||||
dead_sources.push_back (i->second);
|
dead_sources.push_back (i->second);
|
||||||
i->second->GoingAway();
|
i->second->GoingAway();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,16 +182,17 @@ SMFSource::write_unlocked (MidiRingBuffer<nframes_t>& src, sframes_t position, n
|
||||||
_model->start_write();
|
_model->start_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
Evoral::MIDIEvent<nframes_t> ev(0, 0.0, 4, NULL, true);
|
Evoral::MIDIEvent<nframes_t> ev;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool ret = src.peek_time(&time);
|
bool ret = src.peek_time(&time);
|
||||||
if (!ret || time - position > _length + dur) {
|
if (!ret || time > _last_write_end + dur) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = src.read_prefix(&time, &type, &size);
|
ret = src.read_prefix(&time, &type, &size);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
cerr << "ERROR: Unable to read event prefix, corrupt MIDI ring buffer" << endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,10 +228,7 @@ SMFSource::write_unlocked (MidiRingBuffer<nframes_t>& src, sframes_t position, n
|
||||||
Evoral::SMF::flush();
|
Evoral::SMF::flush();
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
const sframes_t oldlen = _length;
|
ViewDataRangeReady(position + _last_write_end, dur); /* EMIT SIGNAL */
|
||||||
update_length(oldlen, dur);
|
|
||||||
|
|
||||||
ViewDataRangeReady(position + oldlen, dur); /* EMIT SIGNAL */
|
|
||||||
|
|
||||||
return dur;
|
return dur;
|
||||||
}
|
}
|
||||||
|
|
@ -254,6 +252,8 @@ SMFSource::append_event_unlocked_beats (const Evoral::Event<double>& ev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_length_beats = max(_length_beats, ev.time());
|
||||||
|
|
||||||
const double delta_time_beats = ev.time() - _last_ev_time_beats;
|
const double delta_time_beats = ev.time() - _last_ev_time_beats;
|
||||||
const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn());
|
const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn());
|
||||||
|
|
||||||
|
|
@ -287,6 +287,8 @@ SMFSource::append_event_unlocked_frames (const Evoral::Event<nframes_t>& ev, sfr
|
||||||
|
|
||||||
BeatsFramesConverter converter(_session, position);
|
BeatsFramesConverter converter(_session, position);
|
||||||
|
|
||||||
|
_length_beats = max(_length_beats, converter.from(ev.time()));
|
||||||
|
|
||||||
const sframes_t delta_time_frames = ev.time() - _last_ev_time_frames;
|
const sframes_t delta_time_frames = ev.time() - _last_ev_time_frames;
|
||||||
const double delta_time_beats = converter.from(delta_time_frames);
|
const double delta_time_beats = converter.from(delta_time_frames);
|
||||||
const uint32_t delta_time_ticks = (uint32_t)(lrint(delta_time_beats * (double)ppqn()));
|
const uint32_t delta_time_ticks = (uint32_t)(lrint(delta_time_beats * (double)ppqn()));
|
||||||
|
|
@ -405,6 +407,8 @@ SMFSource::load_model (bool lock, bool force_reload)
|
||||||
scratch_size = ev.size();
|
scratch_size = ev.size();
|
||||||
}
|
}
|
||||||
ev.size() = scratch_size; // ensure read_event only allocates if necessary
|
ev.size() = scratch_size; // ensure read_event only allocates if necessary
|
||||||
|
|
||||||
|
_length_beats = max(_length_beats, ev.time());
|
||||||
}
|
}
|
||||||
|
|
||||||
set_default_controls_interpolation();
|
set_default_controls_interpolation();
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ Source::Source (Session& s, DataType type, const string& name, Flag flags)
|
||||||
{
|
{
|
||||||
_analysed = false;
|
_analysed = false;
|
||||||
_timestamp = 0;
|
_timestamp = 0;
|
||||||
_length = 0;
|
|
||||||
_in_use = 0;
|
_in_use = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +64,6 @@ Source::Source (Session& s, const XMLNode& node)
|
||||||
, _timeline_position(0)
|
, _timeline_position(0)
|
||||||
{
|
{
|
||||||
_timestamp = 0;
|
_timestamp = 0;
|
||||||
_length = 0;
|
|
||||||
_analysed = false;
|
_analysed = false;
|
||||||
_in_use = 0;
|
_in_use = 0;
|
||||||
|
|
||||||
|
|
@ -139,14 +137,6 @@ Source::set_state (const XMLNode& node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Source::update_length (sframes_t pos, sframes_t cnt)
|
|
||||||
{
|
|
||||||
if (pos + cnt > _length) {
|
|
||||||
_length = pos + cnt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Source::add_playlist (boost::shared_ptr<Playlist> pl)
|
Source::add_playlist (boost::shared_ptr<Playlist> pl)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue