rename TransportMasterManager::init() to ::set_default_configuration() to make its...
[ardour.git] / libs / ardour / disk_io.cc
index 587ba19ed05a79c1cfaba85ba02ec9ff9aa85b27..427f3644041db6ceec5e5858835c89a2beb74b9c 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "pbd/debug.h"
 #include "pbd/error.h"
-#include "pbd/i18n.h"
 
 #include "ardour/audioplaylist.h"
 #include "ardour/butler.h"
@@ -36,6 +35,8 @@
 #include "ardour/session.h"
 #include "ardour/session_playlists.h"
 
+#include "pbd/i18n.h"
+
 using namespace ARDOUR;
 using namespace PBD;
 using namespace std;
@@ -49,24 +50,35 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
        : Processor (s, str)
        , _flags (f)
        , i_am_the_modifier (false)
-       , _buffer_reallocation_required (false)
-       , _seek_required (false)
        , _slaved (false)
-       , loop_location (0)
        , in_set_state (false)
-        , file_frame (0)
-        , playback_sample (0)
-        , wrap_buffer_size (0)
-        , speed_buffer_size (0)
+       , playback_sample (0)
        , _need_butler (false)
        , channels (new ChannelList)
-       , _midi_buf (new MidiRingBuffer<framepos_t> (s.butler()->midi_diskstream_buffer_size()))
-       , _frames_written_to_ringbuffer (0)
-       , _frames_read_from_ringbuffer (0)
+       , _midi_buf (new MidiRingBuffer<samplepos_t> (s.butler()->midi_diskstream_buffer_size()))
+       , _samples_written_to_ringbuffer (0)
+       , _samples_read_from_ringbuffer (0)
 {
-       midi_interpolation.add_channel_to (0,0);
+       set_display_to_user (false);
+}
+
+DiskIOProcessor::~DiskIOProcessor ()
+{
+       {
+               RCUWriter<ChannelList> writer (channels);
+               boost::shared_ptr<ChannelList> c = writer.get_copy();
+
+               for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
+                       delete *chan;
+               }
+
+               c->clear();
+       }
+
+       channels.flush ();
 }
 
+
 void
 DiskIOProcessor::init ()
 {
@@ -76,17 +88,17 @@ DiskIOProcessor::init ()
 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;
+       samplecnt_t read_chunk_size;
+       samplecnt_t read_buffer_size;
+       samplecnt_t write_chunk_size;
+       samplecnt_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);
+       DiskReader::set_chunk_samples (read_chunk_size);
+       DiskWriter::set_chunk_samples (write_chunk_size);
 
        Config->set_audio_capture_buffer_seconds (write_buffer_size);
        Config->set_audio_playback_buffer_seconds (read_buffer_size);
@@ -94,10 +106,10 @@ DiskIOProcessor::set_buffering_parameters (BufferingPreset bp)
 
 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)
+                                        samplecnt_t& read_chunk_size,
+                                        samplecnt_t& read_buffer_size,
+                                        samplecnt_t& write_chunk_size,
+                                        samplecnt_t& write_buffer_size)
 {
        switch (bp) {
        case Small:
@@ -136,10 +148,8 @@ DiskIOProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& o
                return false;
        }
 
-       if (in != out) {
-               /* currently no way to deliver different channels that we receive */
-               return false;
-       }
+       /* currently no way to deliver different channels that we receive */
+       out = in;
 
        return true;
 }
