get loop recording working when using seam-ed looping
This commit is contained in:
parent
0613ddd1f9
commit
34f088576c
@ -67,6 +67,8 @@ class LIBARDOUR_API Butler : public SessionHandleRef
|
||||
framecnt_t audio_diskstream_playback_buffer_size() const { return audio_dstream_playback_buffer_size; }
|
||||
uint32_t midi_diskstream_buffer_size() const { return midi_dstream_buffer_size; }
|
||||
|
||||
bool flush_tracks_to_disk (boost::shared_ptr<RouteList>, uint32_t& errors, bool force_flush);
|
||||
|
||||
static void* _thread_work(void *arg);
|
||||
void* thread_work();
|
||||
|
||||
|
@ -268,44 +268,7 @@ Butler::thread_work ()
|
||||
goto restart;
|
||||
}
|
||||
|
||||
for (i = rl->begin(); !transport_work_requested() && should_run && i != rl->end(); ++i) {
|
||||
// cerr << "write behind for " << (*i)->name () << endl;
|
||||
|
||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||
|
||||
if (!tr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* note that we still try to flush diskstreams attached to inactive routes
|
||||
*/
|
||||
|
||||
gint64 before, after;
|
||||
int ret;
|
||||
|
||||
DEBUG_TRACE (DEBUG::Butler, string_compose ("butler flushes track %1 capture load %2\n", tr->name(), tr->capture_buffer_load()));
|
||||
before = g_get_monotonic_time ();
|
||||
ret = tr->do_flush (ButlerContext);
|
||||
after = g_get_monotonic_time ();
|
||||
switch (ret) {
|
||||
case 0:
|
||||
DEBUG_TRACE (DEBUG::Butler, string_compose ("\tflush complete for %1, %2 usecs\n", tr->name(), after - before));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DEBUG_TRACE (DEBUG::Butler, string_compose ("\tflush not finished for %1, %2 usecs\n", tr->name(), after - before));
|
||||
disk_work_outstanding = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
err++;
|
||||
error << string_compose(_("Butler write-behind failure on dstream %1"), (*i)->name()) << endmsg;
|
||||
std::cerr << string_compose(_("Butler write-behind failure on dstream %1"), (*i)->name()) << std::endl;
|
||||
/* don't break - try to flush all streams in case they
|
||||
are split across disks.
|
||||
*/
|
||||
}
|
||||
}
|
||||
disk_work_outstanding = flush_tracks_to_disk (rl, err, false);
|
||||
|
||||
if (err && _session.actively_recording()) {
|
||||
/* stop the transport and try to catch as much possible
|
||||
@ -315,12 +278,6 @@ Butler::thread_work ()
|
||||
_session.request_stop ();
|
||||
}
|
||||
|
||||
if (i != rl->begin() && i != rl->end()) {
|
||||
/* we didn't get to all the streams */
|
||||
DEBUG_TRACE (DEBUG::Butler, "not all tracks processed, will need to go back for more\n");
|
||||
disk_work_outstanding = true;
|
||||
}
|
||||
|
||||
if (!err && transport_work_requested()) {
|
||||
DEBUG_TRACE (DEBUG::Butler, "transport work requested during flush, back to restart\n");
|
||||
goto restart;
|
||||
@ -330,7 +287,6 @@ Butler::thread_work ()
|
||||
_session.refresh_disk_space ();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (request_lock);
|
||||
|
||||
@ -351,6 +307,54 @@ Butler::thread_work ()
|
||||
return (0);
|
||||
}
|
||||
|
||||
bool
|
||||
Butler::flush_tracks_to_disk (boost::shared_ptr<RouteList> rl, uint32_t& errors, bool force)
|
||||
{
|
||||
bool disk_work_outstanding = false;
|
||||
|
||||
for (RouteList::iterator i = rl->begin(); (force || !transport_work_requested()) && should_run && i != rl->end(); ++i) {
|
||||
|
||||
// cerr << "write behind for " << (*i)->name () << endl;
|
||||
|
||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||
|
||||
if (!tr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* note that we still try to flush diskstreams attached to inactive routes
|
||||
*/
|
||||
|
||||
gint64 before, after;
|
||||
int ret;
|
||||
|
||||
DEBUG_TRACE (DEBUG::Butler, string_compose ("butler flushes track %1 capture load %2\n", tr->name(), tr->capture_buffer_load()));
|
||||
before = g_get_monotonic_time ();
|
||||
ret = tr->do_flush (ButlerContext, force);
|
||||
after = g_get_monotonic_time ();
|
||||
switch (ret) {
|
||||
case 0:
|
||||
DEBUG_TRACE (DEBUG::Butler, string_compose ("\tflush complete for %1, %2 usecs\n", tr->name(), after - before));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DEBUG_TRACE (DEBUG::Butler, string_compose ("\tflush not finished for %1, %2 usecs\n", tr->name(), after - before));
|
||||
disk_work_outstanding = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
errors++;
|
||||
error << string_compose(_("Butler write-behind failure on dstream %1"), (*i)->name()) << endmsg;
|
||||
std::cerr << string_compose(_("Butler write-behind failure on dstream %1"), (*i)->name()) << std::endl;
|
||||
/* don't break - try to flush all streams in case they
|
||||
are split across disks.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
return disk_work_outstanding;
|
||||
}
|
||||
|
||||
void
|
||||
Butler::schedule_transport_work ()
|
||||
{
|
||||
|
@ -326,6 +326,37 @@ Session::butler_transport_work ()
|
||||
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
|
||||
|
||||
|
||||
if (ptw & PostTransportLocate) {
|
||||
|
||||
if (get_play_loop() && !Config->get_seamless_loop() && actively_recording()) {
|
||||
|
||||
/* this locate is happening while we are doing loop
|
||||
* recording but with seam-ed (non-seamless) looping.
|
||||
* We must flush any data to disk before resetting
|
||||
* buffers as part of the pending locate (which happens
|
||||
* a little later in this method).
|
||||
*/
|
||||
|
||||
bool more_disk_io_to_do = false;
|
||||
uint32_t errors = 0;
|
||||
|
||||
do {
|
||||
more_disk_io_to_do = _butler->flush_tracks_to_disk (r, errors, true);
|
||||
|
||||
if (errors) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (more_disk_io_to_do) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} while (false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ptw & PostTransportAdjustPlaybackBuffering) {
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||
@ -1067,6 +1098,13 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
|
||||
target_frame, with_roll, with_flush, for_loop_enabled, force, with_mmc));
|
||||
|
||||
if (!force && _transport_frame == target_frame && !loop_changing && !for_loop_enabled) {
|
||||
|
||||
/* already at the desired position. Not forced to locate,
|
||||
the loop isn't changing, so unless we're told to
|
||||
start rolling also, there's nothing to do but
|
||||
tell the world where we are (again).
|
||||
*/
|
||||
|
||||
if (with_roll) {
|
||||
set_transport_speed (1.0, 0, false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user