Add some comments.
[ardour.git] / libs / ardour / audio_diskstream.cc
index eeaa095fbd63c35306450d35b7b82db64b682acd..7f791963493e282f8dec3975bb3b520cb65d954a 100644 (file)
@@ -170,10 +170,10 @@ AudioDiskstream::non_realtime_input_change ()
                        
                        _n_channels.set(DataType::AUDIO, c->size());
                        
-                       if (_io->n_inputs().get(DataType::AUDIO) > _n_channels.get(DataType::AUDIO)) {
-                               add_channel_to (c, _io->n_inputs().get(DataType::AUDIO) - _n_channels.get(DataType::AUDIO));
-                       } else if (_io->n_inputs().get(DataType::AUDIO) < _n_channels.get(DataType::AUDIO)) {
-                               remove_channel_from (c, _n_channels.get(DataType::AUDIO) - _io->n_inputs().get(DataType::AUDIO));
+                       if (_io->n_inputs().n_audio() > _n_channels.n_audio()) {
+                               add_channel_to (c, _io->n_inputs().n_audio() - _n_channels.n_audio());
+                       } else if (_io->n_inputs().n_audio() < _n_channels.n_audio()) {
+                               remove_channel_from (c, _n_channels.n_audio() - _io->n_inputs().n_audio());
                        }
                }
                
@@ -212,7 +212,7 @@ AudioDiskstream::get_input_sources ()
 
        uint32_t n;
        ChannelList::iterator chan;
-       uint32_t ni = _io->n_inputs().get(DataType::AUDIO);
+       uint32_t ni = _io->n_inputs().n_audio();
 
        for (n = 0, chan = c->begin(); chan != c->end() && n < ni; ++chan, ++n) {
                
@@ -243,7 +243,7 @@ AudioDiskstream::find_and_use_playlist (const string& name)
        boost::shared_ptr<AudioPlaylist> playlist;
                
        if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlist_by_name (name))) == 0) {
-               playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, name));
+               playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, name));
        }
 
        if (!playlist) {
@@ -280,7 +280,7 @@ AudioDiskstream::use_new_playlist ()
                newname = Playlist::bump_name (_name, _session);
        }
 
-       if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, newname, hidden()))) != 0) {
+       if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, newname, hidden()))) != 0) {
                
                playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
@@ -526,6 +526,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
                return 0;
        }
 
+       commit_should_unlock = false;
+
        check_record_status (transport_frame, nframes, can_record);
 
        nominally_recording = (can_record && re);
@@ -544,12 +546,12 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
        if (!state_lock.trylock()) {
                return 1;
        } 
-
+       commit_should_unlock = true;
        adjust_capture_position = 0;
 
        for (chan = c->begin(); chan != c->end(); ++chan) {
                (*chan)->current_capture_buffer = 0;
-               (*chan)->current_playback_buffer  = 0;
+               (*chan)->current_playback_buffer = 0;
        }
 
        if (nominally_recording || (_session.get_record_enabled() && Config->get_punch_in())) {
@@ -610,7 +612,16 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
 
        if (nominally_recording || rec_nframes) {
 
-               for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
+               uint32_t limit = _io->n_inputs ().n_audio();
+
+               /* one or more ports could already have been removed from _io, but our
+                  channel setup hasn't yet been updated. prevent us from trying to
+                  use channels that correspond to missing ports. note that the
+                  process callback (from which this is called) is always atomic
+                  with respect to port removal/addition.
+               */
+
+               for (n = 0, chan = c->begin(); chan != c->end() && n < limit; ++chan, ++n) {
                        
                        ChannelInfo* chaninfo (*chan);
 
@@ -796,6 +807,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
                   be called. unlock the state lock.
                */
                
+               commit_should_unlock = false;
                state_lock.unlock();
        } 
 
@@ -835,7 +847,10 @@ AudioDiskstream::commit (nframes_t nframes)
                        || c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
        }
 
-       state_lock.unlock();
+       if (commit_should_unlock) {
+               state_lock.unlock();
+       }
+
        _processed = false;
 
        return need_butler;
@@ -1676,7 +1691,7 @@ AudioDiskstream::finish_capture (bool rec_monitors_input, boost::shared_ptr<Chan
 void
 AudioDiskstream::set_record_enabled (bool yn)
 {
-       if (!recordable() || !_session.record_enabling_legal() || _io->n_inputs().get(DataType::AUDIO) == 0) {
+       if (!recordable() || !_session.record_enabling_legal() || _io->n_inputs().n_audio() == 0) {
                return;
        }
 
@@ -1858,13 +1873,13 @@ AudioDiskstream::set_state (const XMLNode& node)
 
        _n_channels.set(DataType::AUDIO, channels.reader()->size());
        
-       if (nchans > _n_channels.get(DataType::AUDIO)) {
+       if (nchans > _n_channels.n_audio()) {
 
-               add_channel (nchans - _n_channels.get(DataType::AUDIO));
+               add_channel (nchans - _n_channels.n_audio());
 
-       } else if (nchans < _n_channels.get(DataType::AUDIO)) {
+       } else if (nchans < _n_channels.n_audio()) {
 
-               remove_channel (_n_channels.get(DataType::AUDIO) - nchans);
+               remove_channel (_n_channels.n_audio() - nchans);
        }
 
        if ((prop = node.property ("playlist")) == 0) {
@@ -2212,7 +2227,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
                return 1;
        }
 
-       if (pending_sources.size() != _n_channels.get(DataType::AUDIO)) {
+       if (pending_sources.size() != _n_channels.n_audio()) {
                error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
                      << endmsg;
                return -1;