Clean up MidiDiskstream code, more closely match audio diskstream.
[ardour.git] / libs / ardour / midi_diskstream.cc
index 7c3bc73fb82c49cb4f76f5b9eba2ff7b5277b3cb..b36e8da293bc8837bc5d24863243889e9cecc3e0 100644 (file)
@@ -339,7 +339,7 @@ MidiDiskstream::check_record_status (nframes_t transport_frame, nframes_t nframe
 
        /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
 
-       if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) || 
+       if (((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record)) || 
            ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
                
                /* starting to record: compute first+last frames */
@@ -548,7 +548,8 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_t
                MidiBuffer::iterator port_iter = _source_port->get_midi_buffer().begin();
 
                for (size_t i=0; i < to_write; ++i) {
-                       const MidiEvent& ev = *port_iter;
+                       const MIDI::Event& ev = *port_iter;
+                       assert(ev.buffer());
                        _capture_buf->write(ev.time() + transport_frame, ev.size(), ev.buffer());
                        ++port_iter;
                }
@@ -817,47 +818,49 @@ MidiDiskstream::do_refill_with_alloc ()
 int
 MidiDiskstream::do_refill ()
 {
-       int32_t        ret = 0;
-       size_t         write_space = _playback_buf->write_space();
-
-       bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
+       int     ret         = 0;
+       size_t  write_space = _playback_buf->write_space();
+       bool    reversed    = (_visible_speed * _session.transport_speed()) < 0.0f;
 
        if (write_space == 0) {
                return 0;
        }
+       
+       /* if there are 2+ chunks of disk i/o possible for
+          this track, let the caller know so that it can arrange
+          for us to be called again, ASAP.
+       */
+       
+       if (write_space >= (_slaved?3:2) * disk_io_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.  
 
           at higher speeds, just do it because the sync between butler
           and audio thread may not be good enough.
-          */
+       */
 
        if ((write_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
-               //cerr << "No refill 1\n";
                return 0;
        }
 
        /* when slaved, don't try to get too close to the read pointer. this
           leaves space for the buffer reversal to have something useful to
           work with.
-          */
+       */
 
        if (_slaved && write_space < (_playback_buf->capacity() / 2)) {
-               //cerr << "No refill 2\n";
                return 0;
        }
 
        if (reversed) {
-               //cerr << "No refill 3 (reverse)\n";
                return 0;
        }
 
+       /* at end: nothing to do */
        if (file_frame == max_frames) {
-               //cerr << "No refill 4 (EOF)\n";
-
-               /* at end: nothing to do */
-
                return 0;
        }
 
@@ -865,19 +868,12 @@ MidiDiskstream::do_refill ()
        assert(_playback_buf->write_space() > 0); // ... have something to write to, and
        assert(file_frame <= max_frames); // ... something to write
 
-       nframes_t file_frame_tmp = file_frame;
        nframes_t to_read = min(disk_io_chunk_frames, (max_frames - file_frame));
        
-       // FIXME: read count?
-       if (read (file_frame_tmp, to_read, reversed)) {
+       if (read (file_frame, to_read, reversed)) {
                ret = -1;
-               goto out;
        }
-
-       file_frame = file_frame_tmp;
-
-out:
-
+               
        return ret;
 }
 
@@ -896,8 +892,6 @@ MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
 {
        uint32_t to_write;
        int32_t ret = 0;
-       // FIXME: I'd be lying if I said I knew what this thing was
-       //RingBufferNPT<CaptureTransition>::rw_vector transvec;
        nframes_t total;
 
        _write_data_count = 0;
@@ -909,7 +903,7 @@ MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
 
        total = _session.transport_frame() - _last_flush_frame;
 
-       if (total == 0 || _capture_buf->read_space() == 0  && _session.transport_speed() == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
+       if (total == 0 || (_capture_buf->read_space() == 0  && _session.transport_speed() == 0) || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
                goto out;
        }
 
@@ -928,7 +922,6 @@ MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
                ret = 1;
        } 
 
-       //to_write = min (disk_io_chunk_frames, (nframes_t) vector.len[0]);
        to_write = disk_io_chunk_frames;
 
        assert(!destructive());
@@ -943,8 +936,7 @@ MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
        }
 
 out:
-       //return ret;
-       return 0; // FIXME: everything's fine!  always!  honest!
+       return ret;
 }
 
 void
@@ -1226,6 +1218,11 @@ MidiDiskstream::get_state ()
        snprintf (buf, sizeof(buf), "0x%x", _flags);
        node->add_property ("flags", buf);
 
+       node->add_property("channel-mode", enum_2_string(get_channel_mode()));
+       
+       snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
+       node->add_property("channel-mask", buf);
+       
        node->add_property ("playlist", _playlist->name());
        
        snprintf (buf, sizeof(buf), "%f", _visible_speed);
@@ -1304,6 +1301,21 @@ MidiDiskstream::set_state (const XMLNode& node)
                _flags = Flag (string_2_enum (prop->value(), _flags));
        }
 
+       ChannelMode channel_mode = AllChannels;
+       if ((prop = node.property ("channel-mode")) != 0) {
+               channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode));
+       }
+       
+       unsigned int channel_mask = 0xFFFF;
+       if ((prop = node.property ("channel-mask")) != 0) {
+               sscanf (prop->value().c_str(), "0x%x", &channel_mask);
+               if (channel_mask & (~0xFFFF)) {
+                       warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg;
+               }
+       }
+
+       set_channel_mode(channel_mode, channel_mask);
+       
        if ((prop = node.property ("channels")) != 0) {
                nchans = atoi (prop->value().c_str());
        }