@@ -149,24 +159,34 @@ DiskIOProcessor::configure_io (ChanCount in, ChanCount out)
 {
        DEBUG_TRACE (DEBUG::DiskIO, string_compose ("Configuring %1 for in:%2 out:%3\n", name(), in, out));
 
-       RCUWriter<ChannelList> writer (channels);
-       boost::shared_ptr<ChannelList> c = writer.get_copy();
+       bool changed = false;
 
-       uint32_t n_audio = in.n_audio();
+       {
+               RCUWriter<ChannelList> writer (channels);
+               boost::shared_ptr<ChannelList> c = writer.get_copy();
 
-       if (n_audio > c->size()) {
-               add_channel_to (c, n_audio - c->size());
-       } else if (n_audio < c->size()) {
-               remove_channel_from (c, c->size() - n_audio);
+               uint32_t n_audio = in.n_audio();
+
+               if (n_audio > c->size()) {
+                       add_channel_to (c, n_audio - c->size());
+                       changed = true;
+               } else if (n_audio < c->size()) {
+                       remove_channel_from (c, c->size() - n_audio);
+                       changed = true;
+               }
+
+               /* writer leaves scope, actual channel list is updated */
        }
 
        if (in.n_midi() > 0 && !_midi_buf) {
                const size_t size = _session.butler()->midi_diskstream_buffer_size();
-               _midi_buf = new MidiRingBuffer<framepos_t>(size);
-               midi_interpolation.add_channel_to (0,0);
+               _midi_buf = new MidiRingBuffer<samplepos_t>(size);
+               changed = true;
        }
 
-       seek (_session.transport_frame());
+       if (changed) {
+               seek (_session.transport_sample());
+       }
 
        return Processor::configure_io (in, out);
 }
@@ -177,58 +197,14 @@ DiskIOProcessor::set_block_size (pframes_t nframes)
        return 0;
 }
 
-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_locate (framepos_t location)
+DiskIOProcessor::non_realtime_locate (samplepos_t location)
 {
        /* now refill channel buffers */
 
        seek (location, true);
 }
 
-void
-DiskIOProcessor::non_realtime_speed_change ()
-{
-       if (_buffer_reallocation_required) {
-               _buffer_reallocation_required = false;
-       }
-
-       if (_seek_required) {
-               seek (_session.transport_frame(), true);
-               _seek_required = false;
-       }
-}
-
-bool
-DiskIOProcessor::realtime_speed_change ()
-{
-       const framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() * fabs (_session.transport_speed())) + 2;
-       bool _buffer_reallocation_required;
-
-       if (required_wrap_size > wrap_buffer_size) {
-               _buffer_reallocation_required = true;
-       } else {
-               _buffer_reallocation_required = false;
-       }
-
-       return _buffer_reallocation_required;
-}
-
 int
 DiskIOProcessor::set_state (const XMLNode& node, int version)
 {
@@ -243,21 +219,6 @@ DiskIOProcessor::set_state (const XMLNode& node, int version)
        return 0;
 }
 
-int
-DiskIOProcessor::add_channel_to (boost::shared_ptr<ChannelList> c, uint32_t how_many)
-{
-       while (how_many--) {
-               c->push_back (new ChannelInfo (_session.butler()->audio_diskstream_playback_buffer_size()));
-               interpolation.add_channel_to (_session.butler()->audio_diskstream_playback_buffer_size(), speed_buffer_size);
-               DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: new channel, write space = %2 read = %3\n",
-                                                           name(),
-                                                           c->back()->buf->write_space(),
-                                                           c->back()->buf->read_space()));
-       }
-
-       return 0;
-}
-
 int
 DiskIOProcessor::add_channel (uint32_t how_many)
 {
@@ -273,7 +234,6 @@ DiskIOProcessor::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t
        while (how_many-- && !c->empty()) {
                delete c->back();
                c->pop_back();
-               interpolation.remove_channel_from ();
        }
 
        return 0;
@@ -325,73 +285,68 @@ DiskIOProcessor::midi_playlist () const
 int
 DiskIOProcessor::use_playlist (DataType dt, boost::shared_ptr<Playlist> playlist)
 {
-        if (!playlist) {
-                return 0;
-        }
-
-        DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: set to use playlist %2 (%3)\n", name(), playlist->name(), dt.to_string()));
+       if (!playlist) {
+               return 0;
+       }
 
-        if (playlist == _playlists[dt]) {
-               return 0;
-        }
+       DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: set to use playlist %2 (%3)\n", name(), playlist->name(), dt.to_string()));
 
-        playlist_connections.drop_connections ();
+       if (playlist == _playlists[dt]) {
+               DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: already using that playlist\n", name()));
+               return 0;
+       }
 
-        if (_playlists[dt]) {
-               _playlists[dt]->release();
-        }
+       playlist_connections.drop_connections ();
 
-        _playlists[dt] = playlist;
-        playlist->use();
+       if (_playlists[dt]) {
+               _playlists[dt]->release();
+       }
 
-        playlist->ContentsChanged.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_modified, this));
-        playlist->LayeringChanged.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_modified, this));
-        playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_deleted, this, boost::weak_ptr<Playlist>(playlist)));
-        playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_ranges_moved, this, _1, _2));
+       _playlists[dt] = playlist;
+       playlist->use();
 
