summaryrefslogtreecommitdiff
path: root/libs/ardour/midi_diskstream.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-07-20 18:13:03 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-07-20 18:13:03 +0000
commitc99738d88e8a2ad806b219b9f3614a6b55b6bf37 (patch)
treed506a27d404e1b63063372ebe2f63aacc7e6ebb4 /libs/ardour/midi_diskstream.cc
parent8c7fda11cf47cd8dd04c6eabffc437dd942403d5 (diff)
try to fix data loss at end of a capture pass for MIDI - add a new virtual method to MidiSource that specifies what should be done with stuck notes, remove duplicate(i hope) _last_flush_frame from SMFSource that mirrored, more or less, MidiSource::_last_write_end; use new virtual method when stopping after capture.
git-svn-id: svn://localhost/ardour2/branches/3.0@9910 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/midi_diskstream.cc')
-rw-r--r--libs/ardour/midi_diskstream.cc69
1 files changed, 33 insertions, 36 deletions
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 8ccdd9420e..6a75537f9a 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -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)
@@ -203,7 +201,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
@@ -861,20 +861,27 @@ 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;
+
+ if (!_write_source) {
+ return 0;
+ }
+
+ assert (!destructive());
cerr << name() << " flushing to disk, bufspace = " << _capture_buf->read_space()
- << " transport @ " << _session.transport_frame() << " last flush @ " << _last_flush_frame
+ << " transport @ " << _session.transport_frame()
<< endl;
_write_data_count = 0;
- total = _session.transport_frame() - _last_flush_frame;
+ 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)) {
cerr << "\tFlush shortcut because total = " << total
<< " capture read space = " << _capture_buf->read_space()
<< " force flush = " << force_flush
@@ -898,35 +905,25 @@ 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 {
- cerr << "didn't write, _write_source = " << _write_source << endl;
- _last_flush_frame = _session.transport_frame();
- }
+ }
} else {
cerr << "\tdidn't write to disk because recenabled = " << record_enabled()
- << " last flush @ " << _last_flush_frame << " disk io " << disk_io_chunk_frames << " TF @ " << _session.transport_frame()
+ << " total = " << total << " TF @ " << _session.transport_frame()
<< " force = " << force_flush << endl;
}
out:
-
- if (ret == 0) {
- if (_last_flush_frame > _session.transport_frame() || _last_flush_frame < capture_start_frame) {
- _last_flush_frame = _session.transport_frame();
- cerr << name() << " set last flush frame to " << _last_flush_frame << endl;
- }
- }
-
return ret;
}
@@ -996,17 +993,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