diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index c960e925c8..cde21b209f 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -138,8 +138,12 @@ class LIBARDOUR_API Diskstream : public SessionObject, public PublicDiskstream ChanCount n_channels() { return _n_channels; } - static framecnt_t disk_io_frames() { return disk_io_chunk_frames; } - static void set_disk_io_chunk_frames (framecnt_t n) { disk_io_chunk_frames = n; } + static framecnt_t disk_read_frames() { return disk_read_chunk_frames; } + static framecnt_t disk_write_frames() { return disk_write_chunk_frames; } + static void set_disk_read_chunk_frames (framecnt_t n) { disk_read_chunk_frames = n; } + static void set_disk_write_chunk_frames (framecnt_t n) { disk_write_chunk_frames = n; } + static framecnt_t default_disk_read_chunk_frames (); + static framecnt_t default_disk_write_chunk_frames (); /* Stateful */ virtual XMLNode& get_state(void); @@ -268,7 +272,9 @@ class LIBARDOUR_API Diskstream : public SessionObject, public PublicDiskstream framecnt_t& rec_nframes, framecnt_t& rec_offset ); - static framecnt_t disk_io_chunk_frames; + static framecnt_t disk_read_chunk_frames; + static framecnt_t disk_write_chunk_frames; + std::vector capture_info; mutable Glib::Threads::Mutex capture_info_lock; diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 826175a60b..1c5f9a82b8 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -67,7 +67,8 @@ CONFIG_VARIABLE (RemoteModel, remote_model, "remote-model", MixerOrdered) /* disk operations */ -CONFIG_VARIABLE (uint32_t, minimum_disk_io_bytes, "minimum-disk-io-bytes", 1024 * 256) +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 (float, audio_capture_buffer_seconds, "capture-buffer-seconds", 5.0) CONFIG_VARIABLE (float, audio_playback_buffer_seconds, "playback-buffer-seconds", 5.0) diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index b31e6abe91..d835c4a20f 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -128,9 +128,7 @@ AudioDiskstream::~AudioDiskstream () void AudioDiskstream::allocate_working_buffers() { - assert(disk_io_frames() > 0); - - _working_buffers_size = disk_io_frames(); + _working_buffers_size = max (disk_write_chunk_frames, disk_read_chunk_frames); _mixdown_buffer = new Sample[_working_buffers_size]; _gain_buffer = new gain_t[_working_buffers_size]; } @@ -786,10 +784,10 @@ AudioDiskstream::commit (framecnt_t playback_distance) } } else { if (_io && _io->active()) { - need_butler = ((framecnt_t) c->front()->playback_buf->write_space() >= disk_io_chunk_frames) - || ((framecnt_t) c->front()->capture_buf->read_space() >= disk_io_chunk_frames); + need_butler = ((framecnt_t) c->front()->playback_buf->write_space() >= disk_read_chunk_frames) + || ((framecnt_t) c->front()->capture_buf->read_space() >= disk_write_chunk_frames); } else { - need_butler = ((framecnt_t) c->front()->capture_buf->read_space() >= disk_io_chunk_frames); + need_butler = ((framecnt_t) c->front()->capture_buf->read_space() >= disk_write_chunk_frames); } } @@ -1056,8 +1054,8 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, int AudioDiskstream::do_refill_with_alloc () { - Sample* mix_buf = new Sample[disk_io_chunk_frames]; - float* gain_buf = new float[disk_io_chunk_frames]; + Sample* mix_buf = new Sample[disk_read_chunk_frames]; + float* gain_buf = new float[disk_read_chunk_frames]; int ret = _do_refill(mix_buf, gain_buf); @@ -1108,22 +1106,22 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) for us to be called again, ASAP. */ - if (total_space >= (_slaved ? 3 : 2) * disk_io_chunk_frames) { + if (total_space >= (_slaved ? 3 : 2) * disk_read_chunk_frames) { ret = 1; } /* if we're running close to normal speed and there isn't enough - space to do disk_io_chunk_frames of I/O, then don't bother. + space to do disk_read_chunk_frames of I/O, then don't bother. at higher speeds, just do it because the sync between butler and audio thread may not be good enough. - Note: it is a design assumption that disk_io_chunk_frames is smaller + Note: it is a design assumption that disk_read_chunk_frames is smaller than the playback buffer size, so this check should never trip when the playback buffer is empty. */ - if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) { + if ((total_space < disk_read_chunk_frames) && fabs (_actual_speed) < 2.0f) { return 0; } @@ -1136,9 +1134,9 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) return 0; } - /* never do more than disk_io_chunk_frames worth of disk input per call (limit doesn't apply for memset) */ + /* never do more than disk_read_chunk_frames worth of disk input per call (limit doesn't apply for memset) */ - total_space = min (disk_io_chunk_frames, total_space); + total_space = min (disk_read_chunk_frames, total_space); if (reversed) { @@ -1215,14 +1213,14 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) chan->playback_buf->get_write_vector (&vector); - if ((framecnt_t) vector.len[0] > disk_io_chunk_frames) { + if ((framecnt_t) vector.len[0] > disk_read_chunk_frames) { /* we're not going to fill the first chunk, so certainly do not bother with the other part. it won't be connected with the part we do fill, as in: .... => writable space ++++ => readable space - ^^^^ => 1 x disk_io_chunk_frames that would be filled + ^^^^ => 1 x disk_read_chunk_frames that would be filled |......|+++++++++++++|...............................| buf1 buf0 @@ -1247,7 +1245,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) len2 = vector.len[1]; to_read = min (ts, len1); - to_read = min (to_read, disk_io_chunk_frames); + to_read = min (to_read, disk_read_chunk_frames); assert (to_read >= 0); @@ -1266,7 +1264,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) if (to_read) { - /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data, + /* we read all of vector.len[0], but it wasn't an entire disk_read_chunk_frames of data, so read some or all of vector.len[1] as well. */ @@ -1294,12 +1292,12 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) /** Flush pending data to disk. * - * Important note: this function will write *AT MOST* disk_io_chunk_frames + * Important note: this function will write *AT MOST* disk_write_chunk_frames * of data to disk. it will never write more than that. If it writes that * much and there is more than that waiting to be written, it will return 1, * otherwise 0 on success or -1 on failure. * - * If there is less than disk_io_chunk_frames to be written, no data will be + * If there is less than disk_write_chunk_frames to be written, no data will be * written at all unless @a force_flush is true. */ int @@ -1323,7 +1321,7 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) total = vector.len[0] + vector.len[1]; - if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) { + if (total == 0 || (total < disk_write_chunk_frames && !force_flush && was_recording)) { goto out; } @@ -1338,11 +1336,11 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) let the caller know too. */ - if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) { + if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) { ret = 1; } - to_write = min (disk_io_chunk_frames, (framecnt_t) vector.len[0]); + to_write = min (disk_write_chunk_frames, (framecnt_t) vector.len[0]); // check the transition buffer when recording destructive // important that we get this after the capture buf @@ -1402,14 +1400,14 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) (*chan)->capture_buf->increment_read_ptr (to_write); (*chan)->curr_capture_cnt += to_write; - if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) { + if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_write_chunk_frames) && !destructive()) { /* we wrote all of vector.len[0] but it wasn't an entire - disk_io_chunk_frames of data, so arrange for some part + disk_write_chunk_frames of data, so arrange for some part of vector.len[1] to be flushed to disk as well. */ - to_write = min ((framecnt_t)(disk_io_chunk_frames - to_write), (framecnt_t) vector.len[1]); + to_write = min ((framecnt_t)(disk_write_chunk_frames - to_write), (framecnt_t) vector.len[1]); DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write)); diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 427063c3a2..0e4b5fcc49 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -53,12 +53,8 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -/* XXX This goes uninitialized when there is no ~/.config/ardour3 directory. - * I can't figure out why, so this will do for now (just stole the - * default from configuration_vars.h). 0 is not a good value for - * allocating buffer sizes.. - */ -ARDOUR::framecnt_t Diskstream::disk_io_chunk_frames = 1024 * 256 / sizeof (Sample); +ARDOUR::framecnt_t Diskstream::disk_read_chunk_frames = default_disk_read_chunk_frames (); +ARDOUR::framecnt_t Diskstream::disk_write_chunk_frames = default_disk_write_chunk_frames (); PBD::Signal0 Diskstream::DiskOverrun; PBD::Signal0 Diskstream::DiskUnderrun; @@ -772,3 +768,21 @@ Diskstream::disengage_record_enable () { g_atomic_int_set (&_record_enabled, 0); } + +framecnt_t +Diskstream::default_disk_read_chunk_frames() +{ +#ifdef PLATFORM_WINDOWS + return (2 * 1048576) / sizeof (Sample); +#elif defined __APPLE__ + return (4 * 1048576) / sizeof (Sample); +#else + return 65536; +#endif +} + +framecnt_t +Diskstream::default_disk_write_chunk_frames () +{ + return 65536; +} diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index e1c29fa708..3e04876eb4 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -620,7 +620,7 @@ MidiDiskstream::overwrite_existing_buffers () having the old data or knowing what change caused the overwrite. */ midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame); - read (overwrite_frame, disk_io_chunk_frames, false); + read (overwrite_frame, disk_read_chunk_frames, false); file_frame = overwrite_frame; // it was adjusted by ::read() overwrite_queued = false; _pending_overwrite = false; @@ -810,12 +810,12 @@ MidiDiskstream::do_refill () /** Flush pending data to disk. * - * Important note: this function will write *AT MOST* disk_io_chunk_frames + * Important note: this function will write *AT MOST* disk_write_chunk_frames * of data to disk. it will never write more than that. If it writes that * much and there is more than that waiting to be written, it will return 1, * otherwise 0 on success or -1 on failure. * - * If there is less than disk_io_chunk_frames to be written, no data will be + * If there is less than disk_write_chunk_frames to be written, no data will be * written at all unless @a force_flush is true. */ int @@ -832,7 +832,7 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush) if (total == 0 || _capture_buf->read_space() == 0 || - (!force_flush && (total < disk_io_chunk_frames) && was_recording)) { + (!force_flush && (total < disk_write_chunk_frames) && was_recording)) { goto out; } @@ -847,7 +847,7 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush) let the caller know too. */ - if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) { + if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) { ret = 1; } @@ -855,10 +855,10 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush) /* push out everything we have, right now */ to_write = max_framecnt; } else { - to_write = disk_io_chunk_frames; + to_write = disk_write_chunk_frames; } - if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) { + if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) { Source::Lock lm(_write_source->mutex()); if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) { error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg; diff --git a/libs/ardour/rc_configuration.cc b/libs/ardour/rc_configuration.cc index 840b8f6883..9fdd6aa1ad 100644 --- a/libs/ardour/rc_configuration.cc +++ b/libs/ardour/rc_configuration.cc @@ -235,7 +235,8 @@ RCConfiguration::set_state (const XMLNode& root, int version) } } - Diskstream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample)); + Diskstream::set_disk_read_chunk_frames (minimum_disk_read_bytes.get() / sizeof (Sample)); + Diskstream::set_disk_write_chunk_frames (minimum_disk_write_bytes.get() / sizeof (Sample)); return 0; } @@ -270,3 +271,4 @@ RCConfiguration::map_parameters (boost::function& functor) #undef CONFIG_VARIABLE #undef CONFIG_VARIABLE_SPECIAL } + diff --git a/libs/ardour/srcfilesource.cc b/libs/ardour/srcfilesource.cc index 6af4aaa9d8..e54afbfaba 100644 --- a/libs/ardour/srcfilesource.cc +++ b/libs/ardour/srcfilesource.cc @@ -30,8 +30,7 @@ using namespace ARDOUR; using namespace PBD; -/* see disk_io_chunk_frames */ -const uint32_t SrcFileSource::blocksize = 65536U; +const uint32_t SrcFileSource::blocksize = 65536U; /* somewhat arbitrary */ SrcFileSource::SrcFileSource (Session& s, boost::shared_ptr src, SrcQuality srcq) : Source(s, DataType::AUDIO, src->name(), Flag (src->flags() & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) diff --git a/system_config b/system_config index 4a968428f3..1260a70093 100644 --- a/system_config +++ b/system_config @@ -2,7 +2,6 @@ -