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
This commit is contained in:
Paul Davis 2015-05-12 14:15:07 -04:00
parent 9ef4888e91
commit 4644e113a8
6 changed files with 124 additions and 4 deletions

View 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 */

View 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)

View 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

View 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()));
}

View 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;
}

View 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;
}