-       DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1 now use playlist %1 (%2)\n", name(), playlist->name(), playlist->id()));
+       playlist->ContentsChanged.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_modified, this));
+       playlist->LayeringChanged.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_modified, this));
+       playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_deleted, this, boost::weak_ptr<Playlist>(playlist)));
+       playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_ranges_moved, this, _1, _2));
 
-       PlaylistChanged (dt); /* EMIT SIGNAL */
-       _session.set_dirty ();
+       DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1 now using playlist %1 (%2)\n", name(), playlist->name(), playlist->id()));
 
        return 0;
 }
 
-DiskIOProcessor::ChannelInfo::ChannelInfo (framecnt_t bufsize)
-{
-       buf = new RingBufferNPT<Sample> (bufsize);
-
-       /* touch the ringbuffer buffer, which will cause
-          them to be mapped into locked physical RAM if
-          we're running with mlockall(). this doesn't do
-          much if we're not.
-       */
-
-       memset (buf->buffer(), 0, sizeof (Sample) * buf->bufsize());
-       capture_transition_buf = new RingBufferNPT<CaptureTransition> (256);
-}
-
-void
-DiskIOProcessor::ChannelInfo::resize (framecnt_t bufsize)
+DiskIOProcessor::ChannelInfo::ChannelInfo (samplecnt_t bufsize)
+       : rbuf (0)
+       , wbuf (0)
+       , capture_transition_buf (0)
+       , curr_capture_cnt (0)
 {
-       delete buf;
-       buf = new RingBufferNPT<Sample> (bufsize);
-       memset (buf->buffer(), 0, sizeof (Sample) * buf->bufsize());
 }
 
 DiskIOProcessor::ChannelInfo::~ChannelInfo ()
 {
-       delete buf;
-       buf = 0;
-
+       delete rbuf;
+       delete wbuf;
        delete capture_transition_buf;
+       rbuf = 0;
+       wbuf = 0;
        capture_transition_buf = 0;
 }
 
+void
+DiskIOProcessor::drop_route ()
+{
+       _route.reset ();
+}
+
 void
 DiskIOProcessor::set_route (boost::shared_ptr<Route> r)
 {
        _route = r;
+
+       if (_route) {
+               _route->DropReferences.connect_same_thread (*this, boost::bind (&DiskIOProcessor::drop_route, this));
+       }
 }
 
 /** Get the start, end, and length of a location "atomically".
@@ -403,9 +358,9 @@ DiskIOProcessor::set_route (boost::shared_ptr<Route> r)
  */
 void
 DiskIOProcessor::get_location_times(const Location* location,
-                   framepos_t*     start,
-                   framepos_t*     end,
-                   framepos_t*     length)
+                   samplepos_t*     start,
+                   samplepos_t*     end,
+                   samplepos_t*     length)
 {
        if (location) {
                *start  = location->start();
@@ -413,3 +368,4 @@ DiskIOProcessor::get_location_times(const Location* location,
                *length = *end - *start;
        }
 }
+