Skip to content

Commit

Permalink
add finite state machine to control/manage transport state
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldavisthefirst committed Sep 18, 2019
1 parent fc3e762 commit bd22993
Show file tree
Hide file tree
Showing 41 changed files with 899 additions and 452 deletions.
2 changes: 1 addition & 1 deletion gtk2_ardour/export_dialog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ ExportDialog::show_progress ()
}
}

status->finish ();
status->finish (TRS_UI);

if (!status->aborted() && UIConfiguration::instance().get_save_export_mixer_screenshot ()) {
ExportProfileManager::TimespanStateList const& timespans = profile_manager->get_timespans();
Expand Down
2 changes: 1 addition & 1 deletion gtk2_ardour/export_video_dialog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ ExportVideoDialog::launch_export ()
}
}
audio_progress_connection.disconnect();
status->finish ();
status->finish (TRS_UI);
if (status->aborted()) {
::g_unlink (_insnd.c_str());
delete _transcoder; _transcoder = 0;
Expand Down
2 changes: 0 additions & 2 deletions gtk2_ardour/gui_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
#include <map>
#include <string>

#include <boost/variant.hpp>

#include "pbd/xml++.h"
#include "pbd/id.h"

Expand Down
4 changes: 3 additions & 1 deletion libs/ardour/ardour/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace PBD {
namespace DEBUG {
LIBARDOUR_API extern DebugBits MidiSourceIO;
LIBARDOUR_API extern DebugBits MidiPlaylistIO;
LIBARDOUR_API extern DebugBits MidiDiskstreamIO;
LIBARDOUR_API extern DebugBits MidiDiskIO;
LIBARDOUR_API extern DebugBits MidiRingBuffer;
LIBARDOUR_API extern DebugBits SnapBBT;
LIBARDOUR_API extern DebugBits Latency;
Expand All @@ -49,6 +49,8 @@ namespace PBD {
LIBARDOUR_API extern DebugBits LTC;
LIBARDOUR_API extern DebugBits TXLTC;
LIBARDOUR_API extern DebugBits Transport;
LIBARDOUR_API extern DebugBits TFSMEvents;
LIBARDOUR_API extern DebugBits TFSMState;
LIBARDOUR_API extern DebugBits Slave;
LIBARDOUR_API extern DebugBits SessionEvents;
LIBARDOUR_API extern DebugBits MidiIO;
Expand Down
2 changes: 0 additions & 2 deletions libs/ardour/ardour/disk_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
protected:
Flag _flags;
uint32_t i_am_the_modifier;
double _actual_speed;
double _target_speed;
bool _slaved;
bool in_set_state;
samplepos_t playback_sample;
Expand Down
15 changes: 12 additions & 3 deletions libs/ardour/ardour/disk_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,17 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor

static void set_midi_readahead_samples (samplecnt_t samples_ahead) { midi_readahead = samples_ahead; }

static void set_no_disk_output (bool yn);
static bool no_disk_output() { return _no_disk_output; }
/* inc/dec variants MUST be called as part of the process call tree, before any
disk readers are invoked. We use it when the session needs the
transport (and thus effective read position for DiskReaders) to keep
advancing as part of syncing up with a transport master, but we
don't want any actual disk output yet because we are still not
synced.
*/

static void inc_no_disk_output () { g_atomic_int_inc (&_no_disk_output); }
static void dec_no_disk_output();
static bool no_disk_output () { return g_atomic_int_get (&_no_disk_output); }

protected:
friend class Track;
Expand Down Expand Up @@ -156,7 +165,7 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor

static samplecnt_t _chunk_samples;
static samplecnt_t midi_readahead;
static bool _no_disk_output;
static gint _no_disk_output;

int audio_read (PBD::PlaybackBuffer<Sample>*,
Sample* sum_buffer,
Expand Down
4 changes: 2 additions & 2 deletions libs/ardour/ardour/export_status.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class LIBARDOUR_API ExportStatus {
}
Glib::Threads::Mutex& lock () { return _run_lock; }

PBD::Signal0<void> Finished;
void finish ();
PBD::Signal1<void,TransportRequestSource> Finished;
void finish (TransportRequestSource);

void cleanup ();

Expand Down
38 changes: 23 additions & 15 deletions libs/ardour/ardour/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
#include "ardour/presentation_info.h"
#include "ardour/route.h"
#include "ardour/route_graph.h"

#include "ardour/transport_api.h"

class XMLTree;
class XMLNode;
Expand Down Expand Up @@ -167,6 +167,7 @@ class Source;
class Speakers;
class TempoMap;
class TransportMaster;
struct TransportFSM;
class Track;
class UI_TransportMaster;
class VCAManager;
Expand All @@ -186,7 +187,7 @@ class LIBARDOUR_API SessionException: public std::exception {
};

/** Ardour Session */
class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager, public TransportAPI
{
private:

Expand Down Expand Up @@ -457,7 +458,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void adjust_capture_buffering();

bool global_locate_pending() const { return _global_locate_pending; }
bool locate_pending() const { return static_cast<bool>(post_transport_work()&PostTransportLocate); }
bool locate_pending() const;
bool declick_in_progress () const;
bool transport_locked () const;

int wipe ();
Expand Down Expand Up @@ -752,8 +754,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
return 0;
}
double transport_speed() const { return _count_in_samples > 0 ? 0. : _transport_speed; }
bool transport_stopped() const { return _transport_speed == 0.0; }
bool transport_rolling() const { return _transport_speed != 0.0 && _count_in_samples == 0 && _remaining_latency_preroll == 0; }
bool transport_stopped() const;
bool transport_rolling() const;

bool silent () { return _silent; }

Expand Down Expand Up @@ -1237,6 +1239,16 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
friend class Route;
void update_latency_compensation (bool force = false);

/* transport API */

void locate (samplepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true);
void stop_transport (bool abort = false, bool clear_state = false);
void start_transport ();
void butler_completed_transport_work ();
void post_locate ();
void schedule_butler_for_transport_work ();
bool should_roll_after_locate () const;

private:
int create (const std::string& mix_template, BusProfile*);
void destroy ();
Expand All @@ -1262,7 +1274,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
samplecnt_t _base_sample_rate; // sample-rate of the session at creation time, "native" SR
samplecnt_t _nominal_sample_rate; // overridden by audioengine setting
samplecnt_t _current_sample_rate; // this includes video pullup offset
int transport_sub_state;
mutable gint _record_status;
samplepos_t _transport_sample;
gint _seek_counter;
Expand Down Expand Up @@ -1357,7 +1368,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop

int pre_export ();
int stop_audio_export ();
void finalize_audio_export ();
void finalize_audio_export (TransportRequestSource trs);
void finalize_export_internal (bool stop_freewheel);
bool _pre_export_mmc_enabled;

Expand Down Expand Up @@ -1436,11 +1447,11 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop

Butler* _butler;

boost::shared_ptr<TransportFSM> _transport_fsm;

static const PostTransportWork ProcessCannotProceedMask =
PostTransportWork (
PostTransportReverse|
PostTransportAudition|
PostTransportStop|
PostTransportClearSubstate);

gint _post_transport_work; /* accessed only atomic ops */
Expand Down Expand Up @@ -1671,28 +1682,25 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
int start_midi_thread ();

bool should_ignore_transport_request (TransportRequestSource, TransportRequestType) const;
bool declick_in_progress () const;

void set_play_loop (bool yn, double speed);
void unset_play_loop ();
void overwrite_some_buffers (Track *);
void flush_all_inserts ();
int micro_locate (samplecnt_t distance);
void locate (samplepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true);
void start_locate (samplepos_t, bool with_roll, bool with_flush, bool for_loop_enabled=false, bool force=false);

void do_locate (samplepos_t, bool with_roll, bool with_flush, bool for_loop_enabled, bool force, bool with_mmc);
void force_locate (samplepos_t sample, bool with_roll = false);
void set_transport_speed (double speed, samplepos_t destination_sample, bool abort = false, bool clear_state = false, bool as_default = false);
void stop_transport (bool abort = false, bool clear_state = false);
void start_transport ();
void realtime_stop (bool abort, bool clear_state);
void realtime_locate ();
void non_realtime_start_scrub ();
void non_realtime_set_speed ();
void non_realtime_locate ();
void non_realtime_stop (bool abort, int entry_request_count, bool& finished);
void non_realtime_overwrite (int entry_request_count, bool& finished);
void post_transport ();
void engine_halted ();
void engine_running ();
void xrun_recovery ();
void set_track_loop (bool);
bool select_playhead_priority_target (samplepos_t&);
Expand Down
1 change: 0 additions & 1 deletion libs/ardour/ardour/session_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class LIBARDOUR_API SessionEvent {

/* only one of each of these events can be queued at any one time */

StopOnce,
AutoLoop,
};

Expand Down
47 changes: 47 additions & 0 deletions libs/ardour/ardour/transport_api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2019 Paul Davis <paul@linuxaudiosystems.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#ifndef _ardour_transport_api_h_
#define _ardour_transport_api_h_

#include "ardour/types.h"
#include "ardour/libardour_visibility.h"

namespace ARDOUR
{

class LIBARDOUR_API TransportAPI
{
public:
TransportAPI() {}
virtual ~TransportAPI() {}

private:
friend struct TransportFSM;

virtual void locate (samplepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true) = 0;
virtual void stop_transport (bool abort = false, bool clear_state = false) = 0;
virtual void start_transport () = 0;
virtual void butler_completed_transport_work () = 0;
virtual void schedule_butler_for_transport_work () = 0;
virtual bool should_roll_after_locate () const = 0;
};

} /* end namespace ARDOUR */

#endif
Loading

0 comments on commit bd22993

Please sign in to comment.