From 92c8b8fae9bb49782258b147e83a8cf3889be76f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 26 Jan 2015 15:13:48 -0500 Subject: [PATCH] introduce the idea of buffering presets, along with 3 possible settings (plus custom). Actual numbers for the parameters are still to be determined/verified, and probably subject to some platform specificity. --- libs/ardour/ardour/diskstream.h | 8 +++ libs/ardour/ardour/rc_configuration_vars.h | 1 + libs/ardour/ardour/types.h | 10 ++++ libs/ardour/audio_diskstream.cc | 2 +- libs/ardour/butler.cc | 25 +++++++-- libs/ardour/diskstream.cc | 59 ++++++++++++++++++++++ libs/ardour/enums.cc | 22 +++++++- system_config | 2 +- 8 files changed, 123 insertions(+), 6 deletions(-) diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index fc8121c70e..8431e06d9d 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -149,6 +149,8 @@ class LIBARDOUR_API Diskstream : public SessionObject, public PublicDiskstream static framecnt_t default_disk_read_chunk_frames (); static framecnt_t default_disk_write_chunk_frames (); + static void set_buffering_parameters (BufferingPreset bp); + /* Stateful */ virtual XMLNode& get_state(void); virtual int set_state(const XMLNode&, int version); @@ -343,6 +345,12 @@ class LIBARDOUR_API Diskstream : public SessionObject, public PublicDiskstream XMLNode* deprecated_io_node; void route_going_away (); + + static bool get_buffering_presets (BufferingPreset bp, + framecnt_t& read_chunk_size, + framecnt_t& read_buffer_size, + framecnt_t& write_chunk_size, + framecnt_t& write_buffer_size); std::string _own_replication_path; virtual int reset_replication_sources () { return 0; } diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 24ebb3aa88..9c9181233b 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -76,6 +76,7 @@ CONFIG_VARIABLE (RemoteModel, remote_model, "remote-model", MixerOrdered) CONFIG_VARIABLE (uint32_t, minimum_disk_read_bytes, "minimum-disk-read-bytes", ARDOUR::Diskstream::default_disk_read_chunk_frames() * sizeof (ARDOUR::Sample)) CONFIG_VARIABLE (uint32_t, minimum_disk_write_bytes, "minimum-disk-write-bytes", ARDOUR::Diskstream::default_disk_write_chunk_frames() * sizeof (ARDOUR::Sample)) CONFIG_VARIABLE (float, midi_readahead, "midi-readahead", 1.0) +CONFIG_VARIABLE (BufferingPreset, buffering_preset, "buffering-preset", Medium) CONFIG_VARIABLE (float, audio_capture_buffer_seconds, "capture-buffer-seconds", 10.0) CONFIG_VARIABLE (float, audio_playback_buffer_seconds, "playback-buffer-seconds", 10.0) CONFIG_VARIABLE (float, midi_track_buffer_seconds, "midi-track-buffer-seconds", 1.0) diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index b46c2dc123..65d2767356 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -605,6 +605,13 @@ namespace ARDOUR { RegionSelectionStart = 0x8, }; + enum BufferingPreset { + Small, + Medium, + Large, + Custom, + }; + } // namespace ARDOUR @@ -635,6 +642,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::WaveformShape& sf); std::istream& operator>>(std::istream& o, ARDOUR::PositionLockStyle& sf); std::istream& operator>>(std::istream& o, ARDOUR::FadeShape& sf); std::istream& operator>>(std::istream& o, ARDOUR::AutoReturnTarget& sf); +std::istream& operator>>(std::istream& o, ARDOUR::BufferingPreset& var); std::ostream& operator<<(std::ostream& o, const ARDOUR::SampleFormat& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf); @@ -659,6 +667,8 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformShape& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::PositionLockStyle& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::FadeShape& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoReturnTarget& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::BufferingPreset& var); + /* because these operators work on types which can be used when making a UI_CONFIG_VARIABLE (in gtk2_ardour) we need them to be exported. diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 8c8ef67178..70de13f59e 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -799,7 +799,7 @@ AudioDiskstream::commit (framecnt_t playback_distance) need_butler = ((framecnt_t) c->front()->capture_buf->read_space() >= disk_write_chunk_frames); } } - + return need_butler; } diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc index 327665441e..cc1d5363b9 100644 --- a/libs/ardour/butler.cc +++ b/libs/ardour/butler.cc @@ -52,7 +52,12 @@ Butler::Butler(Session& s) g_atomic_int_set(&should_do_transport_work, 0); SessionEvent::pool->set_trash (&pool_trash); + /* catch future changes to parameters */ Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Butler::config_changed, this, _1)); + + /* use any current ones that we care about */ + boost::function ff (boost::bind (&Butler::config_changed, this, _1)); + Config->map_parameters (ff); } Butler::~Butler() @@ -64,12 +69,26 @@ 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 (); + if (Config->get_buffering_preset() == Custom) { + /* 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 { + cerr << "Skip explicit buffer seconds, preset in use\n"; + } } else if (p == "capture-buffer-seconds") { + if (Config->get_buffering_preset() == Custom) { + audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * _session.frame_rate()); + _session.adjust_capture_buffering (); + } else { + cerr << "Skip explicit buffer seconds, preset in use\n"; + } + } else if (p == "buffering-preset") { + Diskstream::set_buffering_parameters (Config->get_buffering_preset()); audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * _session.frame_rate()); + audio_dstream_playback_buffer_size = (uint32_t) floor (Config->get_audio_playback_buffer_seconds() * _session.frame_rate()); _session.adjust_capture_buffering (); + _session.adjust_playback_buffering (); } } diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index c96f40b1c4..dd8e2f43d6 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -821,3 +821,62 @@ Diskstream::default_disk_write_chunk_frames () //GZ to Paul Davis FIX-ME restored old value which used to work with current ring buffer capacity return 262144; } + +void +Diskstream::set_buffering_parameters (BufferingPreset bp) +{ + framecnt_t read_chunk_size; + framecnt_t read_buffer_size; + framecnt_t write_chunk_size; + framecnt_t write_buffer_size; + + if (!get_buffering_presets (bp, read_chunk_size, read_buffer_size, write_chunk_size, write_buffer_size)) { + return; + } + + disk_read_chunk_frames = read_chunk_size; + disk_write_chunk_frames = write_chunk_size; + Config->set_audio_capture_buffer_seconds (write_buffer_size); + Config->set_audio_playback_buffer_seconds (read_buffer_size); + + cerr << "Set buffering params to " << disk_read_chunk_frames << '|' << disk_write_chunk_frames << '|' + << Config->get_audio_playback_buffer_seconds() << '|' + << Config->get_audio_capture_buffer_seconds () + << endl; +} + +bool +Diskstream::get_buffering_presets (BufferingPreset bp, + framecnt_t& read_chunk_size, + framecnt_t& read_buffer_size, + framecnt_t& write_chunk_size, + framecnt_t& write_buffer_size) +{ + switch (bp) { + case Small: + read_chunk_size = 65536; /* samples */ + write_chunk_size = 65536; /* samples */ + read_buffer_size = 5; /* seconds */ + write_buffer_size = 5; /* seconds */ + break; + + case Medium: + read_chunk_size = 262144; /* samples */ + write_chunk_size = 131072; /* samples */ + read_buffer_size = 10; /* seconds */ + write_buffer_size = 10; /* seconds */ + break; + + case Large: + read_chunk_size = 524288; /* samples */ + write_chunk_size = 131072; /* samples */ + read_buffer_size = 20; /* seconds */ + write_buffer_size = 20; /* seconds */ + break; + + default: + return false; + } + + return true; +} diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 54368feded..c5b96ec2c3 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -128,7 +128,8 @@ setup_enum_writer () MTC_Status _MIDI_MTC_Status; Evoral::OverlapType _OverlapType; AutoReturnTarget _AutoReturnTarget; - + BufferingPreset _BufferingPreset; + #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear() #define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e) @@ -642,6 +643,11 @@ setup_enum_writer () REGISTER_ENUM (RegionSelectionStart); REGISTER_BITS (_AutoReturnTarget); + REGISTER_ENUM (Small); + REGISTER_ENUM (Medium); + REGISTER_ENUM (Large); + REGISTER_ENUM (Custom); + REGISTER(_BufferingPreset); } } /* namespace ARDOUR */ @@ -973,3 +979,17 @@ std::ostream& operator<<(std::ostream& o, const AutoReturnTarget& var) std::string s = enum_2_string (var); return o << s; } + +std::istream& operator>>(std::istream& o, ARDOUR::BufferingPreset& var) +{ + std::string s; + o >> s; + var = (ARDOUR::BufferingPreset) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const ARDOUR::BufferingPreset& var) +{ + std::string s = enum_2_string (var); + return o << s; +} diff --git a/system_config b/system_config index 26248d354e..be81821afb 100644 --- a/system_config +++ b/system_config @@ -2,7 +2,7 @@ -