fixes for 98% of all the warnings/errors reported by OS X gcc on tiger
[ardour.git] / libs / ardour / midi_diskstream.cc
index 6c51958caa859200ac6c41e40a64ccb392fb5c94..28ee12cc5ae3f574d0c24cf1bf4366a7883096d5 100644 (file)
@@ -74,7 +74,6 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
        , _playback_buf(0)
        , _capture_buf(0)
        , _source_port(0)
-       , _last_flush_frame(0)
        , _note_mode(Sustained)
        , _frames_written_to_ringbuffer(0)
        , _frames_read_from_ringbuffer(0)
@@ -95,7 +94,6 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
        , _playback_buf(0)
        , _capture_buf(0)
        , _source_port(0)
-       , _last_flush_frame(0)
        , _note_mode(Sustained)
        , _frames_written_to_ringbuffer(0)
        , _frames_read_from_ringbuffer(0)
@@ -146,7 +144,7 @@ MidiDiskstream::non_realtime_locate (framepos_t position)
        if (_write_source) {
                _write_source->set_timeline_position (position);
        }
-       seek(position, false);
+       seek (position, false);
 }
 
 
@@ -170,7 +168,7 @@ MidiDiskstream::non_realtime_input_change ()
                                                         _n_channels, input_change_pending.type)
                                      << endmsg;
                        }
-                       
+
                        if (ni == 0) {
                                _source_port = 0;
                        } else {
@@ -202,7 +200,9 @@ MidiDiskstream::non_realtime_input_change ()
                seek (_session.transport_frame());
        }
 
-       _last_flush_frame = _session.transport_frame();
+       if (_write_source) {
+               _write_source->set_last_write_end (_session.transport_frame());
+       }
 }
 
 int
@@ -291,6 +291,7 @@ MidiDiskstream::use_copy_playlist ()
 int
 MidiDiskstream::set_destructive (bool yn)
 {
+       yn = 0; // stop pedantic gcc complaints about unused parameter
        assert( ! destructive());
        assert( ! yn);
        return -1;
@@ -475,7 +476,7 @@ trace_midi (ostream& o, MIDI::byte *msg, size_t len)
 #endif
 
 int
-MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool rec_monitors_input, bool& need_butler)
+MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool& need_butler)
 {
        int       ret = -1;
        framecnt_t rec_offset = 0;
@@ -522,16 +523,35 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can
        }
 
        if (nominally_recording || rec_nframes) {
-               
+
                // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
                MidiBuffer& buf = _source_port->get_midi_buffer(nframes);
                for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
                        const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
                        assert(ev.buffer());
+#ifndef NDEBUG
+                       if (DEBUG::MidiIO & PBD::debug_bits) {
+                               const uint8_t* __data = ev.buffer();
+                               DEBUG_STR_DECL(a);
+                               DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
+                               for (size_t i=0; i < ev.size(); ++i) {
+                                       DEBUG_STR_APPEND(a,hex);
+                                       DEBUG_STR_APPEND(a,"0x");
+                                       DEBUG_STR_APPEND(a,(int)__data[i]);
+                                       DEBUG_STR_APPEND(a,' ');
+                               }
+                               DEBUG_STR_APPEND(a,'\n');
+                               DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
+                       }
+#endif
                        _capture_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer());
                }
 
                if (buf.size() != 0) {
+                       /* XXX this needs fixing - realtime new() call for
+                          every time we get MIDI data in a process callback!
+                       */
+
                        /* Make a copy of this data and emit it for the GUI to see */
                        boost::shared_ptr<MidiBuffer> copy (new MidiBuffer (buf.capacity ()));
                        for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
@@ -544,7 +564,7 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can
        } else {
 
                if (was_recording) {
-                       finish_capture (rec_monitors_input);
+                       finish_capture ();
                }
 
        }
@@ -820,7 +840,7 @@ MidiDiskstream::do_refill ()
        //      << frames_written - frames_read << endl;
 
        to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
+
        if (read (file_frame, to_read, reversed)) {
                ret = -1;
        }
