; (gtk_accel_path "<Actions>/JACK/JACKReconnect" "")
; (gtk_accel_path "<Actions>/Editor/Autoconnect" "")
; (gtk_accel_path "<Actions>/Editor/Edit" "")
-(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-end" "<%PRIMARY%>comma")
+(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "comma")
+(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-sync" "<%PRIMARY%>comma")
; (gtk_accel_path "<Actions>/redirectmenu/copy" "")
; (gtk_accel_path "<Actions>/options/MeterFalloffFaster" "")
(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<%PRIMARY%>space")
; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "")
; (gtk_accel_path "<Actions>/RegionList/rlHide" "")
; (gtk_accel_path "<Actions>/Main/Metering" "")
-(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-end" "<%PRIMARY%>period")
+(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-sync" "<%PRIMARY%>period")
; (gtk_accel_path "<Actions>/Zoom/zoom-focus-playhead" "")
; (gtk_accel_path "<Actions>/Editor/center-edit-cursor" "")
; (gtk_accel_path "<Actions>/Editor/Monitoring" "")
(gtk_accel_path "<Actions>/Editor/undo" "<%PRIMARY%>z")
(gtk_accel_path "<Actions>/Editor/insert-region" "i")
; (gtk_accel_path "<Actions>/Editor/center-playhead" "")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-start" "bracketright")
; (gtk_accel_path "<Actions>/Snap/snap-to-region-start" "")
; (gtk_accel_path "<Actions>/Editor/View" "")
; (gtk_accel_path "<Actions>/Editor/Layering" "")
(gtk_accel_path "<Actions>/Editor/set-edit-point" "e")
; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "")
; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "")
-(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "comma")
; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "")
; (gtk_accel_path "<Actions>/redirectmenu/activate_all" "")
; (gtk_accel_path "<Actions>/redirectmenu/paste" "")
; (gtk_accel_path "<Actions>/Main/CleanupUnused" "")
; (gtk_accel_path "<Actions>/redirectmenu/deselectall" "")
; (gtk_accel_path "<Actions>/options/SoloViaBus" "")
-(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "<Shift>z")
; (gtk_accel_path "<Actions>/RegionList/rlAudition" "")
(gtk_accel_path "<Actions>/Editor/set-region-sync-position" "v")
; (gtk_accel_path "<Actions>/Editor/PullupPlus4Plus1" "")
; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "")
; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "")
(gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow")
-(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-start" "period")
+(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-boundary" "period")
; (gtk_accel_path "<Actions>/options/SendMMC" "")
; (gtk_accel_path "<Actions>/Editor/toggle-auto-xfades" "")
; (gtk_accel_path "<Actions>/Main/AudioFileFormatHeader" "")
; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceFeedback" "")
; (gtk_accel_path "<Actions>/Editor/PullupPlus4Minus1" "")
; (gtk_accel_path "<Actions>/JACK/JACKLatency512" "")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-end" "<%PRIMARY%>bracketright")
; (gtk_accel_path "<Actions>/Main/Recent" "")
; (gtk_accel_path "<Actions>/redirectmenu/newplugin" "")
; (gtk_accel_path "<Actions>/options/InputAutoConnectManual" "")
(gtk_accel_path "<Actions>/Editor/goto-mark-9" "KP_9")
(gtk_accel_path "<Actions>/Transport/ToggleClick" "5")
(gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "4")
+(gtk_accel_path "<Actions>/Transport/focus-on-clock" "KP_Divide")
+(gtk_accel_path "<Actions>/Editor/set-loop-from-edit-range" "bracketright")
+(gtk_accel_path "<Actions>/Editor/set-punch-from-edit-range" "bracketleft")
+(gtk_accel_path "<Actions>/Editor/set-loop-from-region" "<%PRIMARY%><%SECONDARY%>bracketright")
+(gtk_accel_path "<Actions>/Editor/toggle-zoom" "<%TERTIARY%>z")
+(gtk_accel_path "<Actions>/Editor/zoom-to-region" "z")
</menu>
<menu name='Transport' action='Transport'>
<menuitem action='ToggleRoll'/>
+ <menuitem action='play-from-edit-point-and-return'/>
+ <menuitem action='play-edit-range'/>
+ <menuitem action='record-roll'/>
<menuitem action='ToggleRollForgetCapture'/>
<menuitem action='Loop'/>
+ <menuitem action='loop-region'/>
<menuitem action='PlaySelection'/>
<menuitem action='play-edit-range'/>
<menuitem action='Forward'/>
<menuitem action='jump-backward-to-mark'/>
<menuitem action='add-location-from-playhead'/>
<separator/>
- <menuitem action='playhead-to-next-region-start'/>
- <menuitem action='playhead-to-next-region-end'/>
- <menuitem action='playhead-to-previous-region-start'/>
- <menuitem action='playhead-to-previous-region-end'/>
+ <menuitem action='playhead-to-next-region-boundary'/>
+ <menuitem action='playhead-to-previous-region-boundary'/>
<menuitem action='playhead-to-next-region-sync'/>
<menuitem action='playhead-to-previous-region-sync'/>
<menuitem action='center-playhead'/>
<menuitem action='toggle-follow-playhead'/>
<menuitem action='ToggleVideoSync'/>
</menu>
+ <menuitem action='set-loop-from-edit-range'/>
+ <menuitem action='set-loop-from-region'/>
+ <menuitem action='set-punch-from-edit-range'/>
</menu>
<menu name='Edit' action='Edit'>
<menuitem action='undo'/>
<menuitem action='set-mouse-mode-timefx'/>
<separator/>
<menuitem action='cycle-edit-point'/>
+ <menuitem action='cycle-edit-point-with-marker'/>
<menuitem action='toggle-edit-mode'/>
</menu>
</menu>
<menuitem action='select-all-within-cursors'/>
<menuitem action='select-all-in-punch-range'/>
<menuitem action='select-all-in-loop-range'/>
+ <separator/>
+ <menuitem action='select-next-route'/>
+ <menuitem action='select-prev-route'/>
</menu>
<menu name='Regions' action='Regions'>
<menuitem action='crop'/>
<separator/>
<menuitem action='set-fade-in-length'/>
<menuitem action='set-fade-out-length'/>
+ <menuitem action='toggle-fade-in-active'/>
+ <menuitem action='toggle-fade-out-active'/>
<separator/>
<menuitem action='trim-back'/>
<menuitem action='trim-front'/>
<menuitem action='trim-to-end'/>
<menuitem action='trim-region-to-loop'/>
<menuitem action='trim-region-to-punch'/>
+ <separator/>
+ <menuitem action='pitch-shift-region'/>
</menu>
<menu name='View' action = 'View'>
<menu name='ZoomFocus' action='ZoomFocus'>
<menuitem action='snap-magnetic'/>
<separator/>
<menuitem action='cycle-snap-mode'/>
+ <menuitem action='cycle-snap-choice'/>
</menu>
<menu name='SnapTo' action='SnapTo'>
<menuitem action='snap-to-cd-frame'/>
<menuitem action='temporal-zoom-in'/>
<menuitem action='temporal-zoom-out'/>
<menuitem action='zoom-to-session'/>
+ <menuitem action='zoom-to-region'/>
+ <menuitem action='toggle-zoom'/>
<menuitem action='scroll-tracks-down'/>
<menuitem action='scroll-tracks-up'/>
<menuitem action='scroll-tracks-down'/>
new_session = new Session (*engine, path, snap_name, mix_template);
}
+ /* this one is special */
+
+ catch (AudioEngine::PortRegistrationFailure& err) {
+
+ MessageDialog msg (err.what(),
+ true,
+ Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK_CANCEL);
+
+ msg.set_title (_("Loading Error"));
+ msg.set_secondary_text (_("Click the OK button to try again."));
+ msg.set_position (Gtk::WIN_POS_CENTER);
+ msg.present ();
+
+ int response = msg.run ();
+
+ msg.hide ();
+
+ switch (response) {
+ case RESPONSE_CANCEL:
+ exit (1);
+ default:
+ break;
+ }
+ goto out;
+ }
+
catch (...) {
+ cerr << "Caught something\n";
MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
true,
Gtk::MESSAGE_INFO,
class PortRegistrationFailure : public std::exception {
public:
- virtual const char *what() const throw() { return "failed port registration"; }
+ PortRegistrationFailure (const char* why) {
+ reason = why;
+ }
+ virtual const char *what() const throw() { return reason; }
+
+ private:
+ const char* reason;
};
class NoBackendAvailable : public std::exception {
std::string get_nth_physical_audio (uint32_t which, int flags);
+ void port_registration_failure (const std::string& portname);
+
static int _xrun_callback (void *arg);
static int _graph_order_callback (void *arg);
static int _process_callback (nframes_t nframes, void *arg);
virtual ~IO();
+ bool active() const { return _active; }
+ void set_active (bool yn);
+
int input_minimum() const { return _input_minimum; }
int input_maximum() const { return _input_maximum; }
int output_minimum() const { return _output_minimum; }
uint32_t n_inputs () const { return _ninputs; }
uint32_t n_outputs () const { return _noutputs; }
+ sigc::signal<void> active_changed;
+
sigc::signal<void,IOChange,void*> input_changed;
sigc::signal<void,IOChange,void*> output_changed;
void reset_max_peak_meters ();
- static void update_meters();
+ static void update_meters();
private:
- static sigc::signal<void> Meter;
- static Glib::StaticMutex m_meter_signal_lock;
- sigc::connection m_meter_connection;
+ static sigc::signal<void> Meter;
+ static Glib::StaticMutex m_meter_signal_lock;
+ sigc::connection m_meter_connection;
public:
- /* automation */
-
- static void set_automation_interval (jack_nframes_t frames) {
- _automation_interval = frames;
- }
-
- static jack_nframes_t automation_interval() {
- return _automation_interval;
- }
-
- void clear_automation ();
+ bool _active;
- bool gain_automation_recording() const {
- return (_gain_automation_curve.automation_state() & (Write|Touch));
- }
-
- bool gain_automation_playback() const {
- return (_gain_automation_curve.automation_state() & Play) ||
- ((_gain_automation_curve.automation_state() & Touch) &&
- !_gain_automation_curve.touching());
- }
+ /* automation */
+
+ static void set_automation_interval (jack_nframes_t frames) {
+ _automation_interval = frames;
+ }
+
+ static jack_nframes_t automation_interval() {
+ return _automation_interval;
+ }
+
+ void clear_automation ();
+
+ bool gain_automation_recording() const {
+ return (_gain_automation_curve.automation_state() & (Write|Touch));
+ }
+
+ bool gain_automation_playback() const {
+ return (_gain_automation_curve.automation_state() & Play) ||
+ ((_gain_automation_curve.automation_state() & Touch) &&
+ !_gain_automation_curve.touching());
+ }
- virtual void set_gain_automation_state (AutoState);
+ virtual void set_gain_automation_state (AutoState);
AutoState gain_automation_state() const { return _gain_automation_curve.automation_state(); }
sigc::signal<void> gain_automation_state_changed;
void set_gain (gain_t val, void *src);
void inc_gain (gain_t delta, void *src);
- bool active() const { return _active; }
- void set_active (bool yn);
-
void set_solo (bool yn, void *src);
bool soloed() const { return _soloed; }
sigc::signal<void,void*> record_enable_changed;
sigc::signal<void,void*> edit_group_changed;
sigc::signal<void,void*> mix_group_changed;
- sigc::signal<void> active_changed;
sigc::signal<void,void*> meter_change;
/* gui's call this for their own purposes. */
bool _phase_invert : 1;
bool _denormal_protection : 1;
bool _recordable : 1;
- bool _active : 1;
bool _mute_affects_pre_fader : 1;
bool _mute_affects_post_fader : 1;
bool _mute_affects_control_outs : 1;
}
if (_slaved) {
- need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2;
+ if (_io && _io->active()) {
+ need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2;
+ } else {
+ need_butler = false;
+ }
} else {
- need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames
- || c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
+ if (_io && _io->active()) {
+ need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames
+ || c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
+ } else {
+ need_butler = c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
+ }
}
if (commit_should_unlock) {
remove_all_ports ();
}
+void
+AudioEngine::port_registration_failure (const std::string& portname)
+{
+ string full_portname = jack_client_name;
+ full_portname += ':';
+ full_portname += portname;
+
+
+ jack_port_t* p = jack_port_by_name (_jack, full_portname.c_str());
+ string reason;
+
+ if (p) {
+ reason = _("a port with this name already exists: check for duplicated track/bus names");
+ } else {
+ reason = _("unknown error");
+ }
+
+ throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
+}
+
Port *
AudioEngine::register_input_port (DataType type, const string& portname)
{
return newport;
} else {
- throw PortRegistrationFailure();
+ port_registration_failure (portname);
}
return 0;
return newport;
} else {
- throw PortRegistrationFailure ();
+ port_registration_failure (portname);
}
return 0;
_output_maximum (output_max)
{
_panner = new Panner (name, _session);
+ _active = true;
_gain = 1.0;
_desired_gain = 1.0;
_input_connection = 0;
_gain_automation_curve (0, 0, 0) // all reset in set_state()
{
_panner = 0;
+ _active = true;
deferred_state = 0;
no_panner_reset = false;
_desired_gain = 1.0;
setup_peak_meters ();
reset_panner ();
/* pass it on */
- throw AudioEngine::PortRegistrationFailure();
+ throw;
}
_inputs.push_back (input_port);
setup_peak_meters ();
reset_panner ();
/* pass it on */
- throw AudioEngine::PortRegistrationFailure();
+ throw;
}
_inputs.push_back (port);
setup_peak_meters ();
reset_panner ();
/* pass it on */
- throw AudioEngine::PortRegistrationFailure ();
+ throw;
}
_outputs.push_back (port);
node->add_property("name", _name);
id().print (buf, sizeof (buf));
node->add_property("id", buf);
+ node->add_property("active", _active? "yes" : "no");
str = "";
/* old school automation handling */
}
+ if ((prop = node.property (X_("active"))) != 0) {
+ set_active (prop->value() == "yes");
+ }
+
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
if ((*iter)->name() == "Panner") {
return n;
}
+
+void
+IO::set_active (bool yn)
+{
+ _active = yn;
+ active_changed(); /* EMIT SIGNAL */
+}
+
_phase_invert = false;
_denormal_protection = false;
order_keys[strdup (N_("signal"))] = order_key_cnt++;
- _active = true;
_silent = false;
_meter_point = MeterPostFader;
_initial_delay = 0;
node->add_property("default-type", _default_type.to_string());
- node->add_property("active", _active?"yes":"no");
node->add_property("muted", _muted?"yes":"no");
node->add_property("soloed", _soloed?"yes":"no");
node->add_property("phase-invert", _phase_invert?"yes":"no");
set_denormal_protection (prop->value()=="yes"?true:false, this);
}
- if ((prop = node.property (X_("active"))) != 0) {
- set_active (prop->value() == "yes");
- }
-
if ((prop = node.property (X_("muted"))) != 0) {
bool yn = prop->value()=="yes"?true:false;
return onoff;
}
-void
-Route::set_active (bool yn)
-{
- _active = yn;
- active_changed(); /* EMIT SIGNAL */
-}
-
void
Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects)
{
}
}
- //for (i = diskstreams.begin(); i != diskstreams.end(); ++i) {
- // cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
- //}
-
if (transport_work_requested()) {
butler_transport_work ();
}
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
+// for (i = dsl->begin(); i != dsl->end(); ++i) {
+// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
+// }
+
for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
boost::shared_ptr<Diskstream> ds = *i;
+ /* don't read inactive tracks */
+
+ IO* io = ds->io();
+
+ if (ds->io() && !ds->io()->active()) {
+ cerr << "Skip inactive diskstream " << ds->io()->name() << endl;
+ continue;
+ }
+
switch (ds->do_refill ()) {
case 0:
bytes += ds->read_data_count();
for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
+
+ /* note that we still try to flush diskstreams attached to inactive routes
+ */
switch ((*i)->do_flush (Session::ButlerContext)) {
case 0:
}
/* handle this one in a different way than all others, so that its clear what happened */
-
+
catch (AudioEngine::PortRegistrationFailure& err) {
- error << _("Unable to create all required ports")
- << endmsg;
- return -1;
+ destroy ();
+ throw;
}
catch (...) {
void
UI::popup_error (const char *text)
{
- PopUp *pup;
-
if (!caller_is_ui_thread()) {
error << "non-UI threads can't use UI::popup_error"
<< endmsg;
return;
}
-
- pup = new PopUp (WIN_POS_MOUSE, 0, true);
- pup->set_text (text);
- pup->touch ();
-}
+ MessageDialog msg (text, true, MESSAGE_ERROR, BUTTONS_OK);
+ msg.set_title (_("Error"));
+ msg.set_position (WIN_POS_MOUSE);
+ msg.run ();
+}
void
UI::flush_pending ()