/*
- Copyright (C) 1999-2004 Paul Davis
+ Copyright (C) 1999-2004 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
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
#include <cmath>
#include <unistd.h>
-#include <ardour/timestamps.h>
+#include "ardour/timestamps.h"
-#include <pbd/error.h>
+#include "pbd/error.h"
+#include "pbd/enumwriter.h"
#include <glibmm/thread.h>
-#include <ardour/ardour.h>
-#include <ardour/session.h>
-#include <ardour/audio_diskstream.h>
+#include "ardour/ardour.h"
+#include "ardour/audio_diskstream.h"
+#include "ardour/butler.h"
+#include "ardour/session.h"
#include "i18n.h"
+using namespace std;
using namespace ARDOUR;
using namespace PBD;
MultiAllocSingleReleasePool Session::Event::pool ("event", sizeof (Session::Event), 512);
-static const char* event_names[] = {
- "SetTransportSpeed",
- "SetDiskstreamSpeed",
- "Locate",
- "LocateRoll",
- "SetLoop",
- "PunchIn",
- "PunchOut",
- "RangeStop",
- "RangeLocate",
- "Overwrite",
- "SetSlaveSource",
- "Audition",
- "InputConfigurationChange",
- "SetAudioRange",
- "SetMusicRange",
- "SetPlayRange",
- "StopOnce",
- "AutoLoop"
-};
-
void
-Session::add_event (jack_nframes_t frame, Event::Type type, jack_nframes_t target_frame)
+Session::add_event (nframes_t frame, Event::Type type, nframes_t target_frame)
{
Event* ev = new Event (type, Event::Add, frame, target_frame, 0);
queue_event (ev);
}
void
-Session::remove_event (jack_nframes_t frame, Event::Type type)
+Session::remove_event (nframes_t frame, Event::Type type)
{
Event* ev = new Event (type, Event::Remove, frame, 0, 0);
queue_event (ev);
}
void
-Session::replace_event (Event::Type type, jack_nframes_t frame, jack_nframes_t target)
+Session::replace_event (Event::Type type, nframes_t frame, nframes_t target)
{
Event* ev = new Event (type, Event::Replace, frame, target, 0);
queue_event (ev);
if ((Events::const_iterator) next_event == events.end()) {
cerr << "none" << endl;
} else {
- cerr << "at " << (*next_event)->action_frame << ' '
- << (*next_event)->type << " target = "
+ cerr << "at " << (*next_event)->action_frame << ' '
+ << (*next_event)->type << " target = "
<< (*next_event)->target_frame << endl;
}
cerr << "Immediate events pending:\n";
_clear_event_type (ev->type);
delete ev;
return;
-
+
case Event::Add:
break;
}
process_event (ev);
return;
}
-
+
switch (ev->type) {
case Event::AutoLoop:
case Event::StopOnce:
default:
for (Events::iterator i = events.begin(); i != events.end(); ++i) {
if ((*i)->type == ev->type && (*i)->action_frame == ev->action_frame) {
- error << string_compose(_("Session: cannot have two events of type %1 at the same frame (%2)."),
- event_names[ev->type], ev->action_frame) << endmsg;
+ error << string_compose(_("Session: cannot have two events of type %1 at the same frame (%2)."),
+ enum_2_string (ev->type), ev->action_frame) << endmsg;
return;
}
}
{
bool ret = false;
Events::iterator i;
-
+
for (i = events.begin(); i != events.end(); ++i) {
if ((*i)->type == ev->type && (*i)->action_frame == ev->action_frame) {
if ((*i) == ev) {
Session::_clear_event_type (Event::Type type)
{
Events::iterator i, tmp;
-
+
for (i = events.begin(); i != events.end(); ) {
tmp = i;
if (events.empty()) {
next_event = events.end();
return;
- }
+ }
if (next_event == events.end()) {
next_event = events.begin();
*/
if (non_realtime_work_pending()) {
- immediate_events.insert (immediate_events.end(), ev);
- _remove_event (ev);
- return;
+
+ /* 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;
+ }
}
//printf("Processing event: %s\n", event_names[ev->type]);
switch (ev->type) {
case Event::SetLoop:
- set_auto_loop (ev->yes_or_no);
+ 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:
// cerr << "soft locate to " << ev->target_frame << endl;
start_locate (ev->target_frame, false, true, false);
}
- _send_smpte_update = true;
+ _send_timecode_update = true;
break;
case Event::LocateRoll:
// cerr << "soft locate to+roll " << ev->target_frame << endl;
start_locate (ev->target_frame, true, true, false);
}
- _send_smpte_update = true;
+ _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);
+ 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 (punch_in && record_status() == Enabled) {
+ 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 (punch_out) {
+ if (config.get_punch_out()) {
step_back_from_record ();
}
remove = false;
remove = false;
del = false;
break;
-
+
case Event::RangeLocate:
start_locate (ev->target_frame, true, true, false);
remove = false;
del = false;
break;
- case Event::AutoLoop:
- if (auto_loop) {
- start_locate (ev->target_frame, true, false, seamless_loop);
- }
- remove = false;
- del = false;
- break;
-
case Event::Overwrite:
- overwrite_some_buffers (static_cast<AudioDiskstream*>(ev->ptr));
+ 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::SetSlaveSource:
- set_slave_source (ev->slave, ev->target_frame);
+ case Event::SetSyncSource:
+ use_sync_source (ev->sync_source);
break;
case Event::Audition:
- set_audition (static_cast<AudioRegion*> (ev->ptr));
+ set_audition (ev->region);
+ // drop reference to region
+ ev->region.reset ();
break;
case Event::InputConfigurationChange:
- post_transport_work = PostTransportWork (post_transport_work | PostTransportInputChange);
- schedule_butler_transport_work ();
- break;
-
- case Event::SetAudioRange:
- current_audio_range = ev->audio_range;
- setup_auto_play ();
+ add_post_transport_work (PostTransportInputChange);
+ _butler->schedule_transport_work ();
break;
- case Event::SetPlayRange:
- set_play_range (ev->yes_or_no);
+ case Event::SetPlayAudioRange:
+ set_play_range (ev->audio_range, (ev->speed == 1.0f));
break;
default: