move Session::Event into SessionEvent class; add SessionEventManager (Session IS-A SessionEventManager); make session ops to toggle all track rec-enable be atomic with respect to process()
git-svn-id: svn://localhost/ardour2/branches/3.0@6273 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
1ef43ec89c
commit
9ad2875905
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2004 Paul Davis
|
||||
Copyright (C) 2009 Paul Davis
|
||||
|
||||
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
|
||||
|
@ -20,17 +20,43 @@
|
|||
#ifndef __ardour_click_h__
|
||||
#define __ardour_click_h__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "pbd/pool.h"
|
||||
#include "ardour/types.h"
|
||||
#include "ardour/io.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
struct Click {
|
||||
nframes_t start;
|
||||
nframes_t duration;
|
||||
nframes_t offset;
|
||||
const Sample *data;
|
||||
|
||||
Click (nframes_t s, nframes_t d, const Sample *b) : start (s), duration (d), offset (0), data (b) {}
|
||||
|
||||
void *operator new (size_t) {
|
||||
return pool.alloc ();
|
||||
};
|
||||
|
||||
void operator delete(void *ptr, size_t /*size*/) {
|
||||
pool.release (ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
static Pool pool;
|
||||
};
|
||||
|
||||
typedef std::list<Click*> Clicks;
|
||||
|
||||
class ClickIO : public IO
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ClickIO (Session& s, const std::string& name) : IO (s, name, IO::Output) {}
|
||||
~ClickIO() {}
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
uint32_t pans_required () const { return 1; }
|
||||
};
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ class Diskstream : public SessionObject, public boost::noncopyable
|
|||
|
||||
bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
|
||||
virtual void set_record_enabled (bool yn) = 0;
|
||||
virtual void get_input_sources () = 0;
|
||||
|
||||
bool destructive() const { return _flags & Destructive; }
|
||||
virtual int set_destructive (bool /*yn*/) { return -1; }
|
||||
|
@ -233,7 +234,6 @@ class Diskstream : public SessionObject, public boost::noncopyable
|
|||
|
||||
virtual int use_pending_capture_data (XMLNode& node) = 0;
|
||||
|
||||
virtual void get_input_sources () = 0;
|
||||
virtual void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record);
|
||||
virtual void prepare_record_status (nframes_t /*capture_start_frame*/) {}
|
||||
virtual void set_align_style_from_io() {}
|
||||
|
@ -310,6 +310,7 @@ class Diskstream : public SessionObject, public boost::noncopyable
|
|||
sigc::connection plmod_connection;
|
||||
sigc::connection plgone_connection;
|
||||
sigc::connection plregion_connection;
|
||||
sigc::connection ic_connection;
|
||||
|
||||
Flag _flags;
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include <glibmm/thread.h>
|
||||
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/pool.h"
|
||||
#include "pbd/rcu.h"
|
||||
#include "pbd/statefuldestructible.h"
|
||||
#include "pbd/undo.h"
|
||||
|
@ -50,9 +49,11 @@
|
|||
#include "pbd/stateful.h"
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/click.h"
|
||||
#include "ardour/chan_count.h"
|
||||
#include "ardour/rc_configuration.h"
|
||||
#include "ardour/session_configuration.h"
|
||||
#include "ardour/session_event.h"
|
||||
#include "ardour/location.h"
|
||||
#include "ardour/timecode.h"
|
||||
#include "ardour/interpolation.h"
|
||||
|
@ -120,7 +121,7 @@ class VSTPlugin;
|
|||
|
||||
extern void setup_enum_writer ();
|
||||
|
||||
class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
||||
class Session : public PBD::StatefulDestructible, public SessionEventManager, public boost::noncopyable
|
||||
{
|
||||
private:
|
||||
typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
|
||||
|
@ -135,100 +136,6 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
Recording = 2
|
||||
};
|
||||
|
||||
struct Event {
|
||||
enum Type {
|
||||
SetTransportSpeed,
|
||||
SetDiskstreamSpeed,
|
||||
Locate,
|
||||
LocateRoll,
|
||||
LocateRollLocate,
|
||||
SetLoop,
|
||||
PunchIn,
|
||||
PunchOut,
|
||||
RangeStop,
|
||||
RangeLocate,
|
||||
Overwrite,
|
||||
SetSyncSource,
|
||||
Audition,
|
||||
InputConfigurationChange,
|
||||
SetPlayAudioRange,
|
||||
|
||||
/* only one of each of these events can be queued at any one time */
|
||||
|
||||
StopOnce,
|
||||
AutoLoop
|
||||
};
|
||||
|
||||
enum Action {
|
||||
Add,
|
||||
Remove,
|
||||
Replace,
|
||||
Clear
|
||||
};
|
||||
|
||||
Type type;
|
||||
Action action;
|
||||
nframes64_t action_frame;
|
||||
nframes64_t target_frame;
|
||||
double speed;
|
||||
|
||||
union {
|
||||
void* ptr;
|
||||
bool yes_or_no;
|
||||
nframes64_t target2_frame;
|
||||
Slave* slave;
|
||||
Route* route;
|
||||
};
|
||||
|
||||
union {
|
||||
bool second_yes_or_no;
|
||||
};
|
||||
|
||||
std::list<AudioRange> audio_range;
|
||||
std::list<MusicRange> music_range;
|
||||
|
||||
boost::shared_ptr<Region> region;
|
||||
|
||||
Event(Type t, Action a, nframes_t when, nframes_t where, double spd, bool yn = false, bool yn2 = false)
|
||||
: type (t)
|
||||
, action (a)
|
||||
, action_frame (when)
|
||||
, target_frame (where)
|
||||
, speed (spd)
|
||||
, yes_or_no (yn)
|
||||
, second_yes_or_no (yn2)
|
||||
{}
|
||||
|
||||
void set_ptr (void* p) {
|
||||
ptr = p;
|
||||
}
|
||||
|
||||
bool before (const Event& other) const {
|
||||
return action_frame < other.action_frame;
|
||||
}
|
||||
|
||||
bool after (const Event& other) const {
|
||||
return action_frame > other.action_frame;
|
||||
}
|
||||
|
||||
static bool compare (const Event *e1, const Event *e2) {
|
||||
return e1->before (*e2);
|
||||
}
|
||||
|
||||
void *operator new (size_t) {
|
||||
return pool.alloc ();
|
||||
}
|
||||
|
||||
void operator delete (void *ptr, size_t /*size*/) {
|
||||
pool.release (ptr);
|
||||
}
|
||||
|
||||
static const nframes_t Immediate = 0;
|
||||
|
||||
private:
|
||||
static MultiAllocSingleReleasePool pool;
|
||||
};
|
||||
|
||||
/* creating from an XML file */
|
||||
|
||||
Session (AudioEngine&,
|
||||
|
@ -458,10 +365,6 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
|
||||
void reset_input_monitor_state ();
|
||||
|
||||
void add_event (nframes_t action_frame, Event::Type type, nframes_t target_frame = 0);
|
||||
void remove_event (nframes_t frame, Event::Type type);
|
||||
void clear_events (Event::Type type);
|
||||
|
||||
nframes_t get_block_size() const { return current_block_size; }
|
||||
nframes_t worst_output_latency () const { return _worst_output_latency; }
|
||||
nframes_t worst_input_latency () const { return _worst_input_latency; }
|
||||
|
@ -1160,8 +1063,6 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
|
||||
boost::scoped_ptr<SessionDirectory> _session_dir;
|
||||
|
||||
RingBuffer<Event*> pending_events;
|
||||
|
||||
void hookup_io ();
|
||||
void when_engine_running ();
|
||||
void graph_reordered ();
|
||||
|
@ -1247,27 +1148,6 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
sigc::connection auto_loop_changed_connection;
|
||||
void auto_loop_changed (Location *);
|
||||
|
||||
typedef std::list<Event *> Events;
|
||||
Events events;
|
||||
Events immediate_events;
|
||||
Events::iterator next_event;
|
||||
|
||||
/* there can only ever be one of each of these */
|
||||
|
||||
Event *auto_loop_event;
|
||||
Event *punch_out_event;
|
||||
Event *punch_in_event;
|
||||
|
||||
/* events */
|
||||
|
||||
void dump_events () const;
|
||||
void queue_event (Event *ev);
|
||||
void merge_event (Event*);
|
||||
void replace_event (Event::Type, nframes_t action_frame, nframes_t target = 0);
|
||||
bool _replace_event (Event*);
|
||||
bool _remove_event (Event *);
|
||||
void _clear_event_type (Event::Type);
|
||||
|
||||
void first_stage_init (std::string path, std::string snapshot_name);
|
||||
int second_stage_init (bool new_tracks);
|
||||
void find_current_end ();
|
||||
|
@ -1299,8 +1179,12 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
|
||||
void *do_work();
|
||||
|
||||
/* SessionEventManager interface */
|
||||
|
||||
void queue_event (SessionEvent*);
|
||||
void process_event (SessionEvent*);
|
||||
void set_next_event ();
|
||||
void process_event (Event *ev);
|
||||
void cleanup_event (SessionEvent*,int);
|
||||
|
||||
/* MIDI Machine Control */
|
||||
|
||||
|
@ -1585,34 +1469,12 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
int jack_sync_callback (jack_transport_state_t, jack_position_t*);
|
||||
void reset_jack_connection (jack_client_t* jack);
|
||||
void record_enable_change_all (bool yn);
|
||||
void do_record_enable_change_all (RouteList*, bool);
|
||||
|
||||
XMLNode& state(bool);
|
||||
|
||||
/* click track */
|
||||
|
||||
struct Click {
|
||||
nframes_t start;
|
||||
nframes_t duration;
|
||||
nframes_t offset;
|
||||
const Sample *data;
|
||||
|
||||
Click (nframes_t s, nframes_t d, const Sample *b)
|
||||
: start (s), duration (d), data (b) { offset = 0; }
|
||||
|
||||
void *operator new (size_t) {
|
||||
return pool.alloc ();
|
||||
};
|
||||
|
||||
void operator delete(void *ptr, size_t /*size*/) {
|
||||
pool.release (ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
static Pool pool;
|
||||
};
|
||||
|
||||
typedef std::list<Click*> Clicks;
|
||||
|
||||
Clicks clicks;
|
||||
bool _clicking;
|
||||
boost::shared_ptr<IO> _click_io;
|
||||
|
|
152
libs/ardour/ardour/session_event.h
Normal file
152
libs/ardour/ardour/session_event.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
#ifndef __ardour_session_event_h__
|
||||
#define __ardour_session_event_h__
|
||||
|
||||
#include <list>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
#include "pbd/pool.h"
|
||||
#include "pbd/ringbuffer.h"
|
||||
|
||||
#include "ardour/types.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Slave;
|
||||
class Region;
|
||||
|
||||
struct SessionEvent {
|
||||
enum Type {
|
||||
SetTransportSpeed,
|
||||
SetDiskstreamSpeed,
|
||||
Locate,
|
||||
LocateRoll,
|
||||
LocateRollLocate,
|
||||
SetLoop,
|
||||
PunchIn,
|
||||
PunchOut,
|
||||
RangeStop,
|
||||
RangeLocate,
|
||||
Overwrite,
|
||||
SetSyncSource,
|
||||
Audition,
|
||||
InputConfigurationChange,
|
||||
SetPlayAudioRange,
|
||||
SetRecordEnable,
|
||||
|
||||
/* only one of each of these events can be queued at any one time */
|
||||
|
||||
StopOnce,
|
||||
AutoLoop
|
||||
};
|
||||
|
||||
enum Action {
|
||||
Add,
|
||||
Remove,
|
||||
Replace,
|
||||
Clear
|
||||
};
|
||||
|
||||
Type type;
|
||||
Action action;
|
||||
nframes64_t action_frame;
|
||||
nframes64_t target_frame;
|
||||
double speed;
|
||||
|
||||
union {
|
||||
void* ptr;
|
||||
bool yes_or_no;
|
||||
nframes64_t target2_frame;
|
||||
Slave* slave;
|
||||
Route* route;
|
||||
};
|
||||
|
||||
union {
|
||||
bool second_yes_or_no;
|
||||
RouteList* routes;
|
||||
};
|
||||
|
||||
std::list<AudioRange> audio_range;
|
||||
std::list<MusicRange> music_range;
|
||||
|
||||
boost::shared_ptr<Region> region;
|
||||
|
||||
sigc::signal<void,SessionEvent*,int> Complete;
|
||||
|
||||
SessionEvent (Type t, Action a, nframes_t when, nframes_t where, double spd, bool yn = false, bool yn2 = false)
|
||||
: type (t)
|
||||
, action (a)
|
||||
, action_frame (when)
|
||||
, target_frame (where)
|
||||
, speed (spd)
|
||||
, yes_or_no (yn)
|
||||
, second_yes_or_no (yn2) {}
|
||||
|
||||
void set_ptr (void* p) {
|
||||
ptr = p;
|
||||
}
|
||||
|
||||
bool before (const SessionEvent& other) const {
|
||||
return action_frame < other.action_frame;
|
||||
}
|
||||
|
||||
bool after (const SessionEvent& other) const {
|
||||
return action_frame > other.action_frame;
|
||||
}
|
||||
|
||||
static bool compare (const SessionEvent *e1, const SessionEvent *e2) {
|
||||
return e1->before (*e2);
|
||||
}
|
||||
|
||||
void *operator new (size_t) {
|
||||
return pool.alloc ();
|
||||
}
|
||||
|
||||
void operator delete (void *ptr, size_t /*size*/) {
|
||||
pool.release (ptr);
|
||||
}
|
||||
|
||||
static const nframes_t Immediate = 0;
|
||||
|
||||
private:
|
||||
static MultiAllocSingleReleasePool pool;
|
||||
};
|
||||
|
||||
class SessionEventManager {
|
||||
public:
|
||||
SessionEventManager () : pending_events (2048){}
|
||||
virtual ~SessionEventManager() {}
|
||||
|
||||
void add_event (nframes64_t action_frame, SessionEvent::Type type, nframes64_t target_frame = 0);
|
||||
void remove_event (nframes64_t frame, SessionEvent::Type type);
|
||||
void clear_events (SessionEvent::Type type);
|
||||
|
||||
|
||||
protected:
|
||||
RingBuffer<SessionEvent*> pending_events;
|
||||
typedef std::list<SessionEvent *> Events;
|
||||
Events events;
|
||||
Events immediate_events;
|
||||
Events::iterator next_event;
|
||||
|
||||
/* there can only ever be one of each of these */
|
||||
|
||||
SessionEvent *auto_loop_event;
|
||||
SessionEvent *punch_out_event;
|
||||
SessionEvent *punch_in_event;
|
||||
|
||||
void dump_events () const;
|
||||
void merge_event (SessionEvent*);
|
||||
void replace_event (SessionEvent::Type, nframes64_t action_frame, nframes64_t target = 0);
|
||||
bool _replace_event (SessionEvent*);
|
||||
bool _remove_event (SessionEvent *);
|
||||
void _clear_event_type (SessionEvent::Type);
|
||||
|
||||
virtual void process_event(SessionEvent*) = 0;
|
||||
virtual void queue_event (SessionEvent *ev) = 0;
|
||||
virtual void set_next_event () = 0;
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
||||
#endif /* __ardour_session_event_h__ */
|
|
@ -144,7 +144,6 @@ class Track : public Route
|
|||
FreezeRecord _freeze_record;
|
||||
XMLNode* pending_state;
|
||||
sigc::connection recenable_connection;
|
||||
sigc::connection ic_connection;
|
||||
bool _destructive;
|
||||
|
||||
boost::shared_ptr<RecEnableControllable> _rec_enable_control;
|
||||
|
|
|
@ -1651,15 +1651,6 @@ AudioDiskstream::set_record_enabled (bool yn)
|
|||
return;
|
||||
}
|
||||
|
||||
if (yn && channels.reader()->front()->source == 0) {
|
||||
|
||||
/* pick up connections not initiated *from* the IO object
|
||||
we're associated with.
|
||||
*/
|
||||
|
||||
get_input_sources ();
|
||||
}
|
||||
|
||||
/* yes, i know that this not proof against race conditions, but its
|
||||
good enough. i think.
|
||||
*/
|
||||
|
|
|
@ -193,9 +193,6 @@ AudioTrack::set_diskstream (boost::shared_ptr<AudioDiskstream> ds, void * /*src*
|
|||
_diskstream->set_record_enabled (false);
|
||||
_diskstream->monitor_input (false);
|
||||
|
||||
ic_connection.disconnect();
|
||||
ic_connection = _input->changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change));
|
||||
|
||||
DiskstreamChanged (); /* EMIT SIGNAL */
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -141,6 +141,10 @@ Diskstream::set_route (Route& r)
|
|||
{
|
||||
_route = &r;
|
||||
_io = _route->input();
|
||||
|
||||
ic_connection.disconnect();
|
||||
ic_connection = _io->changed.connect (mem_fun (*this, &Diskstream::handle_input_change));
|
||||
|
||||
input_change_pending = ConfigurationChanged;
|
||||
non_realtime_input_change ();
|
||||
set_align_style_from_io ();
|
||||
|
|
|
@ -76,7 +76,7 @@ setup_enum_writer ()
|
|||
ShuttleBehaviour _ShuttleBehaviour;
|
||||
ShuttleUnits _ShuttleUnits;
|
||||
Session::RecordState _Session_RecordState;
|
||||
Session::Event::Type _Session_Event_Type;
|
||||
SessionEvent::Type _SessionEvent_Type;
|
||||
TimecodeFormat _Session_TimecodeFormat;
|
||||
Session::PullupFormat _Session_PullupFormat;
|
||||
AudioRegion::FadeShape _AudioRegion_FadeShape;
|
||||
|
@ -290,24 +290,25 @@ setup_enum_writer ()
|
|||
REGISTER_CLASS_ENUM (Session, Recording);
|
||||
REGISTER (_Session_RecordState);
|
||||
|
||||
REGISTER_CLASS_ENUM (Session::Event, SetTransportSpeed);
|
||||
REGISTER_CLASS_ENUM (Session::Event, SetDiskstreamSpeed);
|
||||
REGISTER_CLASS_ENUM (Session::Event, Locate);
|
||||
REGISTER_CLASS_ENUM (Session::Event, LocateRoll);
|
||||
REGISTER_CLASS_ENUM (Session::Event, LocateRollLocate);
|
||||
REGISTER_CLASS_ENUM (Session::Event, SetLoop);
|
||||
REGISTER_CLASS_ENUM (Session::Event, PunchIn);
|
||||
REGISTER_CLASS_ENUM (Session::Event, PunchOut);
|
||||
REGISTER_CLASS_ENUM (Session::Event, RangeStop);
|
||||
REGISTER_CLASS_ENUM (Session::Event, RangeLocate);
|
||||
REGISTER_CLASS_ENUM (Session::Event, Overwrite);
|
||||
REGISTER_CLASS_ENUM (Session::Event, SetSyncSource);
|
||||
REGISTER_CLASS_ENUM (Session::Event, Audition);
|
||||
REGISTER_CLASS_ENUM (Session::Event, InputConfigurationChange);
|
||||
REGISTER_CLASS_ENUM (Session::Event, SetPlayAudioRange);
|
||||
REGISTER_CLASS_ENUM (Session::Event, StopOnce);
|
||||
REGISTER_CLASS_ENUM (Session::Event, AutoLoop);
|
||||
REGISTER (_Session_Event_Type);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, SetTransportSpeed);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, SetDiskstreamSpeed);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, Locate);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, LocateRoll);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, LocateRollLocate);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, SetLoop);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, PunchIn);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, PunchOut);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, RangeStop);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, RangeLocate);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, Overwrite);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, SetSyncSource);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, Audition);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, InputConfigurationChange);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, SetPlayAudioRange);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, SetRecordEnable);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, StopOnce);
|
||||
REGISTER_CLASS_ENUM (SessionEvent, AutoLoop);
|
||||
REGISTER (_SessionEvent_Type);
|
||||
|
||||
REGISTER_CLASS_ENUM (Session, Stopped);
|
||||
REGISTER_CLASS_ENUM (Session, Waiting);
|
||||
|
|
|
@ -1128,15 +1128,6 @@ MidiDiskstream::set_record_enabled (bool yn)
|
|||
|
||||
assert(!destructive());
|
||||
|
||||
if (yn && _source_port == 0) {
|
||||
|
||||
/* pick up connections not initiated *from* the IO object
|
||||
we're associated with.
|
||||
*/
|
||||
|
||||
get_input_sources ();
|
||||
}
|
||||
|
||||
/* yes, i know that this not proof against race conditions, but its
|
||||
good enough. i think.
|
||||
*/
|
||||
|
|
|
@ -111,9 +111,6 @@ MidiTrack::set_diskstream (boost::shared_ptr<MidiDiskstream> ds)
|
|||
_diskstream->set_record_enabled (false);
|
||||
//_diskstream->monitor_input (false);
|
||||
|
||||
ic_connection.disconnect();
|
||||
ic_connection = _input->changed.connect (mem_fun (*_diskstream, &MidiDiskstream::handle_input_change));
|
||||
|
||||
DiskstreamChanged (); /* EMIT SIGNAL */
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -133,7 +133,6 @@ Session::Session (AudioEngine &eng,
|
|||
_midi_port (default_midi_port),
|
||||
_midi_clock_port (default_midi_clock_port),
|
||||
_session_dir (new SessionDirectory(fullpath)),
|
||||
pending_events (2048),
|
||||
state_tree (0),
|
||||
_butler (new Butler (this)),
|
||||
_post_transport_work (0),
|
||||
|
@ -219,7 +218,6 @@ Session::Session (AudioEngine &eng,
|
|||
_midi_port (default_midi_port),
|
||||
_midi_clock_port (default_midi_clock_port),
|
||||
_session_dir ( new SessionDirectory(fullpath)),
|
||||
pending_events (2048),
|
||||
state_tree (0),
|
||||
_butler (new Butler (this)),
|
||||
_post_transport_work (0),
|
||||
|
@ -916,7 +914,7 @@ Session::reset_input_monitor_state ()
|
|||
void
|
||||
Session::auto_punch_start_changed (Location* location)
|
||||
{
|
||||
replace_event (Event::PunchIn, location->start());
|
||||
replace_event (SessionEvent::PunchIn, location->start());
|
||||
|
||||
if (get_record_enabled() && config.get_punch_in()) {
|
||||
/* capture start has been changed, so save new pending state */
|
||||
|
@ -929,7 +927,7 @@ Session::auto_punch_end_changed (Location* location)
|
|||
{
|
||||
nframes_t when_to_stop = location->end();
|
||||
// when_to_stop += _worst_output_latency + _worst_input_latency;
|
||||
replace_event (Event::PunchOut, when_to_stop);
|
||||
replace_event (SessionEvent::PunchOut, when_to_stop);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -937,15 +935,15 @@ Session::auto_punch_changed (Location* location)
|
|||
{
|
||||
nframes_t when_to_stop = location->end();
|
||||
|
||||
replace_event (Event::PunchIn, location->start());
|
||||
replace_event (SessionEvent::PunchIn, location->start());
|
||||
//when_to_stop += _worst_output_latency + _worst_input_latency;
|
||||
replace_event (Event::PunchOut, when_to_stop);
|
||||
replace_event (SessionEvent::PunchOut, when_to_stop);
|
||||
}
|
||||
|
||||
void
|
||||
Session::auto_loop_changed (Location* location)
|
||||
{
|
||||
replace_event (Event::AutoLoop, location->end(), location->start());
|
||||
replace_event (SessionEvent::AutoLoop, location->end(), location->start());
|
||||
|
||||
if (transport_rolling() && play_loop) {
|
||||
|
||||
|
@ -954,7 +952,7 @@ Session::auto_loop_changed (Location* location)
|
|||
|
||||
if (_transport_frame < location->start() || _transport_frame > location->end()) {
|
||||
// relocate to beginning of loop
|
||||
clear_events (Event::LocateRoll);
|
||||
clear_events (SessionEvent::LocateRoll);
|
||||
|
||||
request_locate (location->start(), true);
|
||||
|
||||
|
@ -966,8 +964,8 @@ Session::auto_loop_changed (Location* location)
|
|||
loop_changing = true;
|
||||
|
||||
if (location->end() > last_loopend) {
|
||||
clear_events (Event::LocateRoll);
|
||||
Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
|
||||
clear_events (SessionEvent::LocateRoll);
|
||||
SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
|
@ -987,8 +985,8 @@ Session::set_auto_punch_location (Location* location)
|
|||
auto_punch_end_changed_connection.disconnect();
|
||||
auto_punch_changed_connection.disconnect();
|
||||
existing->set_auto_punch (false, this);
|
||||
remove_event (existing->start(), Event::PunchIn);
|
||||
clear_events (Event::PunchOut);
|
||||
remove_event (existing->start(), SessionEvent::PunchIn);
|
||||
clear_events (SessionEvent::PunchOut);
|
||||
auto_punch_location_changed (0);
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1027,7 @@ Session::set_auto_loop_location (Location* location)
|
|||
auto_loop_end_changed_connection.disconnect();
|
||||
auto_loop_changed_connection.disconnect();
|
||||
existing->set_auto_loop (false, this);
|
||||
remove_event (existing->end(), Event::AutoLoop);
|
||||
remove_event (existing->end(), SessionEvent::AutoLoop);
|
||||
auto_loop_location_changed (0);
|
||||
}
|
||||
|
||||
|
@ -3424,7 +3422,7 @@ Session::set_audition (boost::shared_ptr<Region> r)
|
|||
void
|
||||
Session::audition_playlist ()
|
||||
{
|
||||
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
|
||||
ev->region.reset ();
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -3444,7 +3442,7 @@ Session::non_realtime_set_audition ()
|
|||
void
|
||||
Session::audition_region (boost::shared_ptr<Region> r)
|
||||
{
|
||||
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
|
||||
ev->region = r;
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -3601,12 +3599,20 @@ Session::graph_reordered ()
|
|||
void
|
||||
Session::record_disenable_all ()
|
||||
{
|
||||
if (!writable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
record_enable_change_all (false);
|
||||
}
|
||||
|
||||
void
|
||||
Session::record_enable_all ()
|
||||
{
|
||||
if (!writable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
record_enable_change_all (true);
|
||||
}
|
||||
|
||||
|
@ -3614,16 +3620,33 @@ void
|
|||
Session::record_enable_change_all (bool yn)
|
||||
{
|
||||
shared_ptr<RouteList> r = routes.reader ();
|
||||
RouteList* tracks = new RouteList;
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
boost::shared_ptr<Track> t;
|
||||
|
||||
if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
|
||||
tracks->push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetRecordEnable, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, yn);
|
||||
|
||||
ev->routes = tracks;
|
||||
ev->Complete.connect (mem_fun (*this, &Session::cleanup_event));
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
Session::do_record_enable_change_all (RouteList* rl, bool yn)
|
||||
{
|
||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||
boost::shared_ptr<Track> t;
|
||||
|
||||
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
|
||||
t->set_record_enable (yn, this);
|
||||
}
|
||||
}
|
||||
|
||||
/* since we don't keep rec-enable state, don't mark session dirty */
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -75,7 +75,7 @@ Session::schedule_curve_reallocation ()
|
|||
void
|
||||
Session::request_overwrite_buffer (Diskstream* stream)
|
||||
{
|
||||
Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0);
|
||||
SessionEvent *ev = new SessionEvent (SessionEvent::Overwrite, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0);
|
||||
ev->set_ptr (stream);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 20002 Paul Davis
|
||||
Copyright (C) 2002 Paul Davis
|
||||
|
||||
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
|
||||
|
@ -35,7 +35,7 @@ using namespace std;
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Pool Session::Click::pool ("click", sizeof (Click), 128);
|
||||
Pool Click::pool ("click", sizeof (Click), 128);
|
||||
|
||||
void
|
||||
Session::click (nframes_t start, nframes_t nframes)
|
||||
|
|
|
@ -24,13 +24,12 @@
|
|||
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/enumwriter.h"
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/audio_diskstream.h"
|
||||
#include "ardour/butler.h"
|
||||
#include "ardour/debug.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/session_event.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
@ -38,39 +37,39 @@ using namespace std;
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
MultiAllocSingleReleasePool Session::Event::pool ("event", sizeof (Session::Event), 512);
|
||||
MultiAllocSingleReleasePool SessionEvent::pool ("event", sizeof (SessionEvent), 512);
|
||||
|
||||
void
|
||||
Session::add_event (nframes_t frame, Event::Type type, nframes_t target_frame)
|
||||
SessionEventManager::add_event (nframes64_t frame, SessionEvent::Type type, nframes64_t target_frame)
|
||||
{
|
||||
Event* ev = new Event (type, Event::Add, frame, target_frame, 0);
|
||||
SessionEvent* ev = new SessionEvent (type, SessionEvent::Add, frame, target_frame, 0);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
Session::remove_event (nframes_t frame, Event::Type type)
|
||||
SessionEventManager::remove_event (nframes64_t frame, SessionEvent::Type type)
|
||||
{
|
||||
Event* ev = new Event (type, Event::Remove, frame, 0, 0);
|
||||
SessionEvent* ev = new SessionEvent (type, SessionEvent::Remove, frame, 0, 0);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
Session::replace_event (Event::Type type, nframes_t frame, nframes_t target)
|
||||
SessionEventManager::replace_event (SessionEvent::Type type, nframes64_t frame, nframes64_t target)
|
||||
{
|
||||
Event* ev = new Event (type, Event::Replace, frame, target, 0);
|
||||
SessionEvent* ev = new SessionEvent (type, SessionEvent::Replace, frame, target, 0);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
Session::clear_events (Event::Type type)
|
||||
SessionEventManager::clear_events (SessionEvent::Type type)
|
||||
{
|
||||
Event* ev = new Event (type, Event::Clear, 0, 0, 0);
|
||||
SessionEvent* ev = new SessionEvent (type, SessionEvent::Clear, 0, 0, 0);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Session::dump_events () const
|
||||
SessionEventManager::dump_events () const
|
||||
{
|
||||
cerr << "EVENT DUMP" << endl;
|
||||
for (Events::const_iterator i = events.begin(); i != events.end(); ++i) {
|
||||
|
@ -93,34 +92,24 @@ Session::dump_events () const
|
|||
}
|
||||
|
||||
void
|
||||
Session::queue_event (Event* ev)
|
||||
{
|
||||
if (_state_of_the_state & Loading) {
|
||||
merge_event (ev);
|
||||
} else {
|
||||
pending_events.write (&ev, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::merge_event (Event* ev)
|
||||
SessionEventManager::merge_event (SessionEvent* ev)
|
||||
{
|
||||
switch (ev->action) {
|
||||
case Event::Remove:
|
||||
case SessionEvent::Remove:
|
||||
_remove_event (ev);
|
||||
delete ev;
|
||||
return;
|
||||
|
||||
case Event::Replace:
|
||||
case SessionEvent::Replace:
|
||||
_replace_event (ev);
|
||||
return;
|
||||
|
||||
case Event::Clear:
|
||||
case SessionEvent::Clear:
|
||||
_clear_event_type (ev->type);
|
||||
delete ev;
|
||||
return;
|
||||
|
||||
case Event::Add:
|
||||
case SessionEvent::Add:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -132,8 +121,8 @@ Session::merge_event (Event* ev)
|
|||
}
|
||||
|
||||
switch (ev->type) {
|
||||
case Event::AutoLoop:
|
||||
case Event::StopOnce:
|
||||
case SessionEvent::AutoLoop:
|
||||
case SessionEvent::StopOnce:
|
||||
_clear_event_type (ev->type);
|
||||
break;
|
||||
|
||||
|
@ -148,14 +137,14 @@ Session::merge_event (Event* ev)
|
|||
}
|
||||
|
||||
events.insert (events.begin(), ev);
|
||||
events.sort (Event::compare);
|
||||
events.sort (SessionEvent::compare);
|
||||
next_event = events.begin();
|
||||
set_next_event ();
|
||||
}
|
||||
|
||||
/** @return true when @a ev is deleted. */
|
||||
bool
|
||||
Session::_replace_event (Event* ev)
|
||||
SessionEventManager::_replace_event (SessionEvent* ev)
|
||||
{
|
||||
bool ret = false;
|
||||
Events::iterator i;
|
||||
|
@ -178,7 +167,7 @@ Session::_replace_event (Event* ev)
|
|||
events.insert (events.begin(), ev);
|
||||
}
|
||||
|
||||
events.sort (Event::compare);
|
||||
events.sort (SessionEvent::compare);
|
||||
next_event = events.end();
|
||||
set_next_event ();
|
||||
|
||||
|
@ -187,7 +176,7 @@ Session::_replace_event (Event* ev)
|
|||
|
||||
/** @return true when @a ev is deleted. */
|
||||
bool
|
||||
Session::_remove_event (Session::Event* ev)
|
||||
SessionEventManager::_remove_event (SessionEvent* ev)
|
||||
{
|
||||
bool ret = false;
|
||||
Events::iterator i;
|
||||
|
@ -215,7 +204,7 @@ Session::_remove_event (Session::Event* ev)
|
|||
}
|
||||
|
||||
void
|
||||
Session::_clear_event_type (Event::Type type)
|
||||
SessionEventManager::_clear_event_type (SessionEvent::Type type)
|
||||
{
|
||||
Events::iterator i, tmp;
|
||||
|
||||
|
@ -251,179 +240,3 @@ Session::_clear_event_type (Event::Type type)
|
|||
set_next_event ();
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_next_event ()
|
||||
{
|
||||
if (events.empty()) {
|
||||
next_event = events.end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (next_event == events.end()) {
|
||||
next_event = events.begin();
|
||||
}
|
||||
|
||||
if ((*next_event)->action_frame > _transport_frame) {
|
||||
next_event = events.begin();
|
||||
}
|
||||
|
||||
for (; next_event != events.end(); ++next_event) {
|
||||
if ((*next_event)->action_frame >= _transport_frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::process_event (Event* ev)
|
||||
{
|
||||
bool remove = true;
|
||||
bool del = true;
|
||||
|
||||
/* if we're in the middle of a state change (i.e. waiting
|
||||
for the butler thread to complete the non-realtime
|
||||
part of the change), we'll just have to queue this
|
||||
event for a time when the change is complete.
|
||||
*/
|
||||
|
||||
if (non_realtime_work_pending()) {
|
||||
|
||||
/* except locates, which we have the capability to handle */
|
||||
|
||||
if (ev->type != Event::Locate) {
|
||||
immediate_events.insert (immediate_events.end(), ev);
|
||||
_remove_event (ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
|
||||
|
||||
switch (ev->type) {
|
||||
case Event::SetLoop:
|
||||
set_play_loop (ev->yes_or_no);
|
||||
break;
|
||||
|
||||
case Event::AutoLoop:
|
||||
if (play_loop) {
|
||||
start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case Event::Locate:
|
||||
if (ev->yes_or_no) {
|
||||
// cerr << "forced locate to " << ev->target_frame << endl;
|
||||
locate (ev->target_frame, false, true, false);
|
||||
} else {
|
||||
// cerr << "soft locate to " << ev->target_frame << endl;
|
||||
start_locate (ev->target_frame, false, true, false);
|
||||
}
|
||||
_send_timecode_update = true;
|
||||
break;
|
||||
|
||||
case Event::LocateRoll:
|
||||
if (ev->yes_or_no) {
|
||||
// cerr << "forced locate to+roll " << ev->target_frame << endl;
|
||||
locate (ev->target_frame, true, true, false);
|
||||
} else {
|
||||
// cerr << "soft locate to+roll " << ev->target_frame << endl;
|
||||
start_locate (ev->target_frame, true, true, false);
|
||||
}
|
||||
_send_timecode_update = true;
|
||||
break;
|
||||
|
||||
case Event::LocateRollLocate:
|
||||
// locate is handled by ::request_roll_at_and_return()
|
||||
_requested_return_frame = ev->target_frame;
|
||||
request_locate (ev->target2_frame, true);
|
||||
break;
|
||||
|
||||
|
||||
case Event::SetTransportSpeed:
|
||||
set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
|
||||
break;
|
||||
|
||||
case Event::PunchIn:
|
||||
// cerr << "PunchIN at " << transport_frame() << endl;
|
||||
if (config.get_punch_in() && record_status() == Enabled) {
|
||||
enable_record ();
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case Event::PunchOut:
|
||||
// cerr << "PunchOUT at " << transport_frame() << endl;
|
||||
if (config.get_punch_out()) {
|
||||
step_back_from_record ();
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case Event::StopOnce:
|
||||
if (!non_realtime_work_pending()) {
|
||||
stop_transport (ev->yes_or_no);
|
||||
_clear_event_type (Event::StopOnce);
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case Event::RangeStop:
|
||||
if (!non_realtime_work_pending()) {
|
||||
stop_transport (ev->yes_or_no);
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case Event::RangeLocate:
|
||||
start_locate (ev->target_frame, true, true, false);
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case Event::Overwrite:
|
||||
overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
|
||||
break;
|
||||
|
||||
case Event::SetDiskstreamSpeed:
|
||||
set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
|
||||
break;
|
||||
|
||||
case Event::SetSyncSource:
|
||||
use_sync_source (ev->slave);
|
||||
break;
|
||||
|
||||
case Event::Audition:
|
||||
set_audition (ev->region);
|
||||
// drop reference to region
|
||||
ev->region.reset ();
|
||||
break;
|
||||
|
||||
case Event::InputConfigurationChange:
|
||||
add_post_transport_work (PostTransportInputChange);
|
||||
_butler->schedule_transport_work ();
|
||||
break;
|
||||
|
||||
case Event::SetPlayAudioRange:
|
||||
set_play_range (ev->audio_range, (ev->speed == 1.0f));
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
};
|
||||
|
||||
if (remove) {
|
||||
del = del && !_remove_event (ev);
|
||||
}
|
||||
|
||||
if (del) {
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/enumwriter.h"
|
||||
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
|
@ -274,7 +275,7 @@ Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
|
|||
void
|
||||
Session::process_with_events (nframes_t nframes)
|
||||
{
|
||||
Event* ev;
|
||||
SessionEvent* ev;
|
||||
nframes_t this_nframes;
|
||||
nframes_t end_frame;
|
||||
bool session_needs_butler = false;
|
||||
|
@ -299,7 +300,7 @@ Session::process_with_events (nframes_t nframes)
|
|||
*/
|
||||
|
||||
while (!non_realtime_work_pending() && !immediate_events.empty()) {
|
||||
Event *ev = immediate_events.front ();
|
||||
SessionEvent *ev = immediate_events.front ();
|
||||
immediate_events.pop_front ();
|
||||
process_event (ev);
|
||||
}
|
||||
|
@ -334,7 +335,7 @@ Session::process_with_events (nframes_t nframes)
|
|||
end_frame = _transport_frame + (nframes_t)frames_moved;
|
||||
|
||||
{
|
||||
Event* this_event;
|
||||
SessionEvent* this_event;
|
||||
Events::iterator the_next_one;
|
||||
|
||||
if (!process_can_proceed()) {
|
||||
|
@ -863,7 +864,7 @@ Session::process_without_events (nframes_t nframes)
|
|||
void
|
||||
Session::process_audition (nframes_t nframes)
|
||||
{
|
||||
Event* ev;
|
||||
SessionEvent* ev;
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
|
@ -890,7 +891,7 @@ Session::process_audition (nframes_t nframes)
|
|||
*/
|
||||
|
||||
while (!non_realtime_work_pending() && !immediate_events.empty()) {
|
||||
Event *ev = immediate_events.front ();
|
||||
SessionEvent *ev = immediate_events.front ();
|
||||
immediate_events.pop_front ();
|
||||
process_event (ev);
|
||||
}
|
||||
|
@ -947,3 +948,209 @@ Session::maybe_sync_start (nframes_t& nframes)
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Session::queue_event (SessionEvent* ev)
|
||||
{
|
||||
if (_state_of_the_state & Deletion) {
|
||||
return;
|
||||
} else if (_state_of_the_state & Loading) {
|
||||
merge_event (ev);
|
||||
} else {
|
||||
pending_events.write (&ev, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_next_event ()
|
||||
{
|
||||
if (events.empty()) {
|
||||
next_event = events.end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (next_event == events.end()) {
|
||||
next_event = events.begin();
|
||||
}
|
||||
|
||||
if ((*next_event)->action_frame > _transport_frame) {
|
||||
next_event = events.begin();
|
||||
}
|
||||
|
||||
for (; next_event != events.end(); ++next_event) {
|
||||
if ((*next_event)->action_frame >= _transport_frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::cleanup_event (SessionEvent* ev, int status)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case SessionEvent::SetRecordEnable:
|
||||
delete ev->routes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::process_event (SessionEvent* ev)
|
||||
{
|
||||
bool remove = true;
|
||||
bool del = true;
|
||||
|
||||
/* if we're in the middle of a state change (i.e. waiting
|
||||
for the butler thread to complete the non-realtime
|
||||
part of the change), we'll just have to queue this
|
||||
event for a time when the change is complete.
|
||||
*/
|
||||
|
||||
if (non_realtime_work_pending()) {
|
||||
|
||||
/* except locates, which we have the capability to handle */
|
||||
|
||||
if (ev->type != SessionEvent::Locate) {
|
||||
immediate_events.insert (immediate_events.end(), ev);
|
||||
_remove_event (ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
|
||||
|
||||
switch (ev->type) {
|
||||
case SessionEvent::SetLoop:
|
||||
set_play_loop (ev->yes_or_no);
|
||||
break;
|
||||
|
||||
case SessionEvent::AutoLoop:
|
||||
if (play_loop) {
|
||||
start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case SessionEvent::Locate:
|
||||
if (ev->yes_or_no) {
|
||||
// cerr << "forced locate to " << ev->target_frame << endl;
|
||||
locate (ev->target_frame, false, true, false);
|
||||
} else {
|
||||
// cerr << "soft locate to " << ev->target_frame << endl;
|
||||
start_locate (ev->target_frame, false, true, false);
|
||||
}
|
||||
_send_timecode_update = true;
|
||||
break;
|
||||
|
||||
case SessionEvent::LocateRoll:
|
||||
if (ev->yes_or_no) {
|
||||
// cerr << "forced locate to+roll " << ev->target_frame << endl;
|
||||
locate (ev->target_frame, true, true, false);
|
||||
} else {
|
||||
// cerr << "soft locate to+roll " << ev->target_frame << endl;
|
||||
start_locate (ev->target_frame, true, true, false);
|
||||
}
|
||||
_send_timecode_update = true;
|
||||
break;
|
||||
|
||||
case SessionEvent::LocateRollLocate:
|
||||
// locate is handled by ::request_roll_at_and_return()
|
||||
_requested_return_frame = ev->target_frame;
|
||||
request_locate (ev->target2_frame, true);
|
||||
break;
|
||||
|
||||
|
||||
case SessionEvent::SetTransportSpeed:
|
||||
set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
|
||||
break;
|
||||
|
||||
case SessionEvent::PunchIn:
|
||||
// cerr << "PunchIN at " << transport_frame() << endl;
|
||||
if (config.get_punch_in() && record_status() == Enabled) {
|
||||
enable_record ();
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case SessionEvent::PunchOut:
|
||||
// cerr << "PunchOUT at " << transport_frame() << endl;
|
||||
if (config.get_punch_out()) {
|
||||
step_back_from_record ();
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case SessionEvent::StopOnce:
|
||||
if (!non_realtime_work_pending()) {
|
||||
stop_transport (ev->yes_or_no);
|
||||
_clear_event_type (SessionEvent::StopOnce);
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case SessionEvent::RangeStop:
|
||||
if (!non_realtime_work_pending()) {
|
||||
stop_transport (ev->yes_or_no);
|
||||
}
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case SessionEvent::RangeLocate:
|
||||
start_locate (ev->target_frame, true, true, false);
|
||||
remove = false;
|
||||
del = false;
|
||||
break;
|
||||
|
||||
case SessionEvent::Overwrite:
|
||||
overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
|
||||
break;
|
||||
|
||||
case SessionEvent::SetDiskstreamSpeed:
|
||||
set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
|
||||
break;
|
||||
|
||||
case SessionEvent::SetSyncSource:
|
||||
use_sync_source (ev->slave);
|
||||
break;
|
||||
|
||||
case SessionEvent::Audition:
|
||||
set_audition (ev->region);
|
||||
// drop reference to region
|
||||
ev->region.reset ();
|
||||
break;
|
||||
|
||||
case SessionEvent::InputConfigurationChange:
|
||||
add_post_transport_work (PostTransportInputChange);
|
||||
_butler->schedule_transport_work ();
|
||||
break;
|
||||
|
||||
case SessionEvent::SetPlayAudioRange:
|
||||
set_play_range (ev->audio_range, (ev->speed == 1.0f));
|
||||
break;
|
||||
|
||||
case SessionEvent::SetRecordEnable:
|
||||
do_record_enable_change_all (ev->routes, ev->yes_or_no);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
};
|
||||
|
||||
if (remove) {
|
||||
del = del && !_remove_event (ev);
|
||||
}
|
||||
|
||||
ev->Complete (ev, 0); /* EMIT SIGNAL */
|
||||
|
||||
if (del) {
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2947,9 +2947,9 @@ Session::config_changed (std::string p, bool ours)
|
|||
if ((location = _locations.auto_punch_location()) != 0) {
|
||||
|
||||
if (config.get_punch_in ()) {
|
||||
replace_event (Event::PunchIn, location->start());
|
||||
replace_event (SessionEvent::PunchIn, location->start());
|
||||
} else {
|
||||
remove_event (location->start(), Event::PunchIn);
|
||||
remove_event (location->start(), SessionEvent::PunchIn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2960,9 +2960,9 @@ Session::config_changed (std::string p, bool ours)
|
|||
if ((location = _locations.auto_punch_location()) != 0) {
|
||||
|
||||
if (config.get_punch_out()) {
|
||||
replace_event (Event::PunchOut, location->end());
|
||||
replace_event (SessionEvent::PunchOut, location->end());
|
||||
} else {
|
||||
clear_events (Event::PunchOut);
|
||||
clear_events (SessionEvent::PunchOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ void
|
|||
Session::request_input_change_handling ()
|
||||
{
|
||||
if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
|
||||
Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
|
||||
queue_event (ev);
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ Session::request_input_change_handling ()
|
|||
void
|
||||
Session::request_sync_source (Slave* new_slave)
|
||||
{
|
||||
Event* ev = new Event (Event::SetSyncSource, Event::Add, Event::Immediate, 0, 0.0);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
|
||||
bool seamless;
|
||||
|
||||
seamless = Config->get_seamless_loop ();
|
||||
|
@ -104,7 +104,7 @@ Session::request_sync_source (Slave* new_slave)
|
|||
void
|
||||
Session::request_transport_speed (double speed)
|
||||
{
|
||||
Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed));
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ Session::request_transport_speed (double speed)
|
|||
void
|
||||
Session::request_diskstream_speed (Diskstream& ds, double speed)
|
||||
{
|
||||
Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetDiskstreamSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
|
||||
ev->set_ptr (&ds);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ Session::request_diskstream_speed (Diskstream& ds, double speed)
|
|||
void
|
||||
Session::request_stop (bool abort, bool clear_state)
|
||||
{
|
||||
Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort, clear_state);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ Session::request_stop (bool abort, bool clear_state)
|
|||
void
|
||||
Session::request_locate (nframes_t target_frame, bool with_roll)
|
||||
{
|
||||
Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
|
||||
SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ Session::request_locate (nframes_t target_frame, bool with_roll)
|
|||
void
|
||||
Session::force_locate (nframes64_t target_frame, bool with_roll)
|
||||
{
|
||||
Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
|
||||
SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
|
||||
queue_event (ev);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ Session::force_locate (nframes64_t target_frame, bool with_roll)
|
|||
void
|
||||
Session::request_play_loop (bool yn, bool leave_rolling)
|
||||
{
|
||||
Event* ev;
|
||||
SessionEvent* ev;
|
||||
Location *location = _locations.auto_loop_location();
|
||||
|
||||
if (location == 0 && yn) {
|
||||
|
@ -153,7 +153,7 @@ Session::request_play_loop (bool yn, bool leave_rolling)
|
|||
return;
|
||||
}
|
||||
|
||||
ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
|
||||
ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
|
||||
queue_event (ev);
|
||||
|
||||
|
@ -167,7 +167,7 @@ Session::request_play_loop (bool yn, bool leave_rolling)
|
|||
void
|
||||
Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
|
||||
{
|
||||
Event* ev = new Event (Event::SetPlayAudioRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
|
||||
if (range) {
|
||||
ev->audio_range = *range;
|
||||
} else {
|
||||
|
@ -222,9 +222,9 @@ Session::realtime_stop (bool abort, bool clear_state)
|
|||
add_post_transport_work (todo);
|
||||
}
|
||||
|
||||
_clear_event_type (Event::StopOnce);
|
||||
_clear_event_type (Event::RangeStop);
|
||||
_clear_event_type (Event::RangeLocate);
|
||||
_clear_event_type (SessionEvent::StopOnce);
|
||||
_clear_event_type (SessionEvent::RangeStop);
|
||||
_clear_event_type (SessionEvent::RangeLocate);
|
||||
|
||||
disable_record (true);
|
||||
|
||||
|
@ -615,7 +615,7 @@ void
|
|||
Session::unset_play_loop ()
|
||||
{
|
||||
play_loop = false;
|
||||
clear_events (Event::AutoLoop);
|
||||
clear_events (SessionEvent::AutoLoop);
|
||||
|
||||
// set all diskstreams to NOT use internal looping
|
||||
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
|
||||
|
@ -676,7 +676,7 @@ Session::set_play_loop (bool yn)
|
|||
|
||||
/* put the loop event into the event list */
|
||||
|
||||
Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
|
||||
SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
|
||||
merge_event (event);
|
||||
|
||||
/* locate to start of loop and roll. If doing seamless loop, force a
|
||||
|
@ -1033,7 +1033,7 @@ Session::stop_transport (bool abort, bool clear_state)
|
|||
and then we'll really be stopped.
|
||||
*/
|
||||
|
||||
Event *ev = new Event (Event::StopOnce, Event::Replace,
|
||||
SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
|
||||
_transport_frame + _worst_output_latency - current_block_size,
|
||||
0, 0, abort);
|
||||
|
||||
|
@ -1276,14 +1276,14 @@ void
|
|||
Session::unset_play_range ()
|
||||
{
|
||||
_play_range = false;
|
||||
_clear_event_type (Event::RangeStop);
|
||||
_clear_event_type (Event::RangeLocate);
|
||||
_clear_event_type (SessionEvent::RangeStop);
|
||||
_clear_event_type (SessionEvent::RangeLocate);
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
|
||||
{
|
||||
Event* ev;
|
||||
SessionEvent* ev;
|
||||
|
||||
/* Called from event-processing context */
|
||||
|
||||
|
@ -1294,7 +1294,7 @@ Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
|
|||
*/
|
||||
if (!leave_rolling) {
|
||||
/* stop transport */
|
||||
Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
|
||||
SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
|
||||
merge_event (ev);
|
||||
}
|
||||
return;
|
||||
|
@ -1329,9 +1329,9 @@ Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
|
|||
}
|
||||
|
||||
if (next == range.end()) {
|
||||
ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
|
||||
ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
|
||||
} else {
|
||||
ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
|
||||
ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
|
||||
}
|
||||
|
||||
merge_event (ev);
|
||||
|
@ -1341,7 +1341,7 @@ Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
|
|||
|
||||
} else if (sz == 1) {
|
||||
|
||||
ev = new Event (Event::RangeStop, Event::Add, range.front().end, 0, 0.0f);
|
||||
ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
|
||||
merge_event (ev);
|
||||
|
||||
}
|
||||
|
@ -1352,7 +1352,7 @@ Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
|
|||
|
||||
/* now start rolling at the right place */
|
||||
|
||||
ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, range.front().start, 0.0f, false);
|
||||
ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
|
||||
merge_event (ev);
|
||||
|
||||
TransportStateChange ();
|
||||
|
@ -1370,7 +1370,7 @@ Session::request_bounded_roll (nframes_t start, nframes_t end)
|
|||
void
|
||||
Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
|
||||
{
|
||||
Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
|
||||
SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
|
||||
ev->target2_frame = start;
|
||||
queue_event (ev);
|
||||
}
|
||||
|
|
|
@ -192,13 +192,17 @@ Track::set_record_enable (bool yn, void *src)
|
|||
|
||||
_diskstream->set_record_enabled (yn);
|
||||
|
||||
#if 0
|
||||
if (_diskstream->record_enabled()) {
|
||||
set_meter_point (MeterInput, this);
|
||||
} else {
|
||||
set_meter_point (_saved_meter_point, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
cerr << "4\n";
|
||||
_rec_enable_control->Changed ();
|
||||
cerr << "5\n";
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user