diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/audio_diskstream.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/diskstream.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 1 | ||||
-rw-r--r-- | libs/ardour/audio_diskstream.cc | 58 | ||||
-rw-r--r-- | libs/ardour/session.cc | 21 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 29 |
7 files changed, 95 insertions, 18 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 4846a20cbd..7b7df480d8 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -226,6 +226,7 @@ class AudioDiskstream : public Diskstream void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>); void transport_stopped (struct tm&, time_t, bool abort); + void transport_looped (nframes_t transport_frame); void init (Diskstream::Flag); diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index 79fec98d6e..f34cee002d 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -207,6 +207,7 @@ class Diskstream : public PBD::StatefulDestructible virtual void playlist_deleted (boost::weak_ptr<Playlist>); virtual void transport_stopped (struct tm&, time_t, bool abort) = 0; + virtual void transport_looped (nframes_t transport_frame) = 0; struct CaptureInfo { uint32_t start; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index fb7d24568f..35ebb0d6fe 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -343,6 +343,7 @@ class Session : public PBD::StatefulDestructible sigc::signal<void,nframes_t> PositionChanged; /* sent after any non-sequential motion */ sigc::signal<void> DurationChanged; sigc::signal<void> HaltOnXrun; + sigc::signal<void> TransportLooped; sigc::signal<void,RouteList&> RouteAdded; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 484e4a621a..62f8fb9c36 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -463,7 +463,7 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram } - if (_flags & Recordable) { + if (recordable() && destructive()) { boost::shared_ptr<ChannelList> c = channels.reader(); for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { @@ -592,7 +592,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ /* |--------| recrange -------------- transrange */ - rec_nframes = last_recordable_frame - last_recordable_frame; + rec_nframes = last_recordable_frame - first_recordable_frame; rec_offset = first_recordable_frame - transport_frame; break; } @@ -1663,6 +1663,57 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca } void +AudioDiskstream::transport_looped (nframes_t transport_frame) +{ + if (was_recording) { + // all we need to do is finish this capture, with modified capture length + boost::shared_ptr<ChannelList> c = channels.reader(); + + // adjust the capture length knowing that the data will be recorded to disk + // only necessary after the first loop where we're recording + if (capture_info.size() == 0) { + capture_captured += _capture_offset; + + if (_alignment_style == ExistingMaterial) { + capture_captured += _session.worst_output_latency(); + } else { + capture_captured += _roll_delay; + } + } + + finish_capture (true, c); + + // the next region will start recording via the normal mechanism + // we'll set the start position to the current transport pos + // no latency adjustment or capture offset needs to be made, as that already happened the first time + capture_start_frame = transport_frame; + first_recordable_frame = transport_frame; // mild lie + last_recordable_frame = max_frames; + was_recording = true; + + if (recordable() && destructive()) { + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + + RingBufferNPT<CaptureTransition>::rw_vector transvec; + (*chan)->capture_transition_buf->get_write_vector(&transvec); + + if (transvec.len[0] > 0) { + transvec.buf[0]->type = CaptureStart; + transvec.buf[0]->capture_val = capture_start_frame; + (*chan)->capture_transition_buf->increment_write_ptr(1); + } + else { + // bad! + fatal << X_("programming error: capture_transition_buf is full on rec loop! inconceivable!") + << endmsg; + } + } + } + + } +} + +void AudioDiskstream::finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList> c) { was_recording = false; @@ -1677,7 +1728,6 @@ AudioDiskstream::finish_capture (bool rec_monitors_input, boost::shared_ptr<Chan RingBufferNPT<CaptureTransition>::rw_vector transvec; (*chan)->capture_transition_buf->get_write_vector(&transvec); - if (transvec.len[0] > 0) { transvec.buf[0]->type = CaptureEnd; transvec.buf[0]->capture_val = capture_captured; @@ -2370,7 +2420,7 @@ AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t bufsize, nframes_t speed_si playback_buf = new RingBufferNPT<Sample> (bufsize); capture_buf = new RingBufferNPT<Sample> (bufsize); - capture_transition_buf = new RingBufferNPT<CaptureTransition> (128); + capture_transition_buf = new RingBufferNPT<CaptureTransition> (256); /* touch the ringbuffer buffers, which will cause them to be mapped into locked physical RAM if diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index c2c21a631d..7c23ae6286 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1259,7 +1259,7 @@ Session::disable_record (bool rt_context, bool force) if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) { - if (!Config->get_latched_record_enable () || force) { + if ((!Config->get_latched_record_enable () && !play_loop) || force) { g_atomic_int_set (&_record_status, Disabled); } else { if (rs == Recording) { @@ -1290,15 +1290,18 @@ Session::disable_record (bool rt_context, bool force) void Session::step_back_from_record () { - g_atomic_int_set (&_record_status, Enabled); + /* XXX really atomic compare+swap here */ + if (g_atomic_int_get (&_record_status) == Recording) { + g_atomic_int_set (&_record_status, Enabled); - if (Config->get_monitoring_model() == HardwareMonitoring) { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (Config->get_auto_input() && (*i)->record_enabled ()) { - //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (false); + if (Config->get_monitoring_model() == HardwareMonitoring) { + boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); + + for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { + if (Config->get_auto_input() && (*i)->record_enabled ()) { + //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; + (*i)->monitor_input (false); + } } } } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 055cbcf82d..ba1ac280be 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -469,7 +469,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) cerr << "delta = " << (int) (dir * this_delta) << " speed = " << slave_speed << " ts = " << _transport_speed - << " M@"<< slave_transport_frame << " S@" << _transport_frame + << " M@ "<< slave_transport_frame << " S@ " << _transport_frame << " avgdelta = " << average_slave_delta << endl; #endif diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 22d30fda9d..c5cbae11c9 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -381,7 +381,8 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) _transport_frame = last_stop_frame; - if (synced_to_jack()) { + if (synced_to_jack() && !play_loop) { + // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl; _engine.transport_locate (_transport_frame); } } @@ -420,14 +421,16 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) /* XXX its a little odd that we're doing this here when realtime_stop(), which has already executed, will have done this. + JLC - so let's not because it seems unnecessary and breaks loop record */ - +#if 0 if (!Config->get_latched_record_enable()) { g_atomic_int_set (&_record_status, Disabled); } else { g_atomic_int_set (&_record_status, Enabled); } RecordStateChanged (); /* emit signal */ +#endif } if ((post_transport_work & PostTransportLocate) && get_record_enabled()) { @@ -613,7 +616,7 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, void Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop) { - if (actively_recording()) { + if (actively_recording() && !with_loop) { return; } @@ -704,6 +707,22 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w // cancel looping directly, this is called from event handling context set_play_loop (false); } + else if (al && _transport_frame == al->start()) { + if (with_loop) { + // this is only necessary for seamless looping + + boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); + + for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { + if ((*i)->record_enabled ()) { + // tell it we've looped, so it can deal with the record state + (*i)->transport_looped(_transport_frame); + } + } + } + + TransportLooped(); // EMIT SIGNAL + } } loop_changing = false; @@ -874,7 +893,9 @@ Session::start_transport () break; case Recording: - disable_record (false); + if (!play_loop) { + disable_record (false); + } break; default: |