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.
31 #include <gtkmm/messagedialog.h>
32 #include <gtkmm/accelmap.h>
34 #include <pbd/error.h>
35 #include <pbd/compose.h>
36 #include <pbd/basename.h>
37 #include <pbd/pathscanner.h>
38 #include <pbd/failed_constructor.h>
39 #include <gtkmm2ext/gtk_ui.h>
40 #include <gtkmm2ext/utils.h>
41 #include <gtkmm2ext/click_box.h>
42 #include <gtkmm2ext/fastmeter.h>
43 #include <gtkmm2ext/stop_signal.h>
44 #include <gtkmm2ext/popup.h>
46 #include <midi++/port.h>
47 #include <midi++/mmc.h>
49 #include <ardour/ardour.h>
50 #include <ardour/port.h>
51 #include <ardour/audioengine.h>
52 #include <ardour/playlist.h>
53 #include <ardour/utils.h>
54 #include <ardour/diskstream.h>
55 #include <ardour/filesource.h>
56 #include <ardour/recent_sessions.h>
57 #include <ardour/session_diskstream.h>
58 #include <ardour/port.h>
59 #include <ardour/audio_track.h>
62 #include "ardour_ui.h"
63 #include "public_editor.h"
64 #include "audio_clock.h"
69 #include "keyboard_target.h"
70 #include "add_route_dialog.h"
71 #include "new_session_dialog.h"
74 #include "gui_thread.h"
75 #include "color_manager.h"
79 using namespace ARDOUR;
80 using namespace Gtkmm2ext;
84 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
86 sigc::signal<void,bool> ARDOUR_UI::Blink;
87 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
88 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
89 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
91 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
93 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
95 primary_clock (X_("TransportClockDisplay"), true, false, true),
96 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
97 preroll_clock (X_("PreRollClock"), true, true),
98 postroll_clock (X_("PostRollClock"), true, true),
102 adjuster_table (3, 3),
106 preroll_button (_("pre\nroll")),
107 postroll_button (_("post\nroll")),
111 big_clock ("BigClockDisplay", true),
115 time_master_button (_("time\nmaster")),
117 shuttle_units_button (_("% ")),
119 punch_in_button (_("punch\nin")),
120 punch_out_button (_("punch\nout")),
121 auto_return_button (_("auto\nreturn")),
122 auto_play_button (_("auto\nplay")),
123 auto_input_button (_("auto\ninput")),
124 click_button (_("click")),
125 auditioning_alert_button (_("AUDITIONING")),
126 solo_alert_button (_("SOLO")),
130 using namespace Gtk::Menu_Helpers;
136 if (theArdourUI == 0) {
140 ActionManager::init ();
144 color_manager = new ColorManager();
146 std::string color_file = ARDOUR::find_config_file("ardour.colors");
148 color_manager->load (color_file);
150 m_new_session_dialog = 0;
151 m_new_session_dialog_ref = NewSessionDialogFactory::create();
152 m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
156 _session_is_new = false;
157 big_clock_window = 0;
158 session_selector_window = 0;
159 last_key_press_time = 0;
160 connection_editor = 0;
161 add_route_dialog = 0;
166 open_session_selector = 0;
167 have_configure_timeout = false;
168 have_disk_overrun_displayed = false;
169 have_disk_underrun_displayed = false;
170 _will_create_new_session_automatically = false;
171 session_loaded = false;
172 last_speed_displayed = -1.0f;
174 last_configure_time.tv_sec = 0;
175 last_configure_time.tv_usec = 0;
177 shuttle_grabbed = false;
179 shuttle_max_speed = 8.0f;
181 set_shuttle_units (Percentage);
182 set_shuttle_behaviour (Sprung);
184 shuttle_style_menu = 0;
185 shuttle_unit_menu = 0;
187 gettimeofday (&last_peak_grab, 0);
188 gettimeofday (&last_shuttle_request, 0);
190 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
191 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
192 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
193 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
195 /* handle pending state with a dialog */
197 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
199 /* have to wait for AudioEngine and Configuration before proceeding */
203 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
205 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
207 string msg = string_compose (_("\
208 You cannot record-enable\n\
210 because it has no input connections.\n\
211 You would be wasting space recording silence."),
214 MessageDialog message (*editor, msg);
219 ARDOUR_UI::set_engine (AudioEngine& e)
223 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
224 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
225 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
226 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
230 keyboard = new Keyboard;
234 meter_path = ARDOUR::find_data_file("v_meter_strip.xpm", "pixmaps");
235 if (meter_path.empty()) {
236 error << _("no vertical meter strip image found") << endmsg;
239 FastMeter::set_vertical_xpm (meter_path);
241 meter_path = ARDOUR::find_data_file("h_meter_strip.xpm", "pixmaps");
242 if (meter_path.empty()) {
243 error << _("no horizontal meter strip image found") << endmsg;
246 FastMeter::set_horizontal_xpm (meter_path);
248 if (setup_windows ()) {
249 throw failed_constructor ();
252 if (GTK_ARDOUR::show_key_actions) {
253 vector<string> names;
254 vector<string> paths;
256 vector<AccelKey> bindings;
258 ActionManager::get_all_actions (names, paths, keys, bindings);
260 vector<string>::iterator n;
261 vector<string>::iterator k;
262 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
263 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
269 /* start with timecode, metering enabled
272 blink_timeout_tag = -1;
274 /* the global configuration object is now valid */
278 /* this being a GUI and all, we want peakfiles */
280 FileSource::set_build_peakfiles (true);
281 FileSource::set_build_missing_peakfiles (true);
283 if (Source::start_peak_thread ()) {
284 throw failed_constructor();
287 /* start the time-of-day-clock */
289 update_wall_clock ();
290 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
292 update_disk_space ();
294 update_sample_rate (engine->frame_rate());
296 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
297 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
300 ARDOUR_UI::~ARDOUR_UI ()
302 save_ardour_state ();
316 if (add_route_dialog) {
317 delete add_route_dialog;
320 Source::stop_peak_thread ();
324 ARDOUR_UI::configure_timeout ()
329 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
330 /* no configure events yet */
334 gettimeofday (&now, 0);
335 timersub (&now, &last_configure_time, &diff);
337 /* force a gap of 0.5 seconds since the last configure event
340 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
343 have_configure_timeout = false;
344 save_ardour_state ();
350 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
352 if (have_configure_timeout) {
353 gettimeofday (&last_configure_time, 0);
355 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
356 have_configure_timeout = true;
363 ARDOUR_UI::save_ardour_state ()
365 if (!keyboard || !mixer || !editor) {
369 /* XXX this is all a bit dubious. add_extra_xml() uses
370 a different lifetime model from add_instant_xml().
373 XMLNode* node = new XMLNode (keyboard->get_state());
374 Config->add_extra_xml (*node);
375 Config->save_state();
377 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
378 XMLNode& mnode (mixer->get_state());
381 session->add_instant_xml(enode, session->path());
382 session->add_instant_xml(mnode, session->path());
384 Config->add_instant_xml(enode, get_user_ardour_path());
385 Config->add_instant_xml(mnode, get_user_ardour_path());
390 AccelMap::save ("ardour.saved_bindings");
394 ARDOUR_UI::startup ()
396 /* Once the UI is up and running, start the audio engine. Doing
397 this before the UI is up and running can cause problems
398 when not running with SCHED_FIFO, because the amount of
399 CPU and disk work needed to get the UI started can interfere
400 with the scheduling of the audio thread.
403 Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
409 if (session && session->dirty()) {
410 switch (ask_about_saving_session(_("quit"))) {
415 /* use the default name */
416 if (save_state_canfail ("")) {
417 /* failed - don't quit */
418 MessageDialog msg (*editor,
420 Ardour was unable to save your session.\n\n\
421 If you still wish to quit, please use the\n\n\
422 \"Just quit\" option."));
436 ARDOUR_UI::ask_about_saving_session (const string & what)
438 ArdourDialog window (_("ardour: save session?"));
439 Gtk::HBox dhbox; // the hbox for the image and text
440 Gtk::Label prompt_label;
441 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
445 msg = string_compose(_("Don't %1"), what);
446 window.add_button (msg, RESPONSE_REJECT);
447 msg = string_compose(_("Just %1"), what);
448 window.add_button (msg, RESPONSE_APPLY);
449 msg = string_compose(_("Save and %1"), what);
450 window.add_button (msg, RESPONSE_ACCEPT);
452 window.set_default_response (RESPONSE_ACCEPT);
454 Gtk::Button noquit_button (msg);
455 noquit_button.set_name ("EditorGTKButton");
460 if (session->snap_name() == session->name()) {
463 type = _("snapshot");
465 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?"),
466 type, session->snap_name());
468 prompt_label.set_text (prompt);
469 prompt_label.set_name (X_("PrompterLabel"));
470 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
471 dhbox.set_homogeneous (false);
472 dhbox.pack_start (*dimage, false, false, 5);
473 dhbox.pack_start (prompt_label, true, false, 5);
474 window.get_vbox()->pack_start (dhbox);
476 window.set_name (_("Prompter"));
477 window.set_position (Gtk::WIN_POS_MOUSE);
478 window.set_modal (true);
479 window.set_resizable (false);
482 save_the_session = 0;
484 editor->ensure_float (window);
486 ResponseType r = (ResponseType) window.run();
491 case RESPONSE_ACCEPT: // save and get out of here
493 case RESPONSE_APPLY: // get out of here
503 ARDOUR_UI::every_second ()
506 update_buffer_load ();
507 update_disk_space ();
512 ARDOUR_UI::every_point_one_seconds ()
514 update_speed_display ();
515 RapidScreenUpdate(); /* EMIT_SIGNAL */
520 ARDOUR_UI::every_point_zero_one_seconds ()
522 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
527 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
531 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
533 if (!engine->connected()) {
535 snprintf (buf, sizeof (buf), _("disconnected"));
539 jack_nframes_t rate = engine->frame_rate();
541 if (fmod (rate, 1000.0) != 0.0) {
542 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
543 (float) rate/1000.0f,
544 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
546 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
548 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
552 sample_rate_label.set_text (buf);
556 ARDOUR_UI::update_cpu_load ()
559 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
560 cpu_load_label.set_text (buf);
564 ARDOUR_UI::update_buffer_load ()
569 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
570 session->playback_load(), session->capture_load());
571 buffer_load_label.set_text (buf);
573 buffer_load_label.set_text ("");
578 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
580 if (ds.record_enabled()) {
581 rec_enabled_diskstreams++;
586 ARDOUR_UI::update_disk_space()
592 jack_nframes_t frames = session->available_capture_duration();
595 if (frames == max_frames) {
596 strcpy (buf, _("space: 24hrs+"));
601 jack_nframes_t fr = session->frame_rate();
603 if (session->actively_recording()){
605 rec_enabled_diskstreams = 0;
606 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
608 if (rec_enabled_diskstreams) {
609 frames /= rec_enabled_diskstreams;
614 /* hmmm. shall we divide by the route count? or the diskstream count?
615 or what? for now, do nothing ...
620 hrs = frames / (fr * 3600);
621 frames -= hrs * fr * 3600;
622 mins = frames / (fr * 60);
623 frames -= mins * fr * 60;
626 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
629 disk_space_label.set_text (buf);
633 ARDOUR_UI::update_wall_clock ()
640 tm_now = localtime (&now);
642 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
643 wall_clock_label.set_text (buf);
648 ARDOUR_UI::control_methods_adjusted ()
653 which_method = (int) online_control_button->adjustment.get_value();
654 switch (which_method) {
656 allow_mmc_and_local ();
665 fatal << _("programming error: impossible control method") << endmsg;
671 ARDOUR_UI::mmc_device_id_adjusted ()
676 int dev_id = (int) mmc_id_button->adjustment.get_value();
677 mmc->set_device_id (dev_id);
683 ARDOUR_UI::session_menu (GdkEventButton *ev)
685 session_popup_menu->popup (0, 0);
690 ARDOUR_UI::redisplay_recent_sessions ()
692 vector<string *> *sessions;
693 vector<string *>::iterator i;
694 RecentSessionsSorter cmp;
696 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
697 recent_session_model->clear ();
700 ARDOUR::read_recent_sessions (rs);
703 recent_session_display.set_model (recent_session_model);
707 /* sort them alphabetically */
708 sort (rs.begin(), rs.end(), cmp);
709 sessions = new vector<string*>;
711 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
712 sessions->push_back (new string ((*i).second));
715 for (i = sessions->begin(); i != sessions->end(); ++i) {
717 vector<string*>* states;
718 vector<const gchar*> item;
719 string fullpath = *(*i);
721 /* remove any trailing / */
723 if (fullpath[fullpath.length()-1] == '/') {
724 fullpath = fullpath.substr (0, fullpath.length()-1);
727 /* now get available states for this session */
729 if ((states = Session::possible_states (fullpath)) == 0) {
734 TreeModel::Row row = *(recent_session_model->append());
736 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
737 row[recent_session_columns.fullpath] = fullpath;
739 if (states->size() > 1) {
741 /* add the children */
743 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
745 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
747 child_row[recent_session_columns.visible_name] = **i2;
748 child_row[recent_session_columns.fullpath] = fullpath;
757 recent_session_display.set_model (recent_session_model);
762 ARDOUR_UI::build_session_selector ()
764 session_selector_window = new ArdourDialog ("session selector");
766 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
768 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
769 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
770 session_selector_window->set_default_response (RESPONSE_ACCEPT);
771 recent_session_model = TreeStore::create (recent_session_columns);
772 recent_session_display.set_model (recent_session_model);
773 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
774 recent_session_display.set_headers_visible (false);
775 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
777 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
779 scroller->add (recent_session_display);
780 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
782 session_selector_window->set_name ("SessionSelectorWindow");
783 session_selector_window->set_size_request (200, 400);
784 session_selector_window->get_vbox()->pack_start (*scroller);
785 session_selector_window->show_all_children();
789 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
791 session_selector_window->response (RESPONSE_ACCEPT);
795 ARDOUR_UI::open_recent_session ()
797 /* popup selector window */
799 if (session_selector_window == 0) {
800 build_session_selector ();
803 redisplay_recent_sessions ();
805 ResponseType r = (ResponseType) session_selector_window->run ();
807 session_selector_window->hide();
810 case RESPONSE_ACCEPT:
816 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
818 if (i == recent_session_model->children().end()) {
822 Glib::ustring path = (*i)[recent_session_columns.fullpath];
823 Glib::ustring state = (*i)[recent_session_columns.visible_name];
825 _session_is_new = false;
827 load_session (path, state);
831 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
835 if (stat (info.filename.c_str(), &statbuf) != 0) {
839 if (!S_ISDIR(statbuf.st_mode)) {
843 string session_file = info.filename;
845 session_file += PBD::basename (info.filename);
846 session_file += ".ardour";
848 if (stat (session_file.c_str(), &statbuf) != 0) {
852 return S_ISREG (statbuf.st_mode);
856 ARDOUR_UI::open_session ()
858 /* popup selector window */
860 if (open_session_selector == 0) {
862 /* ardour sessions are folders */
864 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
865 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
866 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
868 FileFilter session_filter;
869 session_filter.add_pattern ("*.ardour");
870 session_filter.set_name (_("Ardour sessions"));
871 open_session_selector->add_filter (session_filter);
872 open_session_selector->set_filter (session_filter);
875 int response = open_session_selector->run();
876 open_session_selector->hide ();
879 case RESPONSE_ACCEPT:
882 open_session_selector->hide();
886 open_session_selector->hide();
887 string session_path = open_session_selector->get_filename();
891 if (session_path.length() > 0) {
892 if (Session::find_session (session_path, path, name, isnew) == 0) {
893 _session_is_new = isnew;
894 load_session (path, name);
901 ARDOUR_UI::session_add_midi_track ()
903 cerr << _("Patience is a virtue.\n");
907 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
912 warning << _("You cannot add a track without a session already loaded.") << endmsg;
918 if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) {
919 error << _("could not create new audio track") << endmsg;
922 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
923 error << _("could not create new audio bus") << endmsg;
928 if (need_control_room_outs) {
934 route->set_stereo_control_outs (control_lr_channels);
935 route->control_outs()->set_stereo_pan (pans, this);
937 #endif /* CONTROLOUTS */
941 MessageDialog msg (*editor,
942 _("There are insufficient JACK ports available\n\
943 to create a new track or bus.\n\
944 You should save Ardour, exit and\n\
945 restart JACK with more ports."));
951 ARDOUR_UI::diskstream_added (DiskStream* ds)
956 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
958 jack_nframes_t _preroll;
961 _preroll = session->convert_to_frames_at (new_position, session->preroll);
963 if (new_position > _preroll) {
964 new_position -= _preroll;
969 session->request_locate (new_position);
974 ARDOUR_UI::transport_goto_start ()
977 session->goto_start();
980 /* force displayed area in editor to start no matter
981 what "follow playhead" setting is.
985 editor->reposition_x_origin (session->current_start_frame());
991 ARDOUR_UI::transport_goto_zero ()
994 session->request_locate (0);
997 /* force displayed area in editor to start no matter
998 what "follow playhead" setting is.
1002 editor->reposition_x_origin (0);
1008 ARDOUR_UI::transport_goto_end ()
1011 jack_nframes_t frame = session->current_end_frame();
1012 session->request_locate (frame);
1014 /* force displayed area in editor to start no matter
1015 what "follow playhead" setting is.
1019 editor->reposition_x_origin (frame);
1025 ARDOUR_UI::transport_stop ()
1031 if (session->is_auditioning()) {
1032 session->cancel_audition ();
1036 if (session->get_auto_loop()) {
1037 session->request_auto_loop (false);
1040 session->request_stop ();
1044 ARDOUR_UI::transport_stop_and_forget_capture ()
1047 session->request_stop (true);
1052 ARDOUR_UI::remove_last_capture()
1055 editor->remove_last_capture();
1060 ARDOUR_UI::transport_record ()
1063 switch (session->record_status()) {
1064 case Session::Disabled:
1065 if (session->ntracks() == 0) {
1066 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1067 MessageDialog msg (*editor, txt);
1071 session->maybe_enable_record ();
1073 case Session::Recording:
1074 case Session::Enabled:
1075 session->disable_record (true);
1081 ARDOUR_UI::transport_roll ()
1089 rolling = session->transport_rolling ();
1091 if (session->get_auto_loop()) {
1092 session->request_auto_loop (false);
1093 auto_loop_button.set_active (false);
1094 roll_button.set_active (true);
1095 } else if (session->get_play_range ()) {
1096 session->request_play_range (false);
1097 play_selection_button.set_active (false);
1098 } else if (rolling) {
1099 session->request_locate (session->last_transport_start(), true);
1102 session->request_transport_speed (1.0f);
1106 ARDOUR_UI::transport_loop()
1109 if (session->get_auto_loop()) {
1110 if (session->transport_rolling()) {
1111 Location * looploc = session->locations()->auto_loop_location();
1113 session->request_locate (looploc->start(), true);
1118 session->request_auto_loop (true);
1124 ARDOUR_UI::transport_play_selection ()
1130 if (!session->get_play_range()) {
1131 session->request_stop ();
1134 editor->play_selection ();
1138 ARDOUR_UI::transport_rewind (int option)
1140 float current_transport_speed;
1143 current_transport_speed = session->transport_speed();
1145 if (current_transport_speed >= 0.0f) {
1148 session->request_transport_speed (-1.0f);
1151 session->request_transport_speed (-4.0f);
1154 session->request_transport_speed (-0.5f);
1159 session->request_transport_speed (current_transport_speed * 1.5f);
1165 ARDOUR_UI::transport_forward (int option)
1167 float current_transport_speed;
1170 current_transport_speed = session->transport_speed();
1172 if (current_transport_speed <= 0.0f) {
1175 session->request_transport_speed (1.0f);
1178 session->request_transport_speed (4.0f);
1181 session->request_transport_speed (0.5f);
1186 session->request_transport_speed (current_transport_speed * 1.5f);
1192 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
1200 if ((ds = session->diskstream_by_id (dstream)) != 0) {
1201 Port *port = ds->io()->input (0);
1202 port->request_monitor_input (!port->monitoring_input());
1207 ARDOUR_UI::toggle_record_enable (guint32 dstream)
1215 if ((ds = session->diskstream_by_id (dstream)) != 0) {
1216 ds->set_record_enabled (!ds->record_enabled(), this);
1221 ARDOUR_UI::queue_transport_change ()
1223 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1227 ARDOUR_UI::map_transport_state ()
1229 float sp = session->transport_speed();
1232 transport_rolling ();
1233 } else if (sp < 0.0f) {
1234 transport_rewinding ();
1235 } else if (sp > 0.0f) {
1236 transport_forwarding ();
1238 transport_stopped ();
1243 ARDOUR_UI::allow_local_only ()
1249 ARDOUR_UI::allow_mmc_only ()
1255 ARDOUR_UI::allow_mmc_and_local ()
1261 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1263 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1264 (int) adj.get_value()].c_str());
1268 ARDOUR_UI::engine_stopped ()
1270 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1271 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1272 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1277 ARDOUR_UI::engine_running ()
1279 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1280 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1281 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1285 ARDOUR_UI::engine_halted ()
1287 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1289 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1290 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1292 update_sample_rate (0);
1294 MessageDialog msg (*editor,
1296 JACK has either been shutdown or it\n\
1297 disconnected Ardour because Ardour\n\
1298 was not fast enough. You can save the\n\
1299 session and/or try to reconnect to JACK ."));
1304 ARDOUR_UI::do_engine_start ()
1310 catch (AudioEngine::PortRegistrationFailure& err) {
1312 error << _("Unable to create all required ports")
1320 error << _("Unable to start the session running")
1330 ARDOUR_UI::start_engine ()
1332 if (do_engine_start () == 0) {
1333 if (session && _session_is_new) {
1334 /* we need to retain initial visual
1335 settings for a new session
1337 session->save_state ("");
1340 /* there is too much going on, in too many threads, for us to
1341 end up with a clean session. So wait 1 second after loading,
1342 and fix it up. its ugly, but until i come across a better
1343 solution, its what we have.
1346 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1353 ARDOUR_UI::update_clocks ()
1355 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1359 ARDOUR_UI::start_clocking ()
1361 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1365 ARDOUR_UI::stop_clocking ()
1367 clock_signal_connection.disconnect ();
1371 ARDOUR_UI::toggle_clocking ()
1374 if (clock_button.get_active()) {
1383 ARDOUR_UI::_blink (void *arg)
1386 ((ARDOUR_UI *) arg)->blink ();
1393 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1397 ARDOUR_UI::start_blinking ()
1399 /* Start the blink signal. Everybody with a blinking widget
1400 uses Blink to drive the widget's state.
1403 if (blink_timeout_tag < 0) {
1405 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
1410 ARDOUR_UI::stop_blinking ()
1412 if (blink_timeout_tag >= 0) {
1413 gtk_timeout_remove (blink_timeout_tag);
1414 blink_timeout_tag = -1;
1420 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
1422 using namespace Gtk;
1423 using namespace Menu_Helpers;
1425 if (dstream.hidden()) {
1429 MenuList& items = diskstream_menu->items();
1430 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
1434 ARDOUR_UI::diskstream_selected (gint32 id)
1436 selected_dstream = id;
1441 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
1443 using namespace Gtk;
1444 using namespace Menu_Helpers;
1450 diskstream_menu = new Menu();
1451 diskstream_menu->set_name ("ArdourContextMenu");
1452 using namespace Gtk;
1453 using namespace Menu_Helpers;
1455 MenuList& items = diskstream_menu->items();
1456 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
1458 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
1461 diskstream_menu->popup (ev->button, ev->time);
1463 diskstream_menu->popup (0, 0);
1466 selected_dstream = -1;
1470 delete diskstream_menu;
1472 return selected_dstream;
1476 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1482 if (io.n_inputs() == 0) {
1487 /* XXX we're not handling multiple ports yet. */
1489 const char **connections = io.input(0)->get_connections();
1491 if (connections == 0 || connections[0] == '\0') {
1494 buf = connections[0];
1501 if (io.n_outputs() == 0) {
1506 /* XXX we're not handling multiple ports yet. */
1508 const char **connections = io.output(0)->get_connections();
1510 if (connections == 0 || connections[0] == '\0') {
1513 buf = connections[0];
1521 ARDOUR_UI::snapshot_session ()
1523 ArdourPrompter prompter (true);
1530 now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")";
1532 prompter.set_name ("Prompter");
1533 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1534 prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1535 prompter.set_prompt (_("Name of New Snapshot"));
1536 prompter.set_initial_text (now);
1538 switch (prompter.run()) {
1539 case RESPONSE_ACCEPT:
1540 prompter.get_result (snapname);
1541 if (snapname.length()){
1542 save_state (snapname);
1552 ARDOUR_UI::save_state (const string & name)
1554 (void) save_state_canfail (name);
1558 ARDOUR_UI::save_state_canfail (string name)
1563 if (name.length() == 0) {
1564 name = session->snap_name();
1567 if ((ret = session->save_state (name)) != 0) {
1571 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1576 ARDOUR_UI::restore_state (string name)
1579 if (name.length() == 0) {
1580 name = session->name();
1582 session->restore_state (name);
1587 ARDOUR_UI::primary_clock_value_changed ()
1590 session->request_locate (primary_clock.current_time ());
1595 ARDOUR_UI::secondary_clock_value_changed ()
1598 session->request_locate (secondary_clock.current_time ());
1603 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
1605 if (session && dstream && dstream->record_enabled()) {
1607 Session::RecordState rs;
1609 rs = session->record_status ();
1612 case Session::Disabled:
1613 case Session::Enabled:
1614 if (w->get_state() != STATE_SELECTED) {
1615 w->set_state (STATE_SELECTED);
1619 case Session::Recording:
1620 if (w->get_state() != STATE_ACTIVE) {
1621 w->set_state (STATE_ACTIVE);
1627 if (w->get_state() != STATE_NORMAL) {
1628 w->set_state (STATE_NORMAL);
1634 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1640 switch (session->record_status()) {
1641 case Session::Enabled:
1643 rec_button.set_state (1);
1645 rec_button.set_state (0);
1649 case Session::Recording:
1650 rec_button.set_state (2);
1654 rec_button.set_state (0);
1660 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1668 ARDOUR_UI::start_keyboard_prefix ()
1670 keyboard->start_prefix();
1674 ARDOUR_UI::save_template ()
1677 ArdourPrompter prompter (true);
1680 prompter.set_name (X_("Prompter"));
1681 prompter.set_prompt (_("Name for mix template:"));
1682 prompter.set_initial_text(session->name() + _("-template"));
1683 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1684 prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1686 switch (prompter.run()) {
1687 case RESPONSE_ACCEPT:
1688 prompter.get_result (name);
1690 if (name.length()) {
1691 session->save_template (name);
1701 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1703 m_new_session_dialog->show_all();
1704 m_new_session_dialog->set_transient_for(*editor);
1705 m_new_session_dialog->set_name(predetermined_path);
1707 int response = Gtk::RESPONSE_CANCEL;
1710 response = m_new_session_dialog->run ();
1711 if(response == Gtk::RESPONSE_CANCEL) {
1714 } else if (response == Gtk::RESPONSE_YES) {
1715 /* YES == OPEN, but there's no enum for that */
1716 std::string session_name = m_new_session_dialog->session_name();
1717 std::string session_path = m_new_session_dialog->session_folder();
1718 load_session (session_path, session_name);
1721 } else if (response == Gtk::RESPONSE_OK) {
1722 if (m_new_session_dialog->get_current_page() == 1) {
1724 /* XXX this is a bit of a hack..
1725 i really want the new sesion dialog to return RESPONSE_YES
1726 if we're on page 1 (the load page)
1727 Unfortunately i can't see how atm..
1729 std::string session_name = m_new_session_dialog->session_name();
1730 std::string session_path = m_new_session_dialog->session_folder();
1731 load_session (session_path, session_name);
1735 _session_is_new = true;
1737 std::string session_name = m_new_session_dialog->session_name();
1738 std::string session_path = m_new_session_dialog->session_folder();
1741 XXX This is needed because session constructor wants a
1742 non-existant path. hopefully this will be fixed at some point.
1744 session_path = Glib::build_filename(session_path, session_name);
1746 std::string template_name = m_new_session_dialog->session_template_name();
1748 if (m_new_session_dialog->use_session_template()) {
1750 load_session (session_path, session_name, &template_name);
1756 Session::AutoConnectOption iconnect;
1757 Session::AutoConnectOption oconnect;
1759 if (m_new_session_dialog->create_control_bus()) {
1760 cchns = (uint32_t) m_new_session_dialog->control_channel_count();
1765 if (m_new_session_dialog->create_master_bus()) {
1766 mchns = (uint32_t) m_new_session_dialog->master_channel_count();
1771 if (m_new_session_dialog->connect_inputs()) {
1772 iconnect = Session::AutoConnectPhysical;
1774 iconnect = Session::AutoConnectOption (0);
1777 /// @todo some minor tweaks.
1779 if (m_new_session_dialog->connect_outs_to_master()) {
1780 oconnect = Session::AutoConnectMaster;
1781 } else if (m_new_session_dialog->connect_outs_to_physical()) {
1782 oconnect = Session::AutoConnectPhysical;
1784 oconnect = Session::AutoConnectOption (0);
1787 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
1788 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
1790 build_session (session_path,
1798 engine->frame_rate() * 60 * 5);
1803 } while(response == Gtk::RESPONSE_HELP);
1804 m_new_session_dialog->hide_all();
1810 ARDOUR_UI::close_session()
1817 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1819 Session *new_session;
1821 session_loaded = false;
1822 x = unload_session ();
1830 /* if it already exists, we must have write access */
1832 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1833 MessageDialog msg (*editor, _("\
1834 You do not have write access to this session.\n\
1835 This prevents the session from being loaded."));
1841 new_session = new Session (*engine, path, snap_name, mix_template);
1846 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1850 connect_to_session (new_session);
1852 //if (engine->running()) {
1853 //mixer->show_window();
1855 session_loaded = true;
1860 ARDOUR_UI::make_session_clean ()
1863 session->set_clean ();
1872 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1873 uint32_t control_channels,
1874 uint32_t master_channels,
1875 Session::AutoConnectOption input_connect,
1876 Session::AutoConnectOption output_connect,
1879 jack_nframes_t initial_length)
1881 Session *new_session;
1884 session_loaded = false;
1885 x = unload_session ();
1892 _session_is_new = true;
1895 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1896 control_channels, master_channels, nphysin, nphysout, initial_length);
1901 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1905 connect_to_session (new_session);
1907 //if (engine->running()) {
1908 //mixer->show_window();
1910 session_loaded = true;
1918 editor->show_window ();
1922 if (session && mixer) {
1923 // mixer->show_window ();
1932 ARDOUR_UI::show_splash ()
1935 about = new About();
1941 ARDOUR_UI::hide_splash ()
1949 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1953 removed = rep.paths.size();
1956 MessageDialog msgd (*editor,
1957 _("No audio files were ready for cleanup"),
1960 (Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE) );
1961 msgd.set_secondary_text (_("If this seems suprising, \n\
1962 check for any existing snapshots.\n\
1963 These may still include regions that\n\
1964 require some unused files to continue to exist."));
1970 ArdourDialog results (_("ardour: cleanup"), true, false);
1972 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
1973 CleanupResultsModelColumns() {
1977 Gtk::TreeModelColumn<Glib::ustring> visible_name;
1978 Gtk::TreeModelColumn<Glib::ustring> fullpath;
1982 CleanupResultsModelColumns results_columns;
1983 Glib::RefPtr<Gtk::ListStore> results_model;
1984 Gtk::TreeView results_display;
1986 results_model = ListStore::create (results_columns);
1987 results_display.set_model (results_model);
1988 results_display.append_column (list_title, results_columns.visible_name);
1990 results_display.set_name ("CleanupResultsList");
1991 results_display.set_headers_visible (true);
1992 results_display.set_headers_clickable (false);
1993 results_display.set_reorderable (false);
1995 Gtk::ScrolledWindow list_scroller;
1998 Gtk::HBox dhbox; // the hbox for the image and text
1999 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2000 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2002 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2004 if (rep.space < 1048576.0f) {
2006 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2008 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2012 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2014 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2018 dhbox.pack_start (*dimage, true, false, 5);
2019 dhbox.pack_start (txt, true, false, 5);
2021 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2022 TreeModel::Row row = *(results_model->append());
2023 row[results_columns.visible_name] = *i;
2024 row[results_columns.fullpath] = *i;
2027 list_scroller.add (results_display);
2028 list_scroller.set_size_request (-1, 150);
2029 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2031 dvbox.pack_start (dhbox, true, false, 5);
2032 dvbox.pack_start (list_scroller, true, false, 5);
2033 ddhbox.pack_start (dvbox, true, false, 5);
2035 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2036 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2037 results.set_default_response (RESPONSE_CLOSE);
2038 results.set_position (Gtk::WIN_POS_MOUSE);
2039 results.show_all_children ();
2040 results.set_resizable (false);
2047 ARDOUR_UI::cleanup ()
2050 /* shouldn't happen: menu item is insensitive */
2055 MessageDialog checker (_("Are you sure you want to cleanup?"),
2057 Gtk::MESSAGE_QUESTION,
2058 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2060 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2061 ALL undo/redo information will be lost if you cleanup.\n\
2062 After cleanup, unused audio files will be moved to a \
2063 \"dead sounds\" location."));
2065 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2066 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2067 checker.set_default_response (RESPONSE_CANCEL);
2069 checker.set_name (_("CleanupDialog"));
2070 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2071 checker.set_position (Gtk::WIN_POS_MOUSE);
2073 switch (checker.run()) {
2074 case RESPONSE_ACCEPT:
2080 Session::cleanup_report rep;
2082 editor->prepare_for_cleanup ();
2084 if (session->cleanup_sources (rep)) {
2088 display_cleanup_results (rep,
2091 The following %1 %2 not in use and \n\
2092 have been moved to:\n\
2094 Flushing the wastebasket will \n\
2095 release an additional\n\
2096 %4 %5bytes of disk space.\n"
2101 ARDOUR_UI::flush_trash ()
2104 /* shouldn't happen: menu item is insensitive */
2108 Session::cleanup_report rep;
2110 if (session->cleanup_trash_sources (rep)) {
2114 display_cleanup_results (rep,
2116 _("The following %1 %2 deleted from\n\
2118 releasing %4 %5bytes of disk space"));
2122 ARDOUR_UI::add_route ()
2130 if (add_route_dialog == 0) {
2131 add_route_dialog = new AddRouteDialog;
2132 editor->ensure_float (*add_route_dialog);
2135 if (add_route_dialog->is_visible()) {
2136 /* we're already doing this */
2140 ResponseType r = (ResponseType) add_route_dialog->run ();
2142 add_route_dialog->hide();
2145 case RESPONSE_ACCEPT:
2152 if ((count = add_route_dialog->count()) <= 0) {
2156 uint32_t input_chan = add_route_dialog->channels ();
2157 uint32_t output_chan;
2158 string name_template = add_route_dialog->name_template ();
2159 bool track = add_route_dialog->track ();
2161 Session::AutoConnectOption oac = session->get_output_auto_connect();
2163 if (oac & Session::AutoConnectMaster) {
2164 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2166 output_chan = input_chan;
2169 /* XXX do something with name template */
2173 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
2175 session_add_audio_bus (input_chan, output_chan);
2179 while (Main::events_pending()) {
2186 ARDOUR_UI::mixer_settings () const
2191 node = session->instant_xml(X_("Mixer"), session->path());
2193 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2197 node = new XMLNode (X_("Mixer"));
2204 ARDOUR_UI::editor_settings () const
2209 node = session->instant_xml(X_("Editor"), session->path());
2211 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2215 node = new XMLNode (X_("Editor"));
2221 ARDOUR_UI::keyboard_settings () const
2225 node = Config->extra_xml(X_("Keyboard"));
2228 node = new XMLNode (X_("Keyboard"));
2234 ARDOUR_UI::halt_on_xrun_message ()
2236 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2238 MessageDialog msg (*editor,
2239 _("Recording was stopped because your system could not keep up."));
2244 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
2246 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2248 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2252 delete deletion_list;
2256 ARDOUR_UI::disk_overrun_handler ()
2258 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2260 if (!have_disk_overrun_displayed) {
2261 have_disk_overrun_displayed = true;
2262 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2263 The disk system on your computer\n\
2264 was not able to keep up with Ardour.\n\
2266 Specifically, it failed to write data to disk\n\
2267 quickly enough to keep up with recording.\n"));
2269 have_disk_overrun_displayed = false;
2274 ARDOUR_UI::disk_underrun_handler ()
2276 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2278 if (!have_disk_underrun_displayed) {
2279 have_disk_underrun_displayed = true;
2280 MessageDialog msg (*editor,
2281 (_("The disk system on your computer\n\
2282 was not able to keep up with Ardour.\n\
2284 Specifically, it failed to read data from disk\n\
2285 quickly enough to keep up with playback.\n")));
2287 have_disk_underrun_displayed = false;
2292 ARDOUR_UI::disk_underrun_message_gone ()
2294 have_disk_underrun_displayed = false;
2298 ARDOUR_UI::disk_overrun_message_gone ()
2300 have_disk_underrun_displayed = false;
2304 ARDOUR_UI::pending_state_dialog ()
2306 ArdourDialog dialog ("pending state dialog");
2308 This session appears to have been in\n\
2309 middle of recording when ardour or\n\
2310 the computer was shutdown.\n\
2312 Ardour can recover any captured audio for\n\
2313 you, or it can ignore it. Please decide\n\
2314 what you would like to do.\n"));
2316 dialog.get_vbox()->pack_start (message);
2317 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2318 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2320 dialog.set_position (WIN_POS_CENTER);
2323 switch (dialog.run ()) {
2324 case RESPONSE_ACCEPT:
2332 ARDOUR_UI::disconnect_from_jack ()
2335 if( engine->disconnect_from_jack ()) {
2336 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2340 update_sample_rate (0);
2345 ARDOUR_UI::reconnect_to_jack ()
2348 if (engine->reconnect_to_jack ()) {
2349 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2353 update_sample_rate (0);
2358 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2360 engine->request_buffer_size (nframes);
2361 update_sample_rate (0);
2365 ARDOUR_UI::cmdline_new_session (string path)
2367 if (path[0] != '/') {
2368 char buf[PATH_MAX+1];
2371 getcwd (buf, sizeof (buf));
2378 new_session (false, path);
2380 _will_create_new_session_automatically = false; /* done it */
2381 return FALSE; /* don't call it again */
2385 ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
2387 Glib::RefPtr<Action> act;
2391 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2394 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2397 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2400 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2403 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2408 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2409 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
2410 Config->set_native_file_header_format (hf);
2412 session->reset_native_file_format ();
2419 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
2421 Glib::RefPtr<Action> act;
2425 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2428 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2433 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2435 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
2436 Config->set_native_file_data_format (sf);
2438 session->reset_native_file_format ();
2445 ARDOUR_UI::use_config ()
2447 Glib::RefPtr<Action> act;
2449 switch (Config->get_native_file_data_format ()) {
2451 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2454 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2459 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2460 ract->set_active ();
2463 switch (Config->get_native_file_header_format ()) {
2465 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2468 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2471 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2474 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2477 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2482 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2483 ract->set_active ();