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
This commit is contained in:
parent
01829e6338
commit
14004b75a6
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ class Butler : public SessionHandleRef
|
|||
|
||||
private:
|
||||
void empty_pool_trash ();
|
||||
void config_changed (std::string);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -732,3 +732,4 @@ AudioTrack::write_source (uint32_t n)
|
|||
assert (ds);
|
||||
return ds->write_source (n);
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -66,6 +66,36 @@ static inline uint32_t next_power_of_two (uint32_t n)
|
|||
BUTLER THREAD
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
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 ()
|
||||
{
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue