2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #define __STDC_FORMAT_MACROS 1
34 #include <gtkmm/messagedialog.h>
35 #include <gtkmm/accelmap.h>
37 #include <pbd/error.h>
38 #include <pbd/compose.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/failed_constructor.h>
41 #include <gtkmm2ext/gtk_ui.h>
42 #include <gtkmm2ext/utils.h>
43 #include <gtkmm2ext/click_box.h>
44 #include <gtkmm2ext/fastmeter.h>
45 #include <gtkmm2ext/stop_signal.h>
46 #include <gtkmm2ext/popup.h>
48 #include <midi++/port.h>
49 #include <midi++/mmc.h>
51 #include <ardour/ardour.h>
52 #include <ardour/port.h>
53 #include <ardour/audioengine.h>
54 #include <ardour/playlist.h>
55 #include <ardour/utils.h>
56 #include <ardour/audio_diskstream.h>
57 #include <ardour/audiofilesource.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/session_route.h>
60 #include <ardour/port.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/midi_track.h>
65 #include "ardour_ui.h"
66 #include "public_editor.h"
67 #include "audio_clock.h"
72 #include "keyboard_target.h"
73 #include "add_route_dialog.h"
74 #include "new_session_dialog.h"
77 #include "gui_thread.h"
78 #include "color_manager.h"
82 using namespace ARDOUR;
84 using namespace Gtkmm2ext;
88 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
90 sigc::signal<void,bool> ARDOUR_UI::Blink;
91 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
92 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
93 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
95 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
97 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
99 primary_clock (X_("TransportClockDisplay"), true, false, true),
100 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
101 preroll_clock (X_("PreRollClock"), true, true),
102 postroll_clock (X_("PostRollClock"), true, true),
106 adjuster_table (3, 3),
110 preroll_button (_("pre\nroll")),
111 postroll_button (_("post\nroll")),
115 big_clock ("BigClockDisplay", true),
119 time_master_button (_("time\nmaster")),
121 shuttle_units_button (_("% ")),
123 punch_in_button (_("Punch In")),
124 punch_out_button (_("Punch Out")),
125 auto_return_button (_("Auto Return")),
126 auto_play_button (_("Autuo Play")),
127 auto_input_button (_("Auto Input")),
128 click_button (_("Click")),
129 auditioning_alert_button (_("AUDITION")),
130 solo_alert_button (_("SOLO")),
133 using namespace Gtk::Menu_Helpers;
139 if (theArdourUI == 0) {
145 color_manager = new ColorManager();
147 std::string color_file = ARDOUR::find_config_file("ardour.colors");
149 color_manager->load (color_file);
154 _session_is_new = false;
155 big_clock_window = 0;
156 session_selector_window = 0;
157 last_key_press_time = 0;
158 connection_editor = 0;
159 add_route_dialog = 0;
164 open_session_selector = 0;
165 have_configure_timeout = false;
166 have_disk_overrun_displayed = false;
167 have_disk_underrun_displayed = false;
168 _will_create_new_session_automatically = false;
169 session_loaded = false;
170 last_speed_displayed = -1.0f;
172 last_configure_time.tv_sec = 0;
173 last_configure_time.tv_usec = 0;
175 shuttle_grabbed = false;
177 shuttle_max_speed = 8.0f;
179 shuttle_style_menu = 0;
180 shuttle_unit_menu = 0;
182 gettimeofday (&last_peak_grab, 0);
183 gettimeofday (&last_shuttle_request, 0);
185 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
186 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
188 /* handle pending state with a dialog */
190 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
192 /* have to wait for AudioEngine and Configuration before proceeding */
196 ARDOUR_UI::set_engine (AudioEngine& e)
200 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
201 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
202 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
203 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
205 ActionManager::init ();
206 new_session_dialog = new NewSessionDialog();
210 keyboard = new Keyboard;
212 if (setup_windows ()) {
213 throw failed_constructor ();
216 if (GTK_ARDOUR::show_key_actions) {
217 vector<string> names;
218 vector<string> paths;
220 vector<AccelKey> bindings;
222 ActionManager::get_all_actions (names, paths, keys, bindings);
224 vector<string>::iterator n;
225 vector<string>::iterator k;
226 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
227 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
233 /* start with timecode, metering enabled
236 blink_timeout_tag = -1;
238 /* the global configuration object is now valid */
242 /* this being a GUI and all, we want peakfiles */
244 AudioFileSource::set_build_peakfiles (true);
245 AudioFileSource::set_build_missing_peakfiles (true);
247 if (AudioSource::start_peak_thread ()) {
248 throw failed_constructor();
251 /* start the time-of-day-clock */
253 update_wall_clock ();
254 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
256 update_disk_space ();
258 update_sample_rate (engine->frame_rate());
260 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
261 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
264 ARDOUR_UI::~ARDOUR_UI ()
266 save_ardour_state ();
280 if (add_route_dialog) {
281 delete add_route_dialog;
284 AudioSource::stop_peak_thread ();
288 ARDOUR_UI::configure_timeout ()
293 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
294 /* no configure events yet */
298 gettimeofday (&now, 0);
299 timersub (&now, &last_configure_time, &diff);
301 /* force a gap of 0.5 seconds since the last configure event
304 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
307 have_configure_timeout = false;
308 save_ardour_state ();
314 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
316 if (have_configure_timeout) {
317 gettimeofday (&last_configure_time, 0);
319 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
320 have_configure_timeout = true;
327 ARDOUR_UI::save_ardour_state ()
329 if (!keyboard || !mixer || !editor) {
333 /* XXX this is all a bit dubious. add_extra_xml() uses
334 a different lifetime model from add_instant_xml().
337 XMLNode* node = new XMLNode (keyboard->get_state());
338 Config->add_extra_xml (*node);
339 Config->save_state();
341 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
342 XMLNode mnode(mixer->get_state());
345 session->add_instant_xml (enode, session->path());
346 session->add_instant_xml (mnode, session->path());
348 Config->add_instant_xml (enode, get_user_ardour_path());
349 Config->add_instant_xml (mnode, get_user_ardour_path());
354 AccelMap::save ("ardour.saved_bindings");
358 ARDOUR_UI::startup ()
360 /* Once the UI is up and running, start the audio engine. Doing
361 this before the UI is up and running can cause problems
362 when not running with SCHED_FIFO, because the amount of
363 CPU and disk work needed to get the UI started can interfere
364 with the scheduling of the audio thread.
367 Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
373 if (session && session->dirty()) {
374 switch (ask_about_saving_session(_("quit"))) {
379 /* use the default name */
380 if (save_state_canfail ("")) {
381 /* failed - don't quit */
382 MessageDialog msg (*editor,
384 Ardour was unable to save your session.\n\n\
385 If you still wish to quit, please use the\n\n\
386 \"Just quit\" option."));
395 Config->save_state();
400 ARDOUR_UI::ask_about_saving_session (const string & what)
402 ArdourDialog window (_("ardour: save session?"));
403 Gtk::HBox dhbox; // the hbox for the image and text
404 Gtk::Label prompt_label;
405 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
409 msg = string_compose(_("Don't %1"), what);
410 window.add_button (msg, RESPONSE_REJECT);
411 msg = string_compose(_("Just %1"), what);
412 window.add_button (msg, RESPONSE_APPLY);
413 msg = string_compose(_("Save and %1"), what);
414 window.add_button (msg, RESPONSE_ACCEPT);
416 window.set_default_response (RESPONSE_ACCEPT);
418 Gtk::Button noquit_button (msg);
419 noquit_button.set_name ("EditorGTKButton");
424 if (session->snap_name() == session->name()) {
427 type = _("snapshot");
429 prompt = string_compose(_("The %1\"%2\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"),
430 type, session->snap_name());
432 prompt_label.set_text (prompt);
433 prompt_label.set_name (X_("PrompterLabel"));
434 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
436 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
438 dhbox.set_homogeneous (false);
439 dhbox.pack_start (*dimage, false, false, 5);
440 dhbox.pack_start (prompt_label, true, false, 5);
441 window.get_vbox()->pack_start (dhbox);
443 window.set_name (_("Prompter"));
444 window.set_position (Gtk::WIN_POS_MOUSE);
445 window.set_modal (true);
446 window.set_resizable (false);
449 save_the_session = 0;
451 editor->ensure_float (window);
453 ResponseType r = (ResponseType) window.run();
458 case RESPONSE_ACCEPT: // save and get out of here
460 case RESPONSE_APPLY: // get out of here
470 ARDOUR_UI::every_second ()
473 update_buffer_load ();
474 update_disk_space ();
479 ARDOUR_UI::every_point_one_seconds ()
481 update_speed_display ();
482 RapidScreenUpdate(); /* EMIT_SIGNAL */
487 ARDOUR_UI::every_point_zero_one_seconds ()
489 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
494 ARDOUR_UI::update_sample_rate (nframes_t ignored)
498 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
500 if (!engine->connected()) {
502 snprintf (buf, sizeof (buf), _("disconnected"));
506 nframes_t rate = engine->frame_rate();
508 if (fmod (rate, 1000.0) != 0.0) {
509 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
510 (float) rate/1000.0f,
511 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
513 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
515 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
519 sample_rate_label.set_text (buf);
523 ARDOUR_UI::update_cpu_load ()
526 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
527 cpu_load_label.set_text (buf);
531 ARDOUR_UI::update_buffer_load ()
536 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
537 session->playback_load(), session->capture_load());
538 buffer_load_label.set_text (buf);
540 buffer_load_label.set_text ("");
545 ARDOUR_UI::count_recenabled_streams (Route& route)
547 Track* track = dynamic_cast<Track*>(&route);
548 if (track && track->diskstream()->record_enabled()) {
549 rec_enabled_streams += track->n_inputs().get_total();
554 ARDOUR_UI::update_disk_space()
560 nframes_t frames = session->available_capture_duration();
563 if (frames == max_frames) {
564 strcpy (buf, _("Disk: 24hrs+"));
569 nframes_t fr = session->frame_rate();
571 rec_enabled_streams = 0;
572 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
574 if (rec_enabled_streams) {
575 frames /= rec_enabled_streams;
578 hrs = frames / (fr * 3600);
579 frames -= hrs * fr * 3600;
580 mins = frames / (fr * 60);
581 frames -= mins * fr * 60;
584 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
587 disk_space_label.set_text (buf);
591 ARDOUR_UI::update_wall_clock ()
598 tm_now = localtime (&now);
600 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
601 wall_clock_label.set_text (buf);
606 ARDOUR_UI::control_methods_adjusted ()
611 which_method = (int) online_control_button->adjustment.get_value();
612 switch (which_method) {
614 allow_mmc_and_local ();
623 fatal << _("programming error: impossible control method") << endmsg;
629 ARDOUR_UI::mmc_device_id_adjusted ()
634 int dev_id = (int) mmc_id_button->adjustment.get_value();
635 mmc->set_device_id (dev_id);
641 ARDOUR_UI::session_menu (GdkEventButton *ev)
643 session_popup_menu->popup (0, 0);
648 ARDOUR_UI::redisplay_recent_sessions ()
650 vector<string *> *sessions;
651 vector<string *>::iterator i;
652 RecentSessionsSorter cmp;
654 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
655 recent_session_model->clear ();
658 ARDOUR::read_recent_sessions (rs);
661 recent_session_display.set_model (recent_session_model);
665 /* sort them alphabetically */
666 sort (rs.begin(), rs.end(), cmp);
667 sessions = new vector<string*>;
669 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
670 sessions->push_back (new string ((*i).second));
673 for (i = sessions->begin(); i != sessions->end(); ++i) {
675 vector<string*>* states;
676 vector<const gchar*> item;
677 string fullpath = *(*i);
679 /* remove any trailing / */
681 if (fullpath[fullpath.length()-1] == '/') {
682 fullpath = fullpath.substr (0, fullpath.length()-1);
685 /* now get available states for this session */
687 if ((states = Session::possible_states (fullpath)) == 0) {
692 TreeModel::Row row = *(recent_session_model->append());
694 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
695 row[recent_session_columns.fullpath] = fullpath;
697 if (states->size() > 1) {
699 /* add the children */
701 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
703 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
705 child_row[recent_session_columns.visible_name] = **i2;
706 child_row[recent_session_columns.fullpath] = fullpath;
715 recent_session_display.set_model (recent_session_model);
720 ARDOUR_UI::build_session_selector ()
722 session_selector_window = new ArdourDialog ("session selector");
724 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
726 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
727 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
728 session_selector_window->set_default_response (RESPONSE_ACCEPT);
729 recent_session_model = TreeStore::create (recent_session_columns);
730 recent_session_display.set_model (recent_session_model);
731 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
732 recent_session_display.set_headers_visible (false);
733 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
735 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
737 scroller->add (recent_session_display);
738 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
740 session_selector_window->set_name ("SessionSelectorWindow");
741 session_selector_window->set_size_request (200, 400);
742 session_selector_window->get_vbox()->pack_start (*scroller);
743 session_selector_window->show_all_children();
747 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
749 session_selector_window->response (RESPONSE_ACCEPT);
753 ARDOUR_UI::open_recent_session ()
755 /* popup selector window */
757 if (session_selector_window == 0) {
758 build_session_selector ();
761 redisplay_recent_sessions ();
763 ResponseType r = (ResponseType) session_selector_window->run ();
765 session_selector_window->hide();
768 case RESPONSE_ACCEPT:
774 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
776 if (i == recent_session_model->children().end()) {
780 Glib::ustring path = (*i)[recent_session_columns.fullpath];
781 Glib::ustring state = (*i)[recent_session_columns.visible_name];
783 _session_is_new = false;
785 load_session (path, state);
789 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
793 if (stat (info.filename.c_str(), &statbuf) != 0) {
797 if (!S_ISDIR(statbuf.st_mode)) {
803 string session_file = info.filename;
805 session_file += Glib::path_get_basename (info.filename);
806 session_file += ".ardour";
808 if (stat (session_file.c_str(), &statbuf) != 0) {
812 return S_ISREG (statbuf.st_mode);
816 ARDOUR_UI::open_session ()
818 /* popup selector window */
820 if (open_session_selector == 0) {
822 /* ardour sessions are folders */
824 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
825 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
826 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
828 FileFilter session_filter;
829 session_filter.add_pattern ("*.ardour");
830 session_filter.set_name (_("Ardour sessions"));
831 open_session_selector->add_filter (session_filter);
832 open_session_selector->set_filter (session_filter);
835 int response = open_session_selector->run();
836 open_session_selector->hide ();
839 case RESPONSE_ACCEPT:
842 open_session_selector->hide();
846 open_session_selector->hide();
847 string session_path = open_session_selector->get_filename();
851 if (session_path.length() > 0) {
852 if (Session::find_session (session_path, path, name, isnew) == 0) {
853 _session_is_new = isnew;
854 load_session (path, name);
861 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
863 list<boost::shared_ptr<MidiTrack> > tracks;
866 warning << _("You cannot add a track without a session already loaded.") << endmsg;
873 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
875 if (tracks.size() != how_many) {
877 error << _("could not create a new midi track") << endmsg;
879 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
883 if ((route = session->new_midi_route ()) == 0) {
884 error << _("could not create new midi bus") << endmsg;
890 MessageDialog msg (*editor,
891 _("There are insufficient JACK ports available\n\
892 to create a new track or bus.\n\
893 You should save Ardour, exit and\n\
894 restart JACK with more ports."));
901 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
903 list<boost::shared_ptr<AudioTrack> > tracks;
904 Session::RouteList routes;
907 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
913 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
915 if (tracks.size() != how_many) {
917 error << _("could not create a new audio track") << endmsg;
919 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
925 routes = session->new_audio_route (input_channels, output_channels, how_many);
927 if (routes.size() != how_many) {
929 error << _("could not create a new audio track") << endmsg;
931 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
937 if (need_control_room_outs) {
943 route->set_stereo_control_outs (control_lr_channels);
944 route->control_outs()->set_stereo_pan (pans, this);
946 #endif /* CONTROLOUTS */
950 MessageDialog msg (*editor,
951 _("There are insufficient JACK ports available\n\
952 to create a new track or bus.\n\
953 You should save Ardour, exit and\n\
954 restart JACK with more ports."));
960 ARDOUR_UI::do_transport_locate (nframes_t new_position)
962 nframes_t _preroll = 0;
965 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
966 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
968 if (new_position > _preroll) {
969 new_position -= _preroll;
974 session->request_locate (new_position);
979 ARDOUR_UI::transport_goto_start ()
982 session->goto_start();
985 /* force displayed area in editor to start no matter
986 what "follow playhead" setting is.
990 editor->reposition_x_origin (session->current_start_frame());
996 ARDOUR_UI::transport_goto_zero ()
999 session->request_locate (0);
1002 /* force displayed area in editor to start no matter
1003 what "follow playhead" setting is.
1007 editor->reposition_x_origin (0);
1013 ARDOUR_UI::transport_goto_end ()
1016 nframes_t frame = session->current_end_frame();
1017 session->request_locate (frame);
1019 /* force displayed area in editor to start no matter
1020 what "follow playhead" setting is.
1024 editor->reposition_x_origin (frame);
1030 ARDOUR_UI::transport_stop ()
1036 if (session->is_auditioning()) {
1037 session->cancel_audition ();
1041 if (session->get_play_loop ()) {
1042 session->request_play_loop (false);
1045 session->request_stop ();
1049 ARDOUR_UI::transport_stop_and_forget_capture ()
1052 session->request_stop (true);
1057 ARDOUR_UI::remove_last_capture()
1060 editor->remove_last_capture();
1065 ARDOUR_UI::transport_record ()
1068 switch (session->record_status()) {
1069 case Session::Disabled:
1070 if (session->ntracks() == 0) {
1071 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1075 session->maybe_enable_record ();
1077 case Session::Recording:
1078 case Session::Enabled:
1079 session->disable_record (true);
1085 ARDOUR_UI::transport_roll ()
1093 rolling = session->transport_rolling ();
1095 if (session->get_play_loop()) {
1096 session->request_play_loop (false);
1097 auto_loop_button.set_active (false);
1098 roll_button.set_active (true);
1099 } else if (session->get_play_range ()) {
1100 session->request_play_range (false);
1101 play_selection_button.set_active (false);
1102 } else if (rolling) {
1103 session->request_locate (session->last_transport_start(), true);
1106 session->request_transport_speed (1.0f);
1110 ARDOUR_UI::transport_loop()
1113 if (session->get_play_loop()) {
1114 if (session->transport_rolling()) {
1115 Location * looploc = session->locations()->auto_loop_location();
1117 session->request_locate (looploc->start(), true);
1122 session->request_play_loop (true);
1128 ARDOUR_UI::transport_play_selection ()
1134 if (!session->get_play_range()) {
1135 session->request_stop ();
1138 editor->play_selection ();
1142 ARDOUR_UI::transport_rewind (int option)
1144 float current_transport_speed;
1147 current_transport_speed = session->transport_speed();
1149 if (current_transport_speed >= 0.0f) {
1152 session->request_transport_speed (-1.0f);
1155 session->request_transport_speed (-4.0f);
1158 session->request_transport_speed (-0.5f);
1163 session->request_transport_speed (current_transport_speed * 1.5f);
1169 ARDOUR_UI::transport_forward (int option)
1171 float current_transport_speed;
1174 current_transport_speed = session->transport_speed();
1176 if (current_transport_speed <= 0.0f) {
1179 session->request_transport_speed (1.0f);
1182 session->request_transport_speed (4.0f);
1185 session->request_transport_speed (0.5f);
1190 session->request_transport_speed (current_transport_speed * 1.5f);
1196 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1202 boost::shared_ptr<Route> r;
1204 if ((r = session->route_by_remote_id (dstream)) != 0) {
1208 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1209 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1218 ARDOUR_UI::queue_transport_change ()
1220 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1224 ARDOUR_UI::map_transport_state ()
1226 float sp = session->transport_speed();
1229 transport_rolling ();
1230 } else if (sp < 0.0f) {
1231 transport_rewinding ();
1232 } else if (sp > 0.0f) {
1233 transport_forwarding ();
1235 transport_stopped ();
1240 ARDOUR_UI::allow_local_only ()
1246 ARDOUR_UI::allow_mmc_only ()
1252 ARDOUR_UI::allow_mmc_and_local ()
1258 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1260 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1261 (int) adj.get_value()].c_str());
1265 ARDOUR_UI::engine_stopped ()
1267 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1268 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1269 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1273 ARDOUR_UI::engine_running ()
1275 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1276 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1277 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1281 ARDOUR_UI::engine_halted ()
1283 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1285 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1286 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1288 update_sample_rate (0);
1290 MessageDialog msg (*editor,
1292 JACK has either been shutdown or it\n\
1293 disconnected Ardour because Ardour\n\
1294 was not fast enough. You can save the\n\
1295 session and/or try to reconnect to JACK ."));
1300 ARDOUR_UI::do_engine_start ()
1306 catch (AudioEngine::PortRegistrationFailure& err) {
1308 error << _("Unable to create all required ports")
1316 error << _("Unable to start the session running")
1326 ARDOUR_UI::start_engine ()
1328 if (do_engine_start () == 0) {
1329 if (session && _session_is_new) {
1330 /* we need to retain initial visual
1331 settings for a new session
1333 session->save_state ("");
1336 /* there is too much going on, in too many threads, for us to
1337 end up with a clean session. So wait 1 second after loading,
1338 and fix it up. its ugly, but until i come across a better
1339 solution, its what we have.
1342 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1349 ARDOUR_UI::update_clocks ()
1351 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1355 ARDOUR_UI::start_clocking ()
1357 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1361 ARDOUR_UI::stop_clocking ()
1363 clock_signal_connection.disconnect ();
1367 ARDOUR_UI::toggle_clocking ()
1370 if (clock_button.get_active()) {
1379 ARDOUR_UI::_blink (void *arg)
1382 ((ARDOUR_UI *) arg)->blink ();
1389 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1393 ARDOUR_UI::start_blinking ()
1395 /* Start the blink signal. Everybody with a blinking widget
1396 uses Blink to drive the widget's state.
1399 if (blink_timeout_tag < 0) {
1401 blink_timeout_tag = g_timeout_add (240, _blink, this);
1406 ARDOUR_UI::stop_blinking ()
1408 if (blink_timeout_tag >= 0) {
1409 g_source_remove (blink_timeout_tag);
1410 blink_timeout_tag = -1;
1415 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1421 if (io.n_inputs().get_total() == 0) {
1426 /* XXX we're not handling multiple ports yet. */
1428 const char **connections = io.input(0)->get_connections();
1430 if (connections == 0 || connections[0] == '\0') {
1433 buf = connections[0];
1440 if (io.n_outputs().get_total() == 0) {
1445 /* XXX we're not handling multiple ports yet. */
1447 const char **connections = io.output(0)->get_connections();
1449 if (connections == 0 || connections[0] == '\0') {
1452 buf = connections[0];
1460 ARDOUR_UI::snapshot_session ()
1462 ArdourPrompter prompter (true);
1469 now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")";
1471 prompter.set_name ("Prompter");
1472 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1473 prompter.set_prompt (_("Name of New Snapshot"));
1474 prompter.set_initial_text (now);
1476 switch (prompter.run()) {
1477 case RESPONSE_ACCEPT:
1478 prompter.get_result (snapname);
1479 if (snapname.length()){
1480 save_state (snapname);
1490 ARDOUR_UI::save_state (const string & name)
1492 (void) save_state_canfail (name);
1496 ARDOUR_UI::save_state_canfail (string name)
1501 if (name.length() == 0) {
1502 name = session->snap_name();
1505 if ((ret = session->save_state (name)) != 0) {
1509 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1514 ARDOUR_UI::restore_state (string name)
1517 if (name.length() == 0) {
1518 name = session->name();
1520 session->restore_state (name);
1525 ARDOUR_UI::primary_clock_value_changed ()
1528 session->request_locate (primary_clock.current_time ());
1533 ARDOUR_UI::secondary_clock_value_changed ()
1536 session->request_locate (secondary_clock.current_time ());
1541 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1543 if (session && dstream && dstream->record_enabled()) {
1545 Session::RecordState rs;
1547 rs = session->record_status ();
1550 case Session::Disabled:
1551 case Session::Enabled:
1552 if (w->get_state() != STATE_SELECTED) {
1553 w->set_state (STATE_SELECTED);
1557 case Session::Recording:
1558 if (w->get_state() != STATE_ACTIVE) {
1559 w->set_state (STATE_ACTIVE);
1565 if (w->get_state() != STATE_NORMAL) {
1566 w->set_state (STATE_NORMAL);
1572 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1578 switch (session->record_status()) {
1579 case Session::Enabled:
1581 rec_button.set_state (1);
1583 rec_button.set_state (0);
1587 case Session::Recording:
1588 rec_button.set_state (2);
1592 rec_button.set_state (0);
1598 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1606 ARDOUR_UI::start_keyboard_prefix ()
1608 keyboard->start_prefix();
1612 ARDOUR_UI::save_template ()
1615 ArdourPrompter prompter (true);
1618 prompter.set_name (X_("Prompter"));
1619 prompter.set_prompt (_("Name for mix template:"));
1620 prompter.set_initial_text(session->name() + _("-template"));
1621 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1623 switch (prompter.run()) {
1624 case RESPONSE_ACCEPT:
1625 prompter.get_result (name);
1627 if (name.length()) {
1628 session->save_template (name);
1638 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1640 string session_name;
1641 string session_path;
1643 int response = Gtk::RESPONSE_NONE;
1645 new_session_dialog->set_modal(true);
1646 new_session_dialog->set_name (predetermined_path);
1647 new_session_dialog->reset_recent();
1648 new_session_dialog->show();
1651 response = new_session_dialog->run ();
1653 _session_is_new = false;
1655 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1660 new_session_dialog->hide ();
1663 } else if (response == Gtk::RESPONSE_NONE) {
1665 /* Clear was pressed */
1666 new_session_dialog->reset();
1668 } else if (response == Gtk::RESPONSE_YES) {
1670 /* YES == OPEN, but there's no enum for that */
1672 session_name = new_session_dialog->session_name();
1674 if (session_name.empty()) {
1675 response = Gtk::RESPONSE_NONE;
1679 if (session_name[0] == '/' ||
1680 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1681 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1682 load_session (Glib::path_get_dirname (session_name), session_name);
1684 session_path = new_session_dialog->session_folder();
1685 load_session (session_path, session_name);
1688 } else if (response == Gtk::RESPONSE_OK) {
1690 session_name = new_session_dialog->session_name();
1692 if (new_session_dialog->get_current_page() == 1) {
1694 /* XXX this is a bit of a hack..
1695 i really want the new sesion dialog to return RESPONSE_YES
1696 if we're on page 1 (the load page)
1697 Unfortunately i can't see how atm..
1700 if (session_name.empty()) {
1701 response = Gtk::RESPONSE_NONE;
1705 if (session_name[0] == '/' ||
1706 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1707 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1708 load_session (Glib::path_get_dirname (session_name), session_name);
1710 session_path = new_session_dialog->session_folder();
1711 load_session (session_path, session_name);
1716 if (session_name.empty()) {
1717 response = Gtk::RESPONSE_NONE;
1721 if (session_name[0] == '/' ||
1722 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1723 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1725 session_path = Glib::path_get_dirname (session_name);
1726 session_name = Glib::path_get_basename (session_name);
1730 session_path = new_session_dialog->session_folder();
1734 //XXX This is needed because session constructor wants a
1735 //non-existant path. hopefully this will be fixed at some point.
1737 session_path = Glib::build_filename (session_path, session_name);
1739 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1741 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1743 MessageDialog msg (str,
1745 Gtk::MESSAGE_WARNING,
1746 Gtk::BUTTONS_YES_NO,
1750 msg.set_name (X_("CleanupDialog"));
1751 msg.set_wmclass (_("existing_session"), "Ardour");
1752 msg.set_position (Gtk::WIN_POS_MOUSE);
1754 switch (msg.run()) {
1756 load_session (session_path, session_name);
1760 response = RESPONSE_NONE;
1761 new_session_dialog->reset ();
1766 _session_is_new = true;
1768 std::string template_name = new_session_dialog->session_template_name();
1770 if (new_session_dialog->use_session_template()) {
1772 load_session (session_path, session_name, &template_name);
1778 AutoConnectOption iconnect;
1779 AutoConnectOption oconnect;
1781 if (new_session_dialog->create_control_bus()) {
1782 cchns = (uint32_t) new_session_dialog->control_channel_count();
1787 if (new_session_dialog->create_master_bus()) {
1788 mchns = (uint32_t) new_session_dialog->master_channel_count();
1793 if (new_session_dialog->connect_inputs()) {
1794 iconnect = AutoConnectPhysical;
1796 iconnect = AutoConnectOption (0);
1799 /// @todo some minor tweaks.
1801 if (new_session_dialog->connect_outs_to_master()) {
1802 oconnect = AutoConnectMaster;
1803 } else if (new_session_dialog->connect_outs_to_physical()) {
1804 oconnect = AutoConnectPhysical;
1806 oconnect = AutoConnectOption (0);
1809 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1810 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1812 build_session (session_path,
1820 engine->frame_rate() * 60 * 5);
1825 } while (response == Gtk::RESPONSE_NONE);
1829 new_session_dialog->get_window()->set_cursor();
1830 new_session_dialog->hide();
1834 ARDOUR_UI::close_session()
1841 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1843 Session *new_session;
1845 session_loaded = false;
1846 x = unload_session ();
1854 /* if it already exists, we must have write access */
1856 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1857 MessageDialog msg (*editor, _("\
1858 You do not have write access to this session.\n\
1859 This prevents the session from being loaded."));
1865 new_session = new Session (*engine, path, snap_name, mix_template);
1870 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1874 connect_to_session (new_session);
1876 Config->set_current_owner (ConfigVariableBase::Interface);
1878 session_loaded = true;
1880 goto_editor_window ();
1886 ARDOUR_UI::make_session_clean ()
1889 session->set_clean ();
1898 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1899 uint32_t control_channels,
1900 uint32_t master_channels,
1901 AutoConnectOption input_connect,
1902 AutoConnectOption output_connect,
1905 nframes_t initial_length)
1907 Session *new_session;
1910 session_loaded = false;
1911 x = unload_session ();
1918 _session_is_new = true;
1921 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1922 control_channels, master_channels, nphysin, nphysout, initial_length);
1927 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1931 connect_to_session (new_session);
1933 session_loaded = true;
1941 editor->show_window ();
1952 ARDOUR_UI::show_splash ()
1955 about = new About();
1956 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
1963 ARDOUR_UI::about_signal_response(int response)
1969 ARDOUR_UI::hide_splash ()
1972 about->get_window()->set_cursor ();
1978 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1982 removed = rep.paths.size();
1985 MessageDialog msgd (*editor,
1986 _("No audio files were ready for cleanup"),
1989 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
1990 msgd.set_secondary_text (_("If this seems suprising, \n\
1991 check for any existing snapshots.\n\
1992 These may still include regions that\n\
1993 require some unused files to continue to exist."));
1999 ArdourDialog results (_("ardour: cleanup"), true, false);
2001 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2002 CleanupResultsModelColumns() {
2006 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2007 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2011 CleanupResultsModelColumns results_columns;
2012 Glib::RefPtr<Gtk::ListStore> results_model;
2013 Gtk::TreeView results_display;
2015 results_model = ListStore::create (results_columns);
2016 results_display.set_model (results_model);
2017 results_display.append_column (list_title, results_columns.visible_name);
2019 results_display.set_name ("CleanupResultsList");
2020 results_display.set_headers_visible (true);
2021 results_display.set_headers_clickable (false);
2022 results_display.set_reorderable (false);
2024 Gtk::ScrolledWindow list_scroller;
2027 Gtk::HBox dhbox; // the hbox for the image and text
2028 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2029 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2031 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2033 if (rep.space < 1048576.0f) {
2035 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2037 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2041 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2043 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2047 dhbox.pack_start (*dimage, true, false, 5);
2048 dhbox.pack_start (txt, true, false, 5);
2050 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2051 TreeModel::Row row = *(results_model->append());
2052 row[results_columns.visible_name] = *i;
2053 row[results_columns.fullpath] = *i;
2056 list_scroller.add (results_display);
2057 list_scroller.set_size_request (-1, 150);
2058 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2060 dvbox.pack_start (dhbox, true, false, 5);
2061 dvbox.pack_start (list_scroller, true, false, 5);
2062 ddhbox.pack_start (dvbox, true, false, 5);
2064 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2065 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2066 results.set_default_response (RESPONSE_CLOSE);
2067 results.set_position (Gtk::WIN_POS_MOUSE);
2068 results.show_all_children ();
2069 results.set_resizable (false);
2076 ARDOUR_UI::cleanup ()
2079 /* shouldn't happen: menu item is insensitive */
2084 MessageDialog checker (_("Are you sure you want to cleanup?"),
2086 Gtk::MESSAGE_QUESTION,
2087 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2089 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2090 ALL undo/redo information will be lost if you cleanup.\n\
2091 After cleanup, unused audio files will be moved to a \
2092 \"dead sounds\" location."));
2094 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2095 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2096 checker.set_default_response (RESPONSE_CANCEL);
2098 checker.set_name (_("CleanupDialog"));
2099 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2100 checker.set_position (Gtk::WIN_POS_MOUSE);
2102 switch (checker.run()) {
2103 case RESPONSE_ACCEPT:
2109 Session::cleanup_report rep;
2111 editor->prepare_for_cleanup ();
2113 if (session->cleanup_sources (rep)) {
2117 display_cleanup_results (rep,
2120 The following %1 %2 not in use and \n\
2121 have been moved to:\n\
2123 Flushing the wastebasket will \n\
2124 release an additional\n\
2125 %4 %5bytes of disk space.\n"
2130 ARDOUR_UI::flush_trash ()
2133 /* shouldn't happen: menu item is insensitive */
2137 Session::cleanup_report rep;
2139 if (session->cleanup_trash_sources (rep)) {
2143 display_cleanup_results (rep,
2145 _("The following %1 %2 deleted from\n\
2147 releasing %4 %5bytes of disk space"));
2151 ARDOUR_UI::add_route ()
2159 if (add_route_dialog == 0) {
2160 add_route_dialog = new AddRouteDialog;
2161 editor->ensure_float (*add_route_dialog);
2164 if (add_route_dialog->is_visible()) {
2165 /* we're already doing this */
2169 ResponseType r = (ResponseType) add_route_dialog->run ();
2171 add_route_dialog->hide();
2174 case RESPONSE_ACCEPT:
2181 if ((count = add_route_dialog->count()) <= 0) {
2185 uint32_t input_chan = add_route_dialog->channels ();
2186 uint32_t output_chan;
2187 string name_template = add_route_dialog->name_template ();
2188 bool track = add_route_dialog->track ();
2190 AutoConnectOption oac = Config->get_output_auto_connect();
2192 if (oac & AutoConnectMaster) {
2193 output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
2195 output_chan = input_chan;
2198 /* XXX do something with name template */
2200 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2202 session_add_midi_track(count);
2204 MessageDialog msg (*editor,
2205 _("Sorry, MIDI Busses are not supported at this time."));
2207 //session_add_midi_bus();
2211 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2213 session_add_audio_bus (input_chan, output_chan, count);
2219 ARDOUR_UI::mixer_settings () const
2224 node = session->instant_xml(X_("Mixer"), session->path());
2226 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2230 node = new XMLNode (X_("Mixer"));
2237 ARDOUR_UI::editor_settings () const
2242 node = session->instant_xml(X_("Editor"), session->path());
2244 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2248 node = new XMLNode (X_("Editor"));
2254 ARDOUR_UI::keyboard_settings () const
2258 node = Config->extra_xml(X_("Keyboard"));
2261 node = new XMLNode (X_("Keyboard"));
2267 ARDOUR_UI::halt_on_xrun_message ()
2269 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2271 MessageDialog msg (*editor,
2272 _("Recording was stopped because your system could not keep up."));
2277 ARDOUR_UI::disk_overrun_handler ()
2279 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2281 if (!have_disk_overrun_displayed) {
2282 have_disk_overrun_displayed = true;
2283 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2284 The disk system on your computer\n\
2285 was not able to keep up with Ardour.\n\
2287 Specifically, it failed to write data to disk\n\
2288 quickly enough to keep up with recording.\n"));
2290 have_disk_overrun_displayed = false;
2295 ARDOUR_UI::disk_underrun_handler ()
2297 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2299 if (!have_disk_underrun_displayed) {
2300 have_disk_underrun_displayed = true;
2301 MessageDialog msg (*editor,
2302 (_("The disk system on your computer\n\
2303 was not able to keep up with Ardour.\n\
2305 Specifically, it failed to read data from disk\n\
2306 quickly enough to keep up with playback.\n")));
2308 have_disk_underrun_displayed = false;
2313 ARDOUR_UI::disk_underrun_message_gone ()
2315 have_disk_underrun_displayed = false;
2319 ARDOUR_UI::disk_overrun_message_gone ()
2321 have_disk_underrun_displayed = false;
2325 ARDOUR_UI::pending_state_dialog ()
2327 ArdourDialog dialog ("pending state dialog");
2329 This session appears to have been in\n\
2330 middle of recording when ardour or\n\
2331 the computer was shutdown.\n\
2333 Ardour can recover any captured audio for\n\
2334 you, or it can ignore it. Please decide\n\
2335 what you would like to do.\n"));
2337 dialog.get_vbox()->pack_start (message);
2338 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2339 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2341 dialog.set_position (WIN_POS_CENTER);
2344 switch (dialog.run ()) {
2345 case RESPONSE_ACCEPT:
2353 ARDOUR_UI::disconnect_from_jack ()
2356 if( engine->disconnect_from_jack ()) {
2357 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2361 update_sample_rate (0);
2366 ARDOUR_UI::reconnect_to_jack ()
2369 if (engine->reconnect_to_jack ()) {
2370 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2374 update_sample_rate (0);
2379 ARDOUR_UI::set_jack_buffer_size (nframes_t nframes)
2381 engine->request_buffer_size (nframes);
2382 update_sample_rate (0);
2386 ARDOUR_UI::cmdline_new_session (string path)
2388 if (path[0] != '/') {
2389 char buf[PATH_MAX+1];
2392 getcwd (buf, sizeof (buf));
2399 new_session (false, path);
2401 _will_create_new_session_automatically = false; /* done it */
2402 return FALSE; /* don't call it again */
2406 ARDOUR_UI::use_config ()
2408 Glib::RefPtr<Action> act;
2410 switch (Config->get_native_file_data_format ()) {
2412 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2415 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2420 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2421 ract->set_active ();
2424 switch (Config->get_native_file_header_format ()) {
2426 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2429 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2432 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2435 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2438 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2441 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2444 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2449 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2450 ract->set_active ();