#include "pbd/memento_command.h"
#include "pbd/file_utils.h"
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/click_box.h>
-#include <gtkmm2ext/fastmeter.h>
-#include <gtkmm2ext/stop_signal.h>
-#include <gtkmm2ext/popup.h>
-#include <gtkmm2ext/window_title.h>
+#include "gtkmm2ext/gtk_ui.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/click_box.h"
+#include "gtkmm2ext/fastmeter.h"
+#include "gtkmm2ext/stop_signal.h"
+#include "gtkmm2ext/popup.h"
+#include "gtkmm2ext/window_title.h"
#include "midi++/manager.h"
#include "route_time_axis.h"
#include "startup.h"
#include "engine_dialog.h"
+#include "processor_box.h"
#include "i18n.h"
ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
- : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
+ : Gtkmm2ext::UI (X_("gui"), argcp, argvp),
- primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
- secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
- preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
- postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
+ primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true),
+ secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true),
+ preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, false, true),
+ postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, false, true),
/* preroll stuff */
/* big clock */
- big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
+ big_clock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, true),
/* transport */
/* lets get this party started */
- try {
+ try {
if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
throw failed_constructor ();
}
GainMeter::setup_slider_pix ();
RouteTimeAxisView::setup_slider_pix ();
+ SendProcessorEntry::setup_slider_pix ();
+ SessionEvent::create_per_thread_pool ("GUI", 512);
} catch (failed_constructor& err) {
error << _("could not initialize Ardour.") << endmsg;
/* we like keyboards */
- keyboard = new Keyboard;
+ keyboard = new ArdourKeyboard;
+
+ XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
+ if (node) {
+ keyboard->set_state (*node, Stateful::loading_state_version);
+ }
reset_dpi();
platform_setup ();
}
-void
+/** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */
+bool
ARDOUR_UI::run_startup (bool should_be_new)
{
if (_startup == 0) {
main().run();
- /* we don't return here until the startup assistant is finished */
-
_startup->hide ();
+
+ switch (_startup->response()) {
+ case RESPONSE_OK:
+ return true;
+ default:
+ return false;
+ }
}
int
MIDI::Manager::instance()->set_api_data (engine->jack());
setup_midi ();
-
+
ARDOUR::init_post_engine ();
ActionManager::init ();
if (setup_windows ()) {
throw failed_constructor ();
}
-
+
check_memory_locking();
/* this is the first point at which all the keybindings are available */
primary_clock.set_mode (AudioClock::BBT);
secondary_clock.set_mode (AudioClock::MinSec);
} else {
- primary_clock.set_mode (AudioClock::SMPTE);
+ primary_clock.set_mode (AudioClock::Timecode);
secondary_clock.set_mode (AudioClock::BBT);
}
update_cpu_load ();
update_sample_rate (engine->frame_rate());
+ Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
+ Config->map_parameters (mem_fun (*this, &ARDOUR_UI::parameter_changed));
+
/* now start and maybe save state */
if (do_engine_start () == 0) {
win.add_button (Stock::OK, RESPONSE_CLOSE);
} else {
win.add_button (Stock::QUIT, RESPONSE_CLOSE);
- }
+ }
win.set_default_response (RESPONSE_CLOSE);
_startup->engine_control()->set_state (*audio_setup);
}
- if (get_session_parameters (ARDOUR_COMMAND_LINE::new_session)) {
+ if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session)) {
exit (1);
}
}
}
- session->set_deletion_in_progress ();
+ second_connection.disconnect ();
+ point_one_second_connection.disconnect ();
+ point_oh_five_second_connection.disconnect ();
+ point_zero_one_second_connection.disconnect();
+
+ // session->set_deletion_in_progress ();
+ session->remove_pending_capture_state ();
+ delete session;
+ session = 0;
}
ArdourDialog::close_all_dialogs ();
/* ardour sessions are folders */
- open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
+ open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
void
-ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many)
+ARDOUR_UI::session_add_audio_route (bool track, bool aux, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many)
{
list<boost::shared_ptr<AudioTrack> > tracks;
RouteList routes;
} else {
- routes = session->new_audio_route (input_channels, output_channels, route_group, how_many);
+ routes = session->new_audio_route (aux, input_channels, output_channels, route_group, how_many);
if (routes.size() != how_many) {
if (how_many == 1) {
if (session) {
session->goto_start();
-
/* force displayed area in editor to start no matter
what "follow playhead" setting is.
*/
if (editor) {
- editor->reset_x_origin (session->current_start_frame());
+ editor->center_screen (session->current_start_frame ());
}
}
}
*/
if (editor) {
- editor->reset_x_origin (frames - (editor->current_page_frames()/2));
+ editor->center_screen (frames);
}
}
}
ARDOUR_UI::transport_goto_end ()
{
if (session) {
- nframes_t frame = session->current_end_frame();
+ nframes_t const frame = session->current_end_frame();
session->request_locate (frame);
/* force displayed area in editor to start no matter
*/
if (editor) {
- editor->reset_x_origin (frame);
+ editor->center_screen (frame);
}
}
}
return;
}
- if (session->get_play_loop ()) {
- session->request_play_loop (false);
- }
-
session->request_stop ();
}
//cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
}
-void
+void
ARDOUR_UI::transport_roll ()
{
- bool rolling;
-
if (!session) {
return;
}
- rolling = session->transport_rolling ();
+ if (session->is_auditioning()) {
+ return;
+ }
+
+ if (session->config.get_external_sync()) {
+ switch (session->config.get_sync_source()) {
+ case JACK:
+ break;
+ default:
+ /* transport controlled by the master */
+ return;
+ }
+ }
- //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl;
+ bool rolling = session->transport_rolling();
if (session->get_play_loop()) {
- session->request_play_loop (false);
- auto_loop_button.set_visual_state (1);
- roll_button.set_visual_state (1);
+ session->request_play_loop (false, true);
} else if (session->get_play_range ()) {
- session->request_play_range (false);
- play_selection_button.set_visual_state (0);
- } else if (rolling) {
- session->request_locate (session->last_transport_start(), true);
+ session->request_play_range (false, true);
+ }
+
+ if (!rolling) {
+ session->request_transport_speed (1.0f);
+ }
+
+ map_transport_state ();
+}
+
+void
+ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
+{
+
+ if (!session) {
+ return;
+ }
+
+ if (session->is_auditioning()) {
+ session->cancel_audition ();
+ return;
+ }
+
+ if (session->config.get_external_sync()) {
+ switch (session->config.get_sync_source()) {
+ case JACK:
+ break;
+ default:
+ /* transport controlled by the master */
+ return;
+ }
+ }
+
+ bool rolling = session->transport_rolling();
+ bool affect_transport = true;
+
+ if (rolling && roll_out_of_bounded_mode) {
+ /* drop out of loop/range playback but leave transport rolling */
+ if (session->get_play_loop()) {
+ if (Config->get_seamless_loop()) {
+ /* the disk buffers contain copies of the loop - we can't
+ just keep playing, so stop the transport. the user
+ can restart as they wish.
+ */
+ affect_transport = true;
+ } else {
+ /* disk buffers are normal, so we can keep playing */
+ affect_transport = false;
+ }
+ session->request_play_loop (false, true);
+ } else if (session->get_play_range ()) {
+ affect_transport = false;
+ session->request_play_range (0, true);
+ }
+ }
+
+ if (affect_transport) {
+ if (rolling) {
+ session->request_stop (with_abort, true);
+ } else {
+ session->request_transport_speed (1.0f);
+ }
}
- session->request_transport_speed (1.0f);
+ map_transport_state ();
}
void
-ARDOUR_UI::transport_loop()
+ARDOUR_UI::toggle_session_auto_loop ()
{
if (session) {
if (session->get_play_loop()) {
if (looploc) {
session->request_locate (looploc->start(), true);
}
+ } else {
+ session->request_play_loop (false);
+ }
+ } else {
+ Location * looploc = session->locations()->auto_loop_location();
+ if (looploc) {
+ session->request_play_loop (true);
}
- }
- else {
- session->request_play_loop (true);
}
}
}
return;
}
- if (!session->get_play_range()) {
- session->request_stop ();
- }
-
editor->play_selection ();
}
/* speed up */
session->request_transport_speed (current_transport_speed * 1.5f);
}
+
}
}
}
}
-void
-ARDOUR_UI::queue_transport_change ()
-{
- Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
-}
-
void
ARDOUR_UI::map_transport_state ()
{
+ ENSURE_GUI_THREAD(mem_fun (*this, &ARDOUR_UI::map_transport_state));
+
+ if (!session) {
+ auto_loop_button.set_visual_state (0);
+ play_selection_button.set_visual_state (0);
+ roll_button.set_visual_state (0);
+ stop_button.set_visual_state (1);
+ return;
+ }
+
float sp = session->transport_speed();
if (sp == 1.0f) {
- transport_rolling ();
- } else if (sp < 0.0f) {
- transport_rewinding ();
- } else if (sp > 0.0f) {
- transport_forwarding ();
+ shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */
+ shuttle_box.queue_draw ();
+ } else if (sp == 0.0f) {
+ shuttle_fract = 0;
+ shuttle_box.queue_draw ();
+ update_disk_space ();
+ }
+
+ if (sp != 0.0) {
+
+ if (session->get_play_range()) {
+
+ play_selection_button.set_visual_state (1);
+ roll_button.set_visual_state (0);
+ auto_loop_button.set_visual_state (0);
+
+ } else if (session->get_play_loop ()) {
+
+ auto_loop_button.set_visual_state (1);
+ play_selection_button.set_visual_state (0);
+ roll_button.set_visual_state (0);
+
+ } else {
+
+ roll_button.set_visual_state (1);
+ play_selection_button.set_visual_state (0);
+ auto_loop_button.set_visual_state (0);
+ }
+
+ stop_button.set_visual_state (0);
+
} else {
- transport_stopped ();
+
+ stop_button.set_visual_state (1);
+ roll_button.set_visual_state (0);
+ play_selection_button.set_visual_state (0);
+ auto_loop_button.set_visual_state (0);
}
+
}
void
prompter.set_name ("Prompter");
prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
+ prompter.set_title (_("Take Snapshot"));
prompter.set_prompt (_("Name of New Snapshot"));
prompter.set_initial_text (timebuf);
void
ARDOUR_UI::save_template ()
-
{
ArdourPrompter prompter (true);
string name;
}
prompter.set_name (X_("Prompter"));
+ prompter.set_title (_("Save Mix Template"));
prompter.set_prompt (_("Name for mix template:"));
prompter.set_initial_text(session->name() + _("-template"));
prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
true);
- msg.set_name (X_("CleanupDialog"));
+ msg.set_name (X_("OpenExistingDialog"));
+ msg.set_title (_("Open Existing Session"));
msg.set_wmclass (X_("existing_session"), "Ardour");
msg.set_position (Gtk::WIN_POS_MOUSE);
pop_back_splash ();
/// @todo some minor tweaks.
- if (_startup->connect_outs_to_master()) {
- oconnect = AutoConnectMaster;
- } else if (_startup->connect_outs_to_physical()) {
- oconnect = AutoConnectPhysical;
- } else {
- oconnect = AutoConnectOption (0);
+ oconnect = AutoConnectOption (0);
+
+ if (_startup->connect_outputs ()) {
+ if (_startup->connect_outs_to_master()) {
+ oconnect = AutoConnectMaster;
+ } else if (_startup->connect_outs_to_physical()) {
+ oconnect = AutoConnectPhysical;
+ }
}
nphysin = (uint32_t) _startup->input_limit_count();
flush_pending ();
}
+/** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
int
-ARDOUR_UI::get_session_parameters (bool should_be_new)
+ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
{
Glib::ustring session_name;
Glib::ustring session_path;
} else {
- run_startup (should_be_new);
+ bool const apply = run_startup (should_be_new);
+ if (!apply) {
+ if (quit_on_cancel) {
+ exit (1);
+ } else {
+ return ret;
+ }
+ }
/* if we run the startup dialog again, offer more than just "new session" */
_session_is_new = true;
}
-
if (session_name[0] == '/' ||
(session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
(session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
} else {
ret = load_session (session_path, session_name, template_name);
+ if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
+ session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
+ exit (1);
+ }
}
}
unload_session (true);
ARDOUR_COMMAND_LINE::session_name = "";
- get_session_parameters (false);
+ get_session_parameters (true, false);
}
int
}
void
-ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title,
+ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title,
const string& plural_msg, const string& singular_msg)
{
size_t removed;
return;
}
- Session::cleanup_report rep;
+ ARDOUR::CleanupReport rep;
editor->prepare_for_cleanup ();
return;
}
- Session::cleanup_report rep;
+ ARDOUR::CleanupReport rep;
if (session->cleanup_trash_sources (rep)) {
return;
uint32_t output_chan;
string name_template = add_route_dialog->name_template ();
bool track = add_route_dialog->track ();
+ bool aux = !track && add_route_dialog->aux();
RouteGroup* route_group = add_route_dialog->route_group ();
AutoConnectOption oac = Config->get_output_auto_connect();
if (track) {
session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
} else {
- session_add_audio_bus (input_chan, output_chan, route_group, count);
+ session_add_audio_bus (aux, input_chan, output_chan, route_group, count);
}
}
}
void
ARDOUR_UI::write_buffer_stats ()
{
+
+ std::ofstream fout;
struct tm tm;
char buf[64];
+ char path[PATH_MAX+1]; int fd;
+
+ strcpy (path, "ardourBufferingXXXXXX");
- char* tmplt = (char*)calloc(strlen("ardourXXXXXX"), sizeof(char));
- int fd = mkstemp (tmplt);
- if (fd) {
+ if ((fd = mkstemp (path )) < 0) {
cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
return;
}
+
+ fout.open (path);
+ close (fd);
- FILE* fout = fdopen (fd, "w");
if (!fout) {
- cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), tmplt) << endl;
+ cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl;
return;
}
for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
- std::ostringstream ss;
localtime_r (&(*i).when, &tm);
strftime (buf, sizeof (buf), "%T", &tm);
- fprintf(fout, "%s %u %u\n", buf, (*i).capture, (*i).playback);
+ fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl;
}
-
+
disk_buffer_stats.clear ();
- fclose (fout);
- close (fd);
+ fout.close ();
- cerr << "Ardour buffering statistics can be found in: " << tmplt << endl;
- free (tmplt);
+ cerr << "Ardour buffering statistics can be found in: " << path << endl;
}
void
if (r == Session::Recording && h) {
big_clock.set_widget_name ("BigClockRecording");
- } else {
+ } else {
big_clock.set_widget_name ("BigClockNonRecording");
}
}