diff options
author | Robin Gareus <robin@gareus.org> | 2020-01-29 15:14:27 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2020-01-29 16:25:33 +0100 |
commit | 0ab46c342fe7236a1adfe4e21781b00f2dd07294 (patch) | |
tree | 3211d52d4dcfa2156e0fae24c7433097001f6e3a /libs/ardour | |
parent | ffe7fcd3b0a49158ef1160e38162f7e413c8c1f4 (diff) |
Fix MIDI loop capture alignment
Loop recording creates a single long source, regions have to be
"split" from this source, using "start" as offset.
Since MIDI uses absolute timestamps, offsetting this by accumulating
buffer_position += (*ci)->samples;
like Track::use_captured_audio_sources() does, is not correct.
Furthermore, record_enabled() may be off when stopping recording,
MIDI needs to be flushed regardless.
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/types.h | 1 | ||||
-rw-r--r-- | libs/ardour/disk_writer.cc | 14 | ||||
-rw-r--r-- | libs/ardour/track.cc | 6 |
3 files changed, 17 insertions, 4 deletions
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 3db1a34dc9..3a991aa81a 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -783,6 +783,7 @@ enum MidiTempoMapDisposition { struct CaptureInfo { samplepos_t start; samplecnt_t samples; + samplecnt_t loop_offset; }; enum LoopFadeChoice { diff --git a/libs/ardour/disk_writer.cc b/libs/ardour/disk_writer.cc index aafdcc5dcd..6e13da644b 100644 --- a/libs/ardour/disk_writer.cc +++ b/libs/ardour/disk_writer.cc @@ -463,6 +463,7 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp */ _capture_captured = start_sample - loop_start; _capture_start_sample = loop_start; + _first_recordable_sample = loop_start; if (_capture_captured > 0) { /* when enabling record while already looping, * zero fill region back to loop-start. @@ -695,6 +696,16 @@ DiskWriter::finish_capture (boost::shared_ptr<ChannelList> c) ci->start = _capture_start_sample; ci->samples = _capture_captured; + if (_loop_location) { + samplepos_t loop_start = 0; + samplepos_t loop_end = 0; + samplepos_t loop_length = 0; + get_location_times (_loop_location, &loop_start, &loop_end, &loop_length); + ci->loop_offset = _num_captured_loops * loop_length; + } else { + ci->loop_offset = 0; + } + DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->samples)); /* XXX theoretical race condition here. Need atomic exchange ? @@ -1024,7 +1035,7 @@ DiskWriter::do_flush (RunContext ctxt, bool force_flush) to_write = _chunk_samples; } - if (record_enabled() && ((total > _chunk_samples) || force_flush)) { + if ((total > _chunk_samples) || force_flush) { Source::Lock lm(_midi_write_source->mutex()); if (_midi_write_source->midi_write (lm, *_midi_buf, get_capture_start_sample (0), to_write) != to_write) { error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg; @@ -1348,7 +1359,6 @@ DiskWriter::transport_looped (samplepos_t transport_sample) if (_capture_captured) { _transport_looped = true; _transport_loop_sample = transport_sample; - _first_recordable_sample = transport_sample; } } diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 87c9aedabb..a4c26a7ffb 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -977,15 +977,17 @@ Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture _name, (*ci)->start, (*ci)->samples, region_name)); - // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " add a region\n"; + // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " start: " << (*ci)->loop_offset << " add MIDI region\n"; try { PropertyList plist; /* start of this region is the offset between the start of its capture and the start of the whole pass */ - plist.add (Properties::start, (*ci)->start - initial_capture); + samplecnt_t start_off = (*ci)->start - initial_capture + (*ci)->loop_offset; + plist.add (Properties::start, start_off); plist.add (Properties::length, (*ci)->samples); plist.add (Properties::length_beats, converter.from((*ci)->samples).to_double()); + plist.add (Properties::start_beats, converter.from(start_off).to_double()); plist.add (Properties::name, region_name); boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist)); |