summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-06-09 17:24:07 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-06-09 17:24:07 +0000
commit14004b75a6d18a74fa59ac06c203af693164b774 (patch)
tree1d0d3f416a7c1c1a8d8edd8ff630d87e2b276498 /libs
parent01829e63382ebab3d54b02fffbad11de7cf69ea6 (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
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h6
-rw-r--r--libs/ardour/ardour/butler.h1
-rw-r--r--libs/ardour/ardour/midi_diskstream.h6
-rw-r--r--libs/ardour/ardour/midi_track.h2
-rwxr-xr-xlibs/ardour/ardour/public_diskstream.h2
-rw-r--r--libs/ardour/ardour/session.h11
-rw-r--r--libs/ardour/ardour/session_event.h2
-rw-r--r--libs/ardour/ardour/track.h2
-rw-r--r--libs/ardour/audio_diskstream.cc37
-rw-r--r--libs/ardour/audio_track.cc1
-rw-r--r--libs/ardour/butler.cc15
-rw-r--r--libs/ardour/session_butler.cc30
-rw-r--r--libs/ardour/session_process.cc8
-rw-r--r--libs/ardour/session_transport.cc23
-rw-r--r--libs/ardour/track.cc16
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 ();
+ }
+}