introduce the idea of buffering presets, along with 3 possible settings (plus custom).
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 12 May 2015 18:15:07 +0000 (14:15 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 29 Jun 2015 18:18:12 +0000 (14:18 -0400)
Actual numbers for the parameters are still to be determined/verified, and probably subject to
some platform specificity

libs/ardour/ardour/diskstream.h
libs/ardour/ardour/rc_configuration_vars.h
libs/ardour/ardour/types.h
libs/ardour/butler.cc
libs/ardour/diskstream.cc
libs/ardour/enums.cc

index fc41d10160d41f996fcd1b29e968ace16402d6ae..0e82459981d51e255b8ce3c1da361db1df8fca6c 100644 (file)
@@ -147,6 +147,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);
@@ -345,6 +347,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);
 };
 
 }; /* namespace ARDOUR */
index c326b2e888b9444343f31ea66267316c164f5948..10587aba2ed2e96084cb3b9d1ed25901a49a5bb7 100644 (file)
@@ -83,6 +83,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", 5.0)
 CONFIG_VARIABLE (float, audio_playback_buffer_seconds, "playback-buffer-seconds", 5.0)
 CONFIG_VARIABLE (float, midi_track_buffer_seconds, "midi-track-buffer-seconds", 1.0)
index 72ed225486c63211f0d4efcee9c8a0111c9c4356..8d7fb125a186bc4ee304f3267e476bf58ef83f58 100644 (file)
@@ -628,6 +628,13 @@ namespace ARDOUR {
            uint32_t max; //< samples
        };
 
+       enum BufferingPreset {
+               Small,
+               Medium,
+               Large,
+               Custom,
+       };
+
 } // namespace ARDOUR
 
 
@@ -654,6 +661,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& 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::RegionSelectionAfterSplit& 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);
@@ -675,6 +683,7 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::DenormalModel& 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::RegionSelectionAfterSplit& sf);
+std::ostream& operator<<(std::ostream& o, const ARDOUR::BufferingPreset& var);
 
 
 /* because these operators work on types which can be used when making
index 01c21b45d0f6efde499a0942e6448c325c79a04c..2485bc399fa9cf6095381f05ee113674b788a5c7 100644 (file)
@@ -54,7 +54,13 @@ 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));
+       /* 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<void (std::string)> ff (boost::bind (&Butler::config_changed, this, _1));
+       Config->map_parameters (ff);
+       
 }
 
 Butler::~Butler()
@@ -66,12 +72,27 @@ 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 {
+                       std::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 {
+                       std::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 ();
        } else if (p == "midi-readahead") {
                MidiDiskstream::set_readahead_frames ((framecnt_t) (Config->get_midi_readahead() * _session.frame_rate()));
        }
index 5a8f26f17d696ded6808f9731573f7a86981fac8..91859e76a34b2c5168aff9ef743641ac61394418 100644 (file)
@@ -805,3 +805,63 @@ Diskstream::default_disk_write_chunk_frames ()
 {
        return 65536;
 }
+
+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;
+}
+
index 695113bc6f63dd9cab7d4d96209988ae8c2ba16f..6bad2525167f8831ac1552ad5ff1f767c1ec5a1d 100644 (file)
@@ -130,7 +130,8 @@ setup_enum_writer ()
        Session::SlaveState _Session_SlaveState;
        MTC_Status _MIDI_MTC_Status;
        Evoral::OverlapType _OverlapType;
-
+        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)
@@ -659,6 +660,12 @@ setup_enum_writer ()
        REGISTER_ENUM (Evoral::OverlapEnd);
        REGISTER_ENUM (Evoral::OverlapExternal);
        REGISTER(_OverlapType);
+
+       REGISTER_ENUM (Small);
+       REGISTER_ENUM (Medium);
+       REGISTER_ENUM (Large);
+       REGISTER_ENUM (Custom);
+       REGISTER(_BufferingPreset);
 }
 
 } /* namespace ARDOUR */
@@ -1004,3 +1011,17 @@ std::ostream& operator<<(std::ostream& o, const RegionSelectionAfterSplit& 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;
+}