summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour_ui.cc2
-rw-r--r--gtk2_ardour/streamview.cc9
-rw-r--r--gtk2_ardour/streamview.h1
-rw-r--r--libs/ardour/ardour/audio_diskstream.h1
-rw-r--r--libs/ardour/ardour/diskstream.h1
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/audio_diskstream.cc58
-rw-r--r--libs/ardour/session.cc21
-rw-r--r--libs/ardour/session_process.cc2
-rw-r--r--libs/ardour/session_transport.cc29
10 files changed, 106 insertions, 19 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index ca0506878e..0223e8d027 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -1200,7 +1200,7 @@ ARDOUR_UI::transport_record ()
break;
case Session::Recording:
case Session::Enabled:
- session->disable_record (true);
+ session->disable_record (false, true);
}
}
}
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index 62d8e99254..4a454a32f5 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -72,6 +72,7 @@ StreamView::StreamView (RouteTimeAxisView& tv)
if (_trackview.is_track()) {
_trackview.track()->DiskstreamChanged.connect (mem_fun (*this, &StreamView::diskstream_changed));
_trackview.session().TransportStateChange.connect (mem_fun (*this, &StreamView::transport_changed));
+ _trackview.session().TransportLooped.connect (mem_fun (*this, &StreamView::transport_looped));
_trackview.get_diskstream()->RecordEnableChanged.connect (mem_fun (*this, &StreamView::rec_enable_changed));
_trackview.session().RecordStateChanged.connect (mem_fun (*this, &StreamView::sess_rec_enable_changed));
}
@@ -312,6 +313,14 @@ StreamView::transport_changed()
}
void
+StreamView::transport_looped()
+{
+ // to force a new rec region
+ rec_active = false;
+ Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::setup_rec_box));
+}
+
+void
StreamView::update_rec_box ()
{
if (rec_active && rec_rects.size() > 0) {
diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h
index ef55ebc4af..4df00d84a5 100644
--- a/gtk2_ardour/streamview.h
+++ b/gtk2_ardour/streamview.h
@@ -101,6 +101,7 @@ protected:
//private: (FIXME?)
void transport_changed();
+ void transport_looped();
void rec_enable_changed();
void sess_rec_enable_changed();
virtual void setup_rec_box () = 0;
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: