diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2010-06-09 17:24:07 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2010-06-09 17:24:07 +0000 |
commit | 14004b75a6d18a74fa59ac06c203af693164b774 (patch) | |
tree | 1d0d3f416a7c1c1a8d8edd8ff630d87e2b276498 | |
parent | 01829e63382ebab3d54b02fffbad11de7cf69ea6 (diff) |
dynamic playback & capture buffer resizing (though transport is stopped first)
git-svn-id: svn://localhost/ardour2/branches/3.0@7250 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/ardour/ardour/audio_diskstream.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/butler.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_diskstream.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_track.h | 2 | ||||
-rwxr-xr-x | libs/ardour/ardour/public_diskstream.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/session_event.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/track.h | 2 | ||||
-rw-r--r-- | libs/ardour/audio_diskstream.cc | 37 | ||||
-rw-r--r-- | libs/ardour/audio_track.cc | 1 | ||||
-rw-r--r-- | libs/ardour/butler.cc | 15 | ||||
-rw-r--r-- | libs/ardour/session_butler.cc | 30 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 8 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 23 | ||||
-rw-r--r-- | libs/ardour/track.cc | 16 |
15 files changed, 159 insertions, 3 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 0ab9231252..54ddbea14a 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -216,6 +216,9 @@ class AudioDiskstream : public Diskstream RingBufferNPT<CaptureTransition> * capture_transition_buf; // the following are used in the butler thread only nframes_t curr_capture_cnt; + + void resize_playback (nframes_t); + void resize_capture (nframes_t); }; typedef std::vector<ChannelInfo*> ChannelList; @@ -255,6 +258,9 @@ class AudioDiskstream : public Diskstream void setup_destructive_playlist (); void use_destructive_playlist (); + void adjust_playback_buffering (); + void adjust_capture_buffering (); + void engage_record_enable (); void disengage_record_enable (); diff --git a/libs/ardour/ardour/butler.h b/libs/ardour/ardour/butler.h index fc8e4c18c3..6ad96dc704 100644 --- a/libs/ardour/ardour/butler.h +++ b/libs/ardour/ardour/butler.h @@ -83,6 +83,7 @@ class Butler : public SessionHandleRef private: void empty_pool_trash (); + void config_changed (std::string); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 766f9ec5a5..f466889027 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -165,6 +165,12 @@ class MidiDiskstream : public Diskstream void get_input_sources (); void set_align_style_from_io(); + /* fixed size buffers per instance of ardour for now (non-dynamic) + */ + + void adjust_playback_buffering () {} + void adjust_capture_buffering () {} + void engage_record_enable (); void disengage_record_enable (); diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 5d5bdc0cb4..d181bea596 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -53,7 +53,7 @@ public: void freeze_me (InterThreadInfo&); void unfreeze (); - + boost::shared_ptr<Region> bounce (InterThreadInfo&); boost::shared_ptr<Region> bounce_range ( nframes_t start, nframes_t end, InterThreadInfo&, bool enable_processing); diff --git a/libs/ardour/ardour/public_diskstream.h b/libs/ardour/ardour/public_diskstream.h index 90ca030af1..c31e88a79b 100755 --- a/libs/ardour/ardour/public_diskstream.h +++ b/libs/ardour/ardour/public_diskstream.h @@ -72,6 +72,8 @@ public: virtual void set_align_style (AlignStyle) = 0; virtual int use_copy_playlist () = 0; virtual int use_new_playlist () = 0; + virtual void adjust_playback_buffering () = 0; + virtual void adjust_capture_buffering () = 0; }; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index d1362b379a..f7692e09cb 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -299,6 +299,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void allow_auto_play (bool yn); void request_transport_speed (double speed); void request_overwrite_buffer (Track *); + void adjust_playback_buffering(); + void adjust_capture_buffering(); void request_track_speed (Track *, double speed); void request_input_change_handling (); @@ -776,7 +778,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi PostTransportReverse = 0x10000, PostTransportInputChange = 0x20000, PostTransportCurveRealloc = 0x40000, - PostTransportClearSubstate = 0x80000 + PostTransportClearSubstate = 0x80000, + PostTransportAdjustPlaybackBuffering = 0x100000, + PostTransportAdjustCaptureBuffering = 0x200000 }; enum SlaveState { @@ -1028,6 +1032,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void set_post_transport_work (PostTransportWork ptw) { g_atomic_int_set (&_post_transport_work, (gint) ptw); } void add_post_transport_work (PostTransportWork ptw); + void schedule_playback_buffering_adjustment (); + void schedule_capture_buffering_adjustment (); + uint32_t cumulative_rf_motion; uint32_t rf_scale; @@ -1437,6 +1444,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X; void add_session_range_location (nframes_t, nframes_t); + + }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/session_event.h b/libs/ardour/ardour/session_event.h index 726c5be47b..eac27be7f6 100644 --- a/libs/ardour/ardour/session_event.h +++ b/libs/ardour/ardour/session_event.h @@ -34,6 +34,8 @@ struct SessionEvent { InputConfigurationChange, SetPlayAudioRange, RealTimeOperation, + AdjustPlaybackBuffering, + AdjustCaptureBuffering, /* only one of each of these events can be queued at any one time */ diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index a40b82916b..ac948f12df 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -138,6 +138,8 @@ class Track : public Route, public PublicDiskstream void set_align_style (AlignStyle); int use_copy_playlist (); int use_new_playlist (); + void adjust_playback_buffering (); + void adjust_capture_buffering (); PBD::Signal0<void> DiskstreamChanged; PBD::Signal0<void> FreezeChange; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index d864d86cf8..b3204c38b6 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -2297,6 +2297,26 @@ AudioDiskstream::can_become_destructive (bool& requires_bounce) const return true; } +void +AudioDiskstream::adjust_playback_buffering () +{ + boost::shared_ptr<ChannelList> c = channels.reader(); + + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + (*chan)->resize_playback (_session.butler()->audio_diskstream_playback_buffer_size()); + } +} + +void +AudioDiskstream::adjust_capture_buffering () +{ + boost::shared_ptr<ChannelList> c = channels.reader(); + + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + (*chan)->resize_capture (_session.butler()->audio_diskstream_capture_buffer_size()); + } +} + AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t playback_bufsize, nframes_t capture_bufsize, nframes_t speed_size, nframes_t wrap_size) { peak_power = 0.0f; @@ -2324,6 +2344,22 @@ AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t playback_bufsize, nframes_t memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize()); } +void +AudioDiskstream::ChannelInfo::resize_playback (nframes_t playback_bufsize) +{ + delete playback_buf; + playback_buf = new RingBufferNPT<Sample> (playback_bufsize); + memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize()); +} + +void +AudioDiskstream::ChannelInfo::resize_capture (nframes_t capture_bufsize) +{ + delete capture_buf; + capture_buf = new RingBufferNPT<Sample> (capture_bufsize); + memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize()); +} + AudioDiskstream::ChannelInfo::~ChannelInfo () { write_source.reset (); @@ -2346,3 +2382,4 @@ AudioDiskstream::ChannelInfo::~ChannelInfo () delete capture_transition_buf; capture_transition_buf = 0; } + diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index fcd211375a..fcc6da2ad0 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -732,3 +732,4 @@ AudioTrack::write_source (uint32_t n) assert (ds); return ds->write_source (n); } + diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc index 1eb96dea35..1efca35196 100644 --- a/libs/ardour/butler.cc +++ b/libs/ardour/butler.cc @@ -50,6 +50,8 @@ Butler::Butler(Session& s) { g_atomic_int_set(&should_do_transport_work, 0); SessionEvent::pool->set_trash (&pool_trash); + + Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Butler::config_changed, this, _1)); } Butler::~Butler() @@ -57,6 +59,19 @@ Butler::~Butler() terminate_thread (); } +void +Butler::config_changed (std::string p) +{ + if (p == "playback-buffer-seconds") { + /* size is in Samples, not bytes */ + audio_dstream_playback_buffer_size = (uint32_t) floor (Config->get_audio_playback_buffer_seconds() * _session.frame_rate()); + _session.adjust_playback_buffering (); + } else if (p == "capture-buffer-seconds") { + audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * _session.frame_rate()); + _session.adjust_capture_buffering (); + } +} + int Butler::start_thread() { diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index 7cbbd194ae..c92c0604c7 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -67,6 +67,36 @@ static inline uint32_t next_power_of_two (uint32_t n) ---------------------------------------------------------------------------*/ void +Session::adjust_playback_buffering () +{ + request_stop (false, false); + SessionEvent *ev = new SessionEvent (SessionEvent::AdjustPlaybackBuffering, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0); + queue_event (ev); +} + +void +Session::adjust_capture_buffering () +{ + request_stop (false, false); + SessionEvent *ev = new SessionEvent (SessionEvent::AdjustCaptureBuffering, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0); + queue_event (ev); +} + +void +Session::schedule_playback_buffering_adjustment () +{ + add_post_transport_work (PostTransportAdjustPlaybackBuffering); + _butler->schedule_transport_work (); +} + +void +Session::schedule_capture_buffering_adjustment () +{ + add_post_transport_work (PostTransportAdjustCaptureBuffering); + _butler->schedule_transport_work (); +} + +void Session::schedule_curve_reallocation () { add_post_transport_work (PostTransportCurveRealloc); diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 9549227933..79b1953ea8 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -1091,6 +1091,14 @@ Session::process_event (SessionEvent* ev) del = false; // other side of RT request needs to clean up break; + case SessionEvent::AdjustPlaybackBuffering: + schedule_playback_buffering_adjustment (); + break; + + case SessionEvent::AdjustCaptureBuffering: + schedule_capture_buffering_adjustment (); + break; + default: fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg; /*NOTREACHED*/ diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 898af1fb59..e6ff844404 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -260,7 +260,28 @@ Session::butler_transport_work () ptw = post_transport_work(); DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw))); - + + if (ptw & PostTransportAdjustPlaybackBuffering) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i); + if (tr) { + tr->adjust_playback_buffering (); + /* and refill those buffers ... */ + tr->non_realtime_locate (_transport_frame); + } + } + + } + + if (ptw & PostTransportAdjustCaptureBuffering) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i); + if (tr) { + tr->adjust_capture_buffering (); + } + } + } + if (ptw & PostTransportCurveRealloc) { for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->curve_reallocate(); diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 870936ad77..ad4c765867 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -665,3 +665,19 @@ Track::set_block_size (nframes_t n) Route::set_block_size (n); _diskstream->set_block_size (n); } + +void +Track::adjust_playback_buffering () +{ + if (_diskstream) { + _diskstream->adjust_playback_buffering (); + } +} + +void +Track::adjust_capture_buffering () +{ + if (_diskstream) { + _diskstream->adjust_capture_buffering (); + } +} |