@@ -841,20 +861,23 @@ MidiDiskstream::do_refill ()
 int
 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
 {
-       uint32_t to_write;
-       int32_t ret = 0;
+       framecnt_t to_write;
        framecnt_t total;
+       int32_t ret = 0;
 
-       _write_data_count = 0;
+       if (!_write_source) {
+               return 0;
+       }
 
-       total = _session.transport_frame() - _last_flush_frame;
+       assert (!destructive());
 
-       if (_last_flush_frame > _session.transport_frame() || _last_flush_frame < capture_start_frame) {
-               _last_flush_frame = _session.transport_frame();
-       }
+       _write_data_count = 0;
+
+       total = _session.transport_frame() - _write_source->last_write_end();
 
-       if (total == 0 || _capture_buf->read_space() == 0
-                       || (!force_flush && (total < disk_io_chunk_frames && was_recording))) {
+       if (total == 0 || 
+           _capture_buf->read_space() == 0 || 
+           (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
                goto out;
        }
 
@@ -873,19 +896,18 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
                ret = 1;
        }
 
-       to_write = disk_io_chunk_frames;
-
-       assert(!destructive());
+       if (force_flush) {
+               /* push out everything we have, right now */
+               to_write = max_framecnt;
+       } else {
+               to_write = disk_io_chunk_frames;
+       }
 
-       if (record_enabled() &&
-           ((_session.transport_frame() - _last_flush_frame > disk_io_chunk_frames) ||
-            force_flush)) {
-               if ((!_write_source) || _write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
+       if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
+               if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
                        error << string_compose(_("MidiDiskstream %1: cannot write to disk"), _id) << endmsg;
                        return -1;
-               } else {
-                       _last_flush_frame = _session.transport_frame();
-               }
+               } 
        }
 
 out:
@@ -901,9 +923,8 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
        MidiRegion::SourceList srcs;
        MidiRegion::SourceList::iterator src;
        vector<CaptureInfo*>::iterator ci;
-       bool mark_write_completed = false;
 
-       finish_capture (true);
+       finish_capture ();
 
        /* butler is already stopped, but there may be work to do
           to flush remaining data to disk.
@@ -959,17 +980,17 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
                        _write_source->set_timeline_position (capture_info.front()->start);
                        _write_source->set_captured_for (_name);
 
+                       /* set length in beats to entire capture length */
+
+                       BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
+                       const double total_capture_beats = converter.from (total_capture);
+                       _write_source->set_length_beats (total_capture_beats);
+
                        /* flush to disk: this step differs from the audio path,
                           where all the data is already on disk.
                        */
 
-                       _write_source->mark_streaming_write_completed ();
-
-                       /* set length in beats to entire capture length */
-
-                       BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
-                       const double total_capture_beats = converter.from(total_capture);
-                       _write_source->set_length_beats(total_capture_beats);
+                       _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
 
                        /* we will want to be able to keep (over)writing the source
                           but we don't want it to be removable. this also differs
@@ -1070,9 +1091,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
                                _write_source.reset();
                        }
                }
-               
 
-               mark_write_completed = true;
        }
 
        use_new_write_source (0);
@@ -1106,7 +1125,7 @@ MidiDiskstream::transport_looped (framepos_t transport_frame)
                        }
                }
 
-               finish_capture (true);
+               finish_capture ();
 
                // the next region will start recording via the normal mechanism
                // we'll set the start position to the current transport pos
@@ -1119,7 +1138,7 @@ MidiDiskstream::transport_looped (framepos_t transport_frame)
 }
 
 void
-MidiDiskstream::finish_capture (bool /*rec_monitors_input*/)
+MidiDiskstream::finish_capture ()
 {
        was_recording = false;
 
@@ -1286,7 +1305,7 @@ MidiDiskstream::use_new_write_source (uint32_t n)
        if (!_session.writable() || !recordable()) {
                return 1;
        }
-       
+
        assert(n == 0);
 
        _write_source.reset();
@@ -1366,7 +1385,7 @@ MidiDiskstream::set_align_style_from_io ()
                return;
        }
 
-       /* XXX Not sure what, if anything we can do with MIDI 
+       /* XXX Not sure what, if anything we can do with MIDI
           as far as capture alignment etc.
        */
 
@@ -1413,8 +1432,8 @@ MidiDiskstream::get_playback (MidiBuffer& dst, framepos_t start, framepos_t end)
 
 #ifndef NDEBUG
        DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
-                            "%1 MDS pre-read read from %2 write to %3\n", _name, 
-                            _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
+                            "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
+                            _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), start, end));
 //        cerr << "================\n";
 //        _playback_buf->dump (cerr);
 //        cerr << "----------------\n";