summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2020-01-29 15:14:27 +0100
committerRobin Gareus <robin@gareus.org>2020-01-29 16:25:33 +0100
commit0ab46c342fe7236a1adfe4e21781b00f2dd07294 (patch)
tree3211d52d4dcfa2156e0fae24c7433097001f6e3a /libs/ardour
parentffe7fcd3b0a49158ef1160e38162f7e413c8c1f4 (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.h1
-rw-r--r--libs/ardour/disk_writer.cc14
-rw-r--r--libs/ardour/track.cc6
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));