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.
This commit is contained in:
parent
ffe7fcd3b0
commit
0ab46c342f
@ -783,6 +783,7 @@ enum MidiTempoMapDisposition {
|
||||
struct CaptureInfo {
|
||||
samplepos_t start;
|
||||
samplecnt_t samples;
|
||||
samplecnt_t loop_offset;
|
||||
};
|
||||
|
||||
enum LoopFadeChoice {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user