summaryrefslogtreecommitdiff
path: root/libs/ardour/disk_io.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2017-03-03 16:14:07 +0100
committerPaul Davis <paul@linuxaudiosystems.com>2017-09-18 11:40:52 -0400
commit46366541b1aea2c6441b4273734307ab4c55ce13 (patch)
tree6de8d49ec5937d9b4a0386905dbf6d271ec47617 /libs/ardour/disk_io.cc
parent36046cccc1fd40b1d98e7740db8fb398b3928285 (diff)
crawling towards the APIs for separate disk i/o
Diffstat (limited to 'libs/ardour/disk_io.cc')
-rw-r--r--libs/ardour/disk_io.cc205
1 files changed, 205 insertions, 0 deletions
diff --git a/libs/ardour/disk_io.cc b/libs/ardour/disk_io.cc
new file mode 100644
index 0000000000..f75178a5bd
--- /dev/null
+++ b/libs/ardour/disk_io.cc
@@ -0,0 +1,205 @@
+/*
+ Copyright (C) 2009-2016 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "pbd/error.h"
+#include "pbd/i18n.h"
+
+#include "ardour/rc_configuration.h"
+#include "ardour/disk_io.h"
+#include "ardour/disk_reader.h"
+#include "ardour/disk_writer.h"
+#include "ardour/location.h"
+#include "ardour/session.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+using namespace std;
+
+const string DiskIOProcessor::state_node_name = X_("DiskIOProcessor");
+
+// PBD::Signal0<void> DiskIOProcessor::DiskOverrun;
+// PBD::Signal0<void> DiskIOProcessor::DiskUnderrun;
+
+DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
+ : Processor (s, str)
+ , _flags (f)
+ , i_am_the_modifier (false)
+ , _visible_speed (0.0)
+ , _actual_speed (0.0)
+ , _speed (0.0)
+ , _target_speed (0.0)
+ , _buffer_reallocation_required (false)
+ , _seek_required (false)
+ , _slaved (false)
+ , loop_location (0)
+ , in_set_state (false)
+ , wrap_buffer_size (0)
+ , speed_buffer_size (0)
+{
+}
+
+void
+DiskIOProcessor::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;
+ }
+
+ DiskReader::set_chunk_frames (read_chunk_size);
+ DiskWriter::set_chunk_frames (write_chunk_size);
+
+ Config->set_audio_capture_buffer_seconds (write_buffer_size);
+ Config->set_audio_playback_buffer_seconds (read_buffer_size);
+}
+
+bool
+DiskIOProcessor::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;
+}
+
+
+int
+DiskIOProcessor::set_loop (Location *location)
+{
+ if (location) {
+ if (location->start() >= location->end()) {
+ error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
+ return -1;
+ }
+ }
+
+ loop_location = location;
+
+ LoopSet (location); /* EMIT SIGNAL */
+ return 0;
+}
+
+void
+DiskIOProcessor::non_realtime_set_speed ()
+{
+ if (_buffer_reallocation_required)
+ {
+ Glib::Threads::Mutex::Lock lm (state_lock);
+ allocate_temporary_buffers ();
+
+ _buffer_reallocation_required = false;
+ }
+
+ if (_seek_required) {
+ if (speed() != 1.0f || speed() != -1.0f) {
+ seek ((framepos_t) (_session.transport_frame() * (double) speed()), true);
+ }
+ else {
+ seek (_session.transport_frame(), true);
+ }
+
+ _seek_required = false;
+ }
+}
+
+bool
+DiskIOProcessor::realtime_set_speed (double sp, bool global)
+{
+ bool changed = false;
+ double new_speed = sp * _session.transport_speed();
+
+ if (_visible_speed != sp) {
+ _visible_speed = sp;
+ changed = true;
+ }
+
+ if (new_speed != _actual_speed) {
+
+ framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() *
+ fabs (new_speed)) + 2;
+
+ if (required_wrap_size > wrap_buffer_size) {
+ _buffer_reallocation_required = true;
+ }
+
+ _actual_speed = new_speed;
+ _target_speed = fabs(_actual_speed);
+ }
+
+ if (changed) {
+ if (!global) {
+ _seek_required = true;
+ }
+ SpeedChanged (); /* EMIT SIGNAL */
+ }
+
+ return _buffer_reallocation_required || _seek_required;
+}
+
+int
+DiskIOProcessor::set_state (const XMLNode& node, int version)
+{
+ XMLProperty const * prop;
+
+ Processor::set_state (node, version);
+
+ if ((prop = node.property ("flags")) != 0) {
+ _flags = Flag (string_2_enum (prop->value(), _flags));
+ }
+
+ if ((prop = node.property ("speed")) != 0) {
+ double sp = atof (prop->value().c_str());
+
+ if (realtime_set_speed (sp, false)) {
+ non_realtime_set_speed ();
+ }
+ }
+ return 0;
+}