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.
32 #include <pbd/error.h>
33 #include <pbd/basename.h>
34 #include <pbd/pathscanner.h>
35 #include <pbd/failed_constructor.h>
36 #include <gtkmm2ext/gtk_ui.h>
37 #include <gtkmm2ext/pix.h>
38 #include <gtkmm2ext/utils.h>
39 #include <gtkmm2ext/click_box.h>
40 #include <gtkmm2ext/selector.h>
41 #include <gtkmm2ext/fastmeter.h>
42 #include <gtkmm2ext/stop_signal.h>
43 #include <gtkmm2ext/popup.h>
45 #include <midi++/port.h>
46 #include <midi++/mmc.h>
48 #include <ardour/ardour.h>
49 #include <ardour/port.h>
50 #include <ardour/audioengine.h>
51 #include <ardour/playlist.h>
52 #include <ardour/utils.h>
53 #include <ardour/diskstream.h>
54 #include <ardour/filesource.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/session_diskstream.h>
57 #include <ardour/port.h>
58 #include <ardour/audio_track.h>
60 #include "ardour_ui.h"
61 #include "ardour_message.h"
62 #include "public_editor.h"
63 #include "audio_clock.h"
68 #include "keyboard_target.h"
69 #include "add_route_dialog.h"
70 #include "new_session_dialog.h"
73 #include "gui_thread.h"
77 using namespace ARDOUR;
78 using namespace Gtkmm2ext;
82 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
83 SoundFileSelector* ARDOUR_UI::sfdb_window = 0;
85 sigc::signal<void,bool> ARDOUR_UI::Blink;
86 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
87 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
88 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
91 static const gchar *h_meter_strip_xpm[] = {
280 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+",
281 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+",
282 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++",
283 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++",
284 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++"};
287 static const gchar * v_meter_strip_xpm[] = {
770 static const char* channel_setup_names[] = {
781 vector<string> channel_combo_strings;
783 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
785 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
787 primary_clock (X_("TransportClockDisplay"), true, false, true),
788 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
789 preroll_clock (X_("PreRollClock"), true, true),
790 postroll_clock (X_("PostRollClock"), true, true),
794 adjuster_table (3, 3),
798 preroll_button (_("pre\nroll")),
799 postroll_button (_("post\nroll")),
803 big_clock ("BigClockDisplay", true),
807 shuttle_units_button (_("% ")),
808 shuttle_style_button (_("spring")),
810 punch_in_button (_("punch\nin")),
811 punch_out_button (_("punch\nout")),
812 auto_return_button (_("auto\nreturn")),
813 auto_play_button (_("auto\nplay")),
814 auto_input_button (_("auto\ninput")),
815 click_button (_("click")),
816 follow_button (_("follow\nPH")),
817 auditioning_alert_button (_("AUDITIONING")),
818 solo_alert_button (_("SOLO")),
820 session_selector (1, 0),
825 using namespace Gtk::Menu_Helpers;
829 /* actually, its already loaded, but ... */
831 cerr << "Loading UI configuration file " << rcfile << endl;
835 if (theArdourUI == 0) {
842 _session_is_new = false;
843 big_clock_window = 0;
844 session_selector_window = 0;
845 last_key_press_time = 0;
846 connection_editor = 0;
847 add_route_dialog = 0;
853 new_session_window = 0;
854 open_session_selector = 0;
855 have_configure_timeout = false;
856 have_disk_overrun_displayed = false;
857 have_disk_underrun_displayed = false;
858 _will_create_new_session_automatically = false;
859 session_loaded = false;
861 last_configure_time.tv_sec = 0;
862 last_configure_time.tv_usec = 0;
864 shuttle_grabbed = false;
867 set_shuttle_units (Percentage);
868 set_shuttle_behaviour (Sprung);
870 shuttle_unit_menu.items().push_back (MenuElem (_("Percentage"), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units),
872 shuttle_unit_menu.items().push_back (MenuElem (_("Semitones"), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units),
875 shuttle_style_menu.items().push_back (MenuElem (_("Sprung"), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour),
877 shuttle_style_menu.items().push_back (MenuElem (_("Wheel"), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour),
880 gettimeofday (&last_peak_grab, 0);
881 gettimeofday (&last_shuttle_request, 0);
883 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
884 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
885 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
886 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
888 /* handle pending state with a dialog */
890 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
892 channel_combo_strings = internationalize (channel_setup_names);
894 /* have to wait for AudioEngine and Configuration before proceeding */
898 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
900 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
902 string msg = compose (_("\
903 You cannot record-enable\n\
905 because it has no input connections.\n\
906 You would be wasting space recording silence."),
909 ArdourMessage message (editor, X_("cannotrecord"), msg);
913 ARDOUR_UI::set_engine (AudioEngine& e)
917 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
918 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
919 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
920 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
924 keyboard = new Keyboard;
925 install_keybindings ();
927 FastMeter::set_vertical_xpm (v_meter_strip_xpm);
928 FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
930 if (setup_windows ()) {
931 throw failed_constructor ();
934 if (GTK_ARDOUR::show_key_actions) {
935 KeyboardTarget::show_all_actions ();
939 /* start with timecode, metering enabled
942 blink_timeout_tag = -1;
944 /* this being a GUI and all, we want peakfiles */
946 FileSource::set_build_peakfiles (true);
947 FileSource::set_build_missing_peakfiles (true);
949 if (Source::start_peak_thread ()) {
950 throw failed_constructor();
953 /* start the time-of-day-clock */
955 update_wall_clock ();
956 Main::timeout.connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
958 update_disk_space ();
960 update_sample_rate (engine->frame_rate());
962 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
963 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
966 ARDOUR_UI::~ARDOUR_UI ()
968 save_ardour_state ();
982 if (add_route_dialog) {
983 delete add_route_dialog;
986 Source::stop_peak_thread ();
990 ARDOUR_UI::configure_timeout ()
995 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
996 /* no configure events yet */
1000 gettimeofday (&now, 0);
1001 timersub (&now, &last_configure_time, &diff);
1003 /* force a gap of 0.5 seconds since the last configure event
1006 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
1009 have_configure_timeout = false;
1010 save_ardour_state ();
1016 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
1018 if (have_configure_timeout) {
1019 gettimeofday (&last_configure_time, 0);
1022 t.connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
1023 have_configure_timeout = true;
1030 ARDOUR_UI::save_ardour_state ()
1032 if (!keyboard || !mixer || !editor) {
1036 /* XXX this is all a bit dubious. add_extra_xml() uses
1037 a different lifetime model from add_instant_xml().
1040 XMLNode* node = new XMLNode (keyboard->get_state());
1041 Config->add_extra_xml (*node);
1042 Config->save_state();
1044 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
1045 XMLNode& mnode (mixer->get_state());
1048 session->add_instant_xml(enode, session->path());
1049 session->add_instant_xml(mnode, session->path());
1051 Config->add_instant_xml(enode, Config->get_user_ardour_path());
1052 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
1057 ARDOUR_UI::startup ()
1059 /* Once the UI is up and running, start the audio engine. Doing
1060 this before the UI is up and running can cause problems
1061 when not running with SCHED_FIFO, because the amount of
1062 CPU and disk work needed to get the UI started can interfere
1063 with the scheduling of the audio thread.
1066 Gtk::Main::idle.connect (mem_fun(*this, &ARDOUR_UI::start_engine));
1072 if (session && session->dirty()) {
1073 switch (ask_about_saving_session(_("quit"))) {
1078 /* use the default name */
1079 if (save_state_canfail ("")) {
1080 /* failed - don't quit */
1081 ArdourMessage (editor, X_("badsave dialog"),
1083 Ardour was unable to save your session.\n\n\
1084 If you still wish to quit, please use the\n\n\
1085 \"Just quit\" option."));
1098 ARDOUR_UI::ask_about_saving_session (string what)
1100 ArdourDialog window ("saving dialog");
1102 Gtk::Label prompt_label;
1103 Gtk::HBox button_packer;
1107 msg = compose(_("Save and %1"), what);
1109 Gtk::Button save_button (msg);
1110 save_button.set_name ("EditorGTKButton");
1112 msg = compose(_("Just %1"), what);
1114 Gtk::Button nosave_button (msg);
1115 nosave_button.set_name ("EditorGTKButton");
1117 msg = compose(_("Don't %1"), what);
1119 Gtk::Button noquit_button (msg);
1120 noquit_button.set_name ("EditorGTKButton");
1125 if (session->snap_name() == session->name()) {
1126 type = _("session");
1128 type = _("snapshot");
1130 prompt = compose(_("The %1\n\"%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?"),
1131 type, session->snap_name());
1133 prompt_label.set_text (prompt);
1134 prompt_label.set_alignment (0.5, 0.5);
1135 prompt_label.set_name (X_("PrompterLabel"));
1137 save_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 1));
1138 nosave_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 0));
1139 noquit_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), -1));
1141 button_packer.set_spacing (10);
1142 button_packer.pack_start (save_button);
1143 button_packer.pack_start (nosave_button);
1144 button_packer.pack_start (noquit_button);
1146 packer.set_spacing (10);
1147 packer.set_border_width (10);
1148 packer.pack_start (prompt_label);
1149 packer.pack_start (button_packer);
1151 window.set_name (_("Prompter"));
1152 window.set_title (_("ardour: save session?"));
1153 window.set_position (Gtk::WIN_POS_MOUSE);
1154 window.set_modal (true);
1155 window.add (packer);
1159 window.get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
1160 window.set_keyboard_input (true);
1162 save_the_session = 0;
1164 editor->ensure_float (window);
1168 return window.run_status();
1172 ARDOUR_UI::every_second ()
1175 update_buffer_load ();
1176 update_disk_space ();
1177 // update_disk_rate ();
1182 ARDOUR_UI::every_point_one_seconds ()
1185 struct timeval diff;
1187 /* do not attempt to grab peak power more than once per cycle.
1190 gettimeofday (&now, 0);
1191 timersub (&now, &last_peak_grab, &diff);
1193 if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
1194 IO::GrabPeakPower(); /* EMIT_SIGNAL */
1195 last_peak_grab = now;
1198 update_speed_display ();
1199 RapidScreenUpdate(); /* EMIT_SIGNAL */
1204 ARDOUR_UI::every_point_zero_one_seconds ()
1206 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
1211 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
1215 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
1217 if (!engine->connected()) {
1219 snprintf (buf, sizeof (buf), _("disconnected"));
1223 jack_nframes_t rate = engine->frame_rate();
1225 if (fmod (rate, 1000.0) != 0.0) {
1226 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
1227 (float) rate/1000.0f,
1228 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1230 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
1232 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1236 sample_rate_label.set_text (buf);
1240 ARDOUR_UI::update_cpu_load ()
1243 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
1244 cpu_load_label.set_text (buf);
1248 ARDOUR_UI::update_disk_rate ()
1253 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"),
1254 session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
1255 disk_rate_label.set_text (buf);
1257 disk_rate_label.set_text ("");
1262 ARDOUR_UI::update_buffer_load ()
1267 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
1268 session->playback_load(), session->capture_load());
1269 buffer_load_label.set_text (buf);
1271 buffer_load_label.set_text ("");
1276 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
1278 if (ds.record_enabled()) {
1279 rec_enabled_diskstreams++;
1284 ARDOUR_UI::update_disk_space()
1290 jack_nframes_t frames = session->available_capture_duration();
1293 if (frames == max_frames) {
1294 strcpy (buf, _("space: 24hrs+"));
1299 jack_nframes_t fr = session->frame_rate();
1301 if (session->actively_recording()){
1303 rec_enabled_diskstreams = 0;
1304 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
1306 if (rec_enabled_diskstreams) {
1307 frames /= rec_enabled_diskstreams;
1312 /* hmmm. shall we divide by the route count? or the diskstream count?
1313 or what? for now, do nothing ...
1318 hrs = frames / (fr * 3600);
1319 frames -= hrs * fr * 3600;
1320 mins = frames / (fr * 60);
1321 frames -= mins * fr * 60;
1324 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
1327 disk_space_label.set_text (buf);
1331 ARDOUR_UI::update_wall_clock ()
1338 tm_now = localtime (&now);
1340 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1341 wall_clock_label.set_text (buf);
1347 ARDOUR_UI::toggle_recording_plugins ()
1349 /* XXX use toggle_some_session_state */
1355 session->set_recording_plugins (!session->get_recording_plugins());
1359 ARDOUR_UI::toggle_auto_play ()
1362 toggle_some_session_state (auto_play_button,
1363 &Session::get_auto_play,
1364 &Session::set_auto_play);
1368 ARDOUR_UI::toggle_auto_return ()
1371 toggle_some_session_state (auto_return_button,
1372 &Session::get_auto_return,
1373 &Session::set_auto_return);
1377 ARDOUR_UI::toggle_click ()
1379 toggle_some_session_state (click_button,
1380 &Session::get_clicking,
1381 &Session::set_clicking);
1385 ARDOUR_UI::follow_changed ()
1393 if (follow_button.get_active() != (x = editor->follow_playhead())) {
1394 follow_button.set_active (x);
1399 ARDOUR_UI::toggle_follow ()
1407 if (editor->follow_playhead() != (x = follow_button.get_active())) {
1408 editor->set_follow_playhead (x);
1413 ARDOUR_UI::toggle_session_auto_loop ()
1416 if (session->get_auto_loop()) {
1417 if (session->transport_rolling()) {
1421 session->request_auto_loop (false);
1425 session->request_auto_loop (true);
1431 ARDOUR_UI::toggle_session_punch_in ()
1434 session->set_punch_in (!session->get_punch_in());
1439 ARDOUR_UI::toggle_punch_out ()
1441 toggle_some_session_state (punch_out_button,
1442 &Session::get_punch_out,
1443 &Session::set_punch_out);
1447 ARDOUR_UI::toggle_punch_in ()
1449 toggle_some_session_state (punch_in_button,
1450 &Session::get_punch_in,
1451 &Session::set_punch_in);
1455 ARDOUR_UI::map_button_state ()
1458 map_some_session_state (auto_return_button,
1459 &Session::get_auto_return);
1460 map_some_session_state (auto_play_button,
1461 &Session::get_auto_play);
1462 map_some_session_state (auto_input_button,
1463 &Session::get_auto_input);
1464 map_some_session_state (punch_in_button,
1465 &Session::get_punch_in);
1466 map_some_session_state (punch_out_button,
1467 &Session::get_punch_out);
1468 map_some_session_state (click_button,
1469 &Session::get_clicking);
1473 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
1475 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
1479 ARDOUR_UI::map_control_change (Session::ControlType t)
1482 case Session::AutoPlay:
1483 map_some_session_state (auto_play_button, &Session::get_auto_play);
1486 case Session::AutoLoop:
1489 case Session::AutoReturn:
1490 map_some_session_state (auto_return_button, &Session::get_auto_return);
1493 case Session::AutoInput:
1494 map_some_session_state (auto_input_button, &Session::get_auto_input);
1497 case Session::PunchOut:
1498 map_some_session_state (punch_in_button, &Session::get_punch_out);
1501 case Session::PunchIn:
1502 map_some_session_state (punch_in_button, &Session::get_punch_in);
1505 case Session::Clicking:
1506 map_some_session_state (click_button, &Session::get_clicking);
1509 case Session::SlaveType:
1510 // map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
1513 case Session::SendMTC:
1514 // map_some_session_state (send_mtc_button, &Session::get_send_mtc);
1517 case Session::SendMMC:
1518 // map_some_session_state (send_mmc_button, &Session::get_send_mmc);
1521 case Session::MMCControl:
1522 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1525 case Session::MidiFeedback:
1526 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1528 case Session::MidiControl:
1529 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1535 case Session::RecordingPlugins:
1538 case Session::CrossFadesActive:
1541 case Session::EditingMode:
1544 case Session::PlayRange:
1547 case Session::AlignChoice:
1548 /* don't care, this is handled by the options editor */
1550 case Session::SeamlessLoop:
1551 /* don't care, this is handled by the options editor */
1558 ARDOUR_UI::control_methods_adjusted ()
1563 which_method = (int) online_control_button->adjustment.get_value();
1564 switch (which_method) {
1566 allow_mmc_and_local ();
1572 allow_local_only ();
1575 fatal << _("programming error: impossible control method") << endmsg;
1581 ARDOUR_UI::mmc_device_id_adjusted ()
1586 int dev_id = (int) mmc_id_button->adjustment.get_value();
1587 mmc->set_device_id (dev_id);
1593 ARDOUR_UI::map_some_session_state (ToggleButton& button,
1594 bool (Session::*get)() const)
1603 if (button.get_active() != (x = (session->*get)())) {
1604 button.set_active (x);
1609 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
1610 bool (Session::*get)() const,
1611 void (Session::*set)(bool))
1621 button_state = button.get_active ();
1622 session_state = (session->*get)();
1624 if (button_state != session_state) {
1625 (session->*set) (button_state);
1628 /* check that it worked, and reverse
1629 the button state if it didn't
1632 if ((session->*get)() != button_state) {
1633 button->set_active (!button_state);
1641 ARDOUR_UI::session_menu (GdkEventButton *ev)
1643 session_popup_menu->popup (0, 0, 0, 0);
1648 ARDOUR_UI::redisplay_recent_sessions ()
1650 using namespace Gtkmm2ext;
1651 using namespace Gtk::CTree_Helpers;
1653 vector<string *> *sessions;
1654 vector<string *>::iterator i;
1655 RecentSessionsSorter cmp;
1657 /* ---------------------------------------- */
1658 /* XXX MAKE ME A FUNCTION (no CTree::clear() in gtkmm 1.2) */
1660 gtk_ctree_remove_node (session_selector.gobj(), NULL);
1661 /* ---------------------------------------- */
1665 ARDOUR::read_recent_sessions (rs);
1668 session_selector.thaw();
1671 /* sort them alphabetically */
1672 sort(rs.begin(), rs.end(), cmp);
1673 sessions = new vector<string*>;
1674 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1675 sessions->push_back (new string ((*i).second));
1678 session_selector.freeze();
1680 for (i = sessions->begin(); i != sessions->end(); ++i) {
1682 vector<string*>* states;
1683 vector<const gchar*> item;
1684 string fullpath = *(*i);
1686 /* remove any trailing / */
1688 if (fullpath[fullpath.length()-1] == '/') {
1689 fullpath = fullpath.substr (0, fullpath.length()-1);
1692 /* now get available states for this session */
1694 if ((states = Session::possible_states(fullpath)) == 0) {
1695 /* no state file? */
1699 /* OK, try to add entries for this session */
1702 /* add the parent */
1705 string basen = PBD::basename (fullpath);
1706 item.push_back (basen.c_str());
1707 session_selector.rows().push_back (Element (item));
1709 session_selector.rows().back().set_data (new string (fullpath), deferred_delete<string>);
1711 if (states->size() == 1) {
1713 /* only 1 state, show it at the top level */
1715 session_selector.rows().back().set_leaf (true);
1719 session_selector.rows().back().set_leaf (false);
1721 vector<string *>::iterator i2;
1723 /* add the children */
1725 for (i2 = states->begin(); i2 != states->end(); ++i2) {
1727 string statename = *(*i2);
1730 item.push_back (statename.c_str());
1732 session_selector.rows().back().subtree().push_back (Element (item));
1733 session_selector.rows().back().subtree().back().set_data (new string (statename),
1734 deferred_delete<string>);
1735 session_selector.rows().back().subtree().back().set_leaf (true);
1744 session_selector.thaw();
1749 ARDOUR_UI::session_selection (Gtk::CTree_Helpers::Row row, gint column)
1751 using namespace Gtk::CTree_Helpers;
1753 string session_name;
1754 string session_path;
1755 string session_state;
1757 if (!row.is_leaf()) {
1762 string *stp = static_cast<string *> (row.get_data());
1764 if ((*stp)[0] != '/' && (*stp)[0] != '.') {
1766 /* its a state file node, so get the parent for the session information,
1767 and combine with the state file name.
1770 string *spp = static_cast<string *> (row.get_parent().get_data());
1772 session_name = *spp;
1773 session_path = *spp;
1774 session_state = *stp;
1778 /* its a session directory node, so just get the session path,
1779 and use "default" to load the state.
1782 string *spp = static_cast<string *> (row.get_data());
1784 session_name = *spp;
1785 session_path = *spp;
1786 session_state = PBD::basename (*spp);
1789 session_selector_window->hide ();
1790 _session_is_new = false;
1791 load_session (session_path, session_state);
1795 ARDOUR_UI::build_session_selector ()
1797 session_selector_window = new ArdourDialog ("session selector");
1799 Gtk::VBox *vpacker = new Gtk::VBox;
1800 Gtk::ScrolledWindow *scroller = new Gtk::ScrolledWindow;
1801 Gtk::HBox *button_packer = new Gtk::HBox;
1802 Gtk::Button *cancel_button = new Gtk::Button (_("cancel"));
1803 Gtk::Button *rescan_button = new Gtk::Button (_("rescan"));
1805 button_packer->pack_start (*rescan_button);
1806 button_packer->pack_start (*cancel_button);
1808 vpacker->pack_start (*scroller);
1809 vpacker->pack_start (*button_packer, false, false);
1811 scroller->add (session_selector);
1812 scroller->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1814 session_selector_window->add (*vpacker);
1815 session_selector_window->set_name ("SessionSelectorWindow");
1816 session_selector_window->set_size_request (200, 400);
1818 session_selector_window->signal_delete_event().connect (bind (ptr_fun (just_hide_it), static_cast<Gtk::Window*>(session_selector_window)));
1819 cancel_button-.signal_clicked().connect (bind (mem_fun(*this, &ARDOUR_UI::hide_dialog), session_selector_window));
1820 session_selector.tree_select_row.connect (mem_fun(*this, &ARDOUR_UI::session_selection));
1824 ARDOUR_UI::fs_cancel_clicked (Gtk::FileSelection* fs)
1827 fs->get_selection_entry()->set_text("");
1828 allow_focus (false);
1832 ARDOUR_UI::fs_delete_event (GdkEventAny* ev, Gtk::FileSelection* fs)
1834 fs_cancel_clicked (fs);
1839 ARDOUR_UI::open_session ()
1841 /* popup selector window */
1843 if (open_session_selector == 0) {
1844 open_session_selector = new Gtk::FileSelection(_("open session"));
1845 open_session_selector->get_ok_button()-.signal_clicked().connect (mem_fun(*this, &ARDOUR_UI::open_ok_clicked));
1846 open_session_selector->get_cancel_button()-.signal_clicked().connect (bind (mem_fun(*this, &ARDOUR_UI::fs_cancel_clicked), open_session_selector));
1847 open_session_selector->signal_delete_event().connect (bind (mem_fun(*this, &ARDOUR_UI::fs_delete_event), open_session_selector));
1850 open_session_selector->show_all ();
1853 /* wait for selection */
1857 ARDOUR_UI::open_ok_clicked ()
1859 open_session_selector->hide_all();
1860 string session_path = open_session_selector->get_filename();
1864 if (session_path.length() > 0) {
1865 if (Session::find_session (session_path, path, name, isnew) == 0) {
1866 _session_is_new = isnew;
1867 load_session (path, name);
1871 open_session_selector->get_selection_entry()->set_text("");
1873 /* XXX hack hack hack */
1875 GtkCList* clist = (GtkCList*) open_session_selector->gobj()->file_list;
1876 gtk_clist_unselect_all (clist);
1882 ARDOUR_UI::open_recent_session ()
1884 /* popup selector window */
1886 if (session_selector_window == 0) {
1887 build_session_selector ();
1890 redisplay_recent_sessions ();
1891 session_selector_window->show_all ();
1893 /* wait for selection */
1897 ARDOUR_UI::session_add_midi_track ()
1899 cerr << _("Patience is a virtue.\n");
1903 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1908 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1914 if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1915 error << _("could not create new audio track") << endmsg;
1918 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1919 error << _("could not create new audio bus") << endmsg;
1924 if (need_control_room_outs) {
1930 route->set_stereo_control_outs (control_lr_channels);
1931 route->control_outs()->set_stereo_pan (pans, this);
1933 #endif /* CONTROLOUTS */
1937 ArdourMessage msg (editor, X_("noport dialog"),
1938 _("There are insufficient JACK ports available\n\
1939 to create a new track or bus.\n\
1940 You should save Ardour, exit and\n\
1941 restart JACK with more ports."));
1946 ARDOUR_UI::diskstream_added (DiskStream* ds)
1948 // meter_bridge_dialog_check->set_sensitive (true);
1952 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1954 jack_nframes_t _preroll;
1957 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1959 if (new_position > _preroll) {
1960 new_position -= _preroll;
1965 session->request_locate (new_position);
1970 ARDOUR_UI::transport_goto_start ()
1973 session->request_locate (0);
1976 /* force displayed area in editor to start no matter
1977 what "follow playhead" setting is.
1981 editor->reposition_x_origin (0);
1987 ARDOUR_UI::transport_goto_end ()
1990 jack_nframes_t frame = session->current_end_frame();
1991 session->request_locate (frame);
1993 /* force displayed area in editor to start no matter
1994 what "follow playhead" setting is.
1998 editor->reposition_x_origin (frame);
2004 ARDOUR_UI::mouse_transport_stop (GdkEventButton *ev)
2009 if (session->transport_stopped()) {
2010 session->request_locate (session->last_transport_start());
2012 if (session->get_auto_loop()) {
2013 session->request_auto_loop (false);
2016 Keyboard::ModifierMask mask = Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift);
2017 session->request_stop (Keyboard::modifier_state_equals (ev->state, mask));
2025 ARDOUR_UI::mouse_transport_roll (GdkEventButton* ev)
2032 ARDOUR_UI::transport_stop ()
2038 if (session->is_auditioning()) {
2039 session->cancel_audition ();
2043 if (session->get_auto_loop()) {
2044 session->request_auto_loop (false);
2047 session->request_stop ();
2051 ARDOUR_UI::transport_stop_and_forget_capture ()
2054 session->request_stop (true);
2059 ARDOUR_UI::remove_last_capture()
2062 editor->remove_last_capture();
2067 ARDOUR_UI::transport_record ()
2070 switch (session->record_status()) {
2071 case Session::Disabled:
2072 if (session->ntracks() == 0) {
2073 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
2074 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
2077 session->maybe_enable_record ();
2079 case Session::Recording:
2080 case Session::Enabled:
2081 session->disable_record ();
2087 ARDOUR_UI::transport_roll ()
2095 rolling = session->transport_rolling ();
2097 if (session->get_auto_loop()) {
2098 session->request_auto_loop (false);
2099 auto_loop_button.set_active (false);
2100 roll_button.set_active (true);
2101 } else if (session->get_play_range ()) {
2102 session->request_play_range (false);
2103 play_selection_button.set_active (false);
2104 } else if (rolling) {
2105 session->request_locate (session->last_transport_start(), true);
2108 session->request_transport_speed (1.0f);
2112 ARDOUR_UI::transport_loop()
2115 if (session->get_auto_loop()) {
2116 if (session->transport_rolling()) {
2117 Location * looploc = session->locations()->auto_loop_location();
2119 session->request_locate (looploc->start(), true);
2124 session->request_auto_loop (true);
2130 ARDOUR_UI::transport_play_selection ()
2136 if (!session->get_play_range()) {
2137 session->request_stop ();
2140 editor->play_selection ();
2144 ARDOUR_UI::transport_rewind (int option)
2146 float current_transport_speed;
2149 current_transport_speed = session->transport_speed();
2151 if (current_transport_speed >= 0.0f) {
2154 session->request_transport_speed (-1.0f);
2157 session->request_transport_speed (-4.0f);
2160 session->request_transport_speed (-0.5f);
2165 session->request_transport_speed (current_transport_speed * 1.5f);
2171 ARDOUR_UI::transport_forward (int option)
2173 float current_transport_speed;
2176 current_transport_speed = session->transport_speed();
2178 if (current_transport_speed <= 0.0f) {
2181 session->request_transport_speed (1.0f);
2184 session->request_transport_speed (4.0f);
2187 session->request_transport_speed (0.5f);
2192 session->request_transport_speed (current_transport_speed * 1.5f);
2198 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
2206 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2207 Port *port = ds->io()->input (0);
2208 port->request_monitor_input (!port->monitoring_input());
2213 ARDOUR_UI::toggle_record_enable (guint32 dstream)
2221 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2222 ds->set_record_enabled (!ds->record_enabled(), this);
2227 ARDOUR_UI::queue_transport_change ()
2229 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
2233 ARDOUR_UI::map_transport_state ()
2235 float sp = session->transport_speed();
2238 transport_rolling ();
2239 } else if (sp < 0.0f) {
2240 transport_rewinding ();
2241 } else if (sp > 0.0f) {
2242 transport_forwarding ();
2244 transport_stopped ();
2249 ARDOUR_UI::send_all_midi_feedback ()
2252 session->send_all_midi_feedback();
2257 ARDOUR_UI::allow_local_only ()
2263 ARDOUR_UI::allow_mmc_only ()
2269 ARDOUR_UI::allow_mmc_and_local ()
2275 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
2277 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
2278 (int) adj.get_value()].c_str());
2282 ARDOUR_UI::engine_stopped ()
2284 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
2286 jack_disconnect_item->set_sensitive (false);
2287 jack_reconnect_item->set_sensitive (true);
2288 jack_bufsize_menu->set_sensitive (false);
2293 ARDOUR_UI::engine_running ()
2295 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
2297 jack_disconnect_item->set_sensitive (true);
2298 jack_reconnect_item->set_sensitive (false);
2299 jack_bufsize_menu->set_sensitive (true);
2303 ARDOUR_UI::engine_halted ()
2305 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
2307 jack_disconnect_item->set_sensitive (false);
2308 jack_reconnect_item->set_sensitive (true);
2309 jack_bufsize_menu->set_sensitive (false);
2311 update_sample_rate (0);
2313 ArdourMessage msg (editor, X_("halted"),
2315 JACK has either been shutdown or it\n\
2316 disconnected Ardour because Ardour\n\
2317 was not fast enough. You can save the\n\
2318 session and/or try to reconnect to JACK ."));
2322 ARDOUR_UI::do_engine_start ()
2328 catch (AudioEngine::PortRegistrationFailure& err) {
2330 error << _("Unable to create all required ports")
2338 error << _("Unable to start the session running")
2348 ARDOUR_UI::start_engine ()
2350 if (do_engine_start () == 0) {
2351 if (session && _session_is_new) {
2352 /* we need to retain initial visual
2353 settings for a new session
2355 session->save_state ("");
2358 /* there is too much going on, in too many threads, for us to
2359 end up with a clean session. So wait 1 second after loading,
2360 and fix it up. its ugly, but until i come across a better
2361 solution, its what we have.
2364 Main::timeout.connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
2371 ARDOUR_UI::update_clocks ()
2373 Clock (session->audible_frame()); /* EMIT_SIGNAL */
2377 ARDOUR_UI::start_clocking ()
2379 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
2383 ARDOUR_UI::stop_clocking ()
2385 clock_signal_connection.disconnect ();
2389 ARDOUR_UI::toggle_clocking ()
2392 if (clock_button.get_active()) {
2401 ARDOUR_UI::_blink (void *arg)
2404 ((ARDOUR_UI *) arg)->blink ();
2411 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
2415 ARDOUR_UI::start_blinking ()
2417 /* Start the blink signal. Everybody with a blinking widget
2418 uses Blink to drive the widget's state.
2421 if (blink_timeout_tag < 0) {
2423 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
2428 ARDOUR_UI::stop_blinking ()
2430 if (blink_timeout_tag >= 0) {
2431 gtk_timeout_remove (blink_timeout_tag);
2432 blink_timeout_tag = -1;
2438 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
2440 using namespace Gtk;
2441 using namespace Menu_Helpers;
2443 if (dstream.hidden()) {
2447 MenuList& items = diskstream_menu->items();
2448 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
2452 ARDOUR_UI::diskstream_selected (gint32 id)
2454 selected_dstream = id;
2459 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
2461 using namespace Gtk;
2462 using namespace Menu_Helpers;
2468 diskstream_menu = new Menu();
2469 diskstream_menu->set_name ("ArdourContextMenu");
2470 using namespace Gtk;
2471 using namespace Menu_Helpers;
2473 MenuList& items = diskstream_menu->items();
2474 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
2476 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
2479 diskstream_menu->popup (ev->button, ev->time);
2481 diskstream_menu->popup (0, 0);
2484 selected_dstream = -1;
2488 delete diskstream_menu;
2490 return selected_dstream;
2494 ARDOUR_UI::name_io_setup (AudioEngine& engine,
2500 if (io.n_inputs() == 0) {
2505 /* XXX we're not handling multiple ports yet. */
2507 const char **connections = io.input(0)->get_connections();
2509 if (connections == 0 || connections[0] == '\0') {
2512 buf = connections[0];
2519 if (io.n_outputs() == 0) {
2524 /* XXX we're not handling multiple ports yet. */
2526 const char **connections = io.output(0)->get_connections();
2528 if (connections == 0 || connections[0] == '\0') {
2531 buf = connections[0];
2539 ARDOUR_UI::snapshot_session ()
2541 ArdourPrompter prompter (true);
2547 now = now.substr (0, now.length() - 1);
2549 prompter.set_name ("Prompter");
2550 prompter.set_prompt (_("Name for snapshot"));
2551 prompter.set_initial_text (now);
2552 prompter.done.connect (Gtk::Main::quit.slot());
2553 prompter.show_all ();
2557 if (prompter.status == Gtkmm2ext::Prompter::entered) {
2560 prompter.get_result (snapname);
2561 if (snapname.length()){
2562 save_state (snapname);
2568 ARDOUR_UI::save_state (string name)
2570 (void) save_state_canfail (name);
2574 ARDOUR_UI::save_state_canfail (string name)
2579 if (name.length() == 0) {
2580 name = session->snap_name();
2583 if ((ret = session->save_state (name)) != 0) {
2587 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2592 ARDOUR_UI::restore_state (string name)
2595 if (name.length() == 0) {
2596 name = session->name();
2598 session->restore_state (name);
2603 ARDOUR_UI::allow_focus (bool yn)
2606 keyboard->allow_focus (yn);
2611 ARDOUR_UI::primary_clock_value_changed ()
2614 session->request_locate (primary_clock.current_time ());
2619 ARDOUR_UI::secondary_clock_value_changed ()
2622 session->request_locate (secondary_clock.current_time ());
2627 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
2629 if (session && dstream && dstream->record_enabled()) {
2631 Session::RecordState rs;
2633 rs = session->record_status ();
2636 case Session::Disabled:
2637 case Session::Enabled:
2638 if (w->get_state() != GTK_STATE_SELECTED) {
2639 w->set_state (GTK_STATE_SELECTED);
2643 case Session::Recording:
2644 if (w->get_state() != GTK_STATE_ACTIVE) {
2645 w->set_state (GTK_STATE_ACTIVE);
2651 if (w->get_state() != Gtk::STATE_NORMAL) {
2652 w->set_state (Gtk::STATE_NORMAL);
2658 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2664 switch (session->record_status()) {
2665 case Session::Enabled:
2667 rec_button.set_state (GTK_STATE_ACTIVE);
2669 rec_button.set_state (Gtk::STATE_NORMAL);
2673 case Session::Recording:
2674 rec_button.set_state (GTK_STATE_ACTIVE);
2678 rec_button.set_active (false);
2679 rec_button.set_state (Gtk::STATE_NORMAL);
2685 ARDOUR_UI::generic_focus_in_event (GdkEventFocus *ev)
2687 ARDOUR_UI::instance()->allow_focus (true);
2692 ARDOUR_UI::generic_focus_out_event (GdkEventFocus *ev)
2694 ARDOUR_UI::instance()->allow_focus (false);
2699 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
2707 ARDOUR_UI::start_keyboard_prefix ()
2709 keyboard->start_prefix();
2713 ARDOUR_UI::save_template ()
2716 ArdourPrompter prompter (true);
2717 prompter.set_name ("Prompter");
2718 prompter.set_prompt (_("Name for mix template:"));
2719 prompter.set_initial_text(session->name() + _("-template"));
2721 prompter.done.connect(Gtk::Main::quit.slot());
2722 prompter.show_all();
2726 if (prompter.status == Gtkmm2ext::Prompter::entered) {
2729 prompter.get_result (name);
2731 if (name.length()) {
2732 session->save_template (name);
2738 ARDOUR_UI::new_session (bool startup, string predetermined_path)
2740 if (new_session_window == 0){
2741 new_session_window = new NewSessionDialog (*engine, startup, predetermined_path);
2742 editor->ensure_float (*new_session_window);
2745 new_session_window->run ();
2747 /* write favorites either way */
2748 Session::FavoriteDirs favs;
2749 new_session_window->file_selector.get_favorites (favs);
2750 Session::write_favorite_dirs (favs);
2752 if (new_session_window->run_status()) {
2756 string session_path = new_session_window->file_selector.get_path ();
2757 string session_name = PBD::basename (session_path);
2759 // Check that it doesn't already exist.
2760 access(session_path.c_str(), R_OK);
2761 if (errno != ENOENT){
2762 error << compose(_("Session %1 already exists at %2"), session_name, session_path) << endmsg;
2766 _session_is_new = true;
2768 if (session_path[session_path.length()-1] != '/') {
2770 string template_name = new_session_window->get_template_name ();
2772 if (template_name.length()) {
2774 load_session (session_path, session_name, &template_name);
2780 Session::AutoConnectOption iconnect;
2781 Session::AutoConnectOption oconnect;
2783 if (new_session_window->use_control_button.get_active()) {
2784 cchns = (uint32_t) channel_combo_get_channel_count (new_session_window->control_out_channel_combo);
2788 if (new_session_window->use_master_button.get_active()) {
2789 mchns = (uint32_t) channel_combo_get_channel_count (new_session_window->master_out_channel_combo);
2794 if (new_session_window->connect_to_physical_inputs_button.get_active()) {
2795 iconnect = Session::AutoConnectPhysical;
2797 iconnect = Session::AutoConnectOption (0);
2800 if (new_session_window->connect_to_master_button.get_active ()) {
2801 oconnect = Session::AutoConnectMaster;
2802 } else if (new_session_window->connect_to_physical_outputs_button.get_active ()) {
2803 oconnect = Session::AutoConnectPhysical;
2805 oconnect = Session::AutoConnectOption (0);
2808 uint32_t nphysin = (uint32_t) new_session_window->in_count_adjustment.get_value();
2809 uint32_t nphysout = (uint32_t) new_session_window->out_count_adjustment.get_value();
2811 build_session (session_path, session_name, cchns, mchns, iconnect, oconnect, nphysin, nphysout,
2812 engine->frame_rate() * 60 * 5);
2818 ARDOUR_UI::load_session (string path, string snap_name, string* mix_template)
2820 Session *new_session;
2822 session_loaded = false;
2823 x = unload_session ();
2831 /* if it already exists, we must have write access */
2833 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2834 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2835 You do not have write access to this session.\n\
2836 This prevents the session from being loaded."));
2841 new_session = new Session (*engine, path, snap_name, mix_template);
2846 error << compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2850 connect_to_session (new_session);
2852 //if (engine->running()) {
2853 //mixer->show_window();
2855 session_loaded = true;
2860 ARDOUR_UI::make_session_clean ()
2863 session->set_clean ();
2870 ARDOUR_UI::build_session (string path, string snap_name,
2871 uint32_t control_channels,
2872 uint32_t master_channels,
2873 Session::AutoConnectOption input_connect,
2874 Session::AutoConnectOption output_connect,
2877 jack_nframes_t initial_length)
2879 Session *new_session;
2882 session_loaded = false;
2883 x = unload_session ();
2890 _session_is_new = true;
2893 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2894 control_channels, master_channels, nphysin, nphysout, initial_length);
2899 error << compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2903 connect_to_session (new_session);
2905 //if (engine->running()) {
2906 //mixer->show_window();
2908 session_loaded = true;
2913 ARDOUR_UI::hide_dialog (ArdourDialog *dialog)
2922 editor->show_window ();
2926 if (session && mixer) {
2927 mixer->show_window ();
2931 about->get_window().raise ();
2936 ARDOUR_UI::show_splash ()
2939 about = new About(this);
2941 about->show_sub (true);
2942 about->get_window().raise ();
2945 about->get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
2947 about->get_window().raise ();
2952 ARDOUR_UI::hide_splash ()
2960 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, string msg)
2964 removed = rep.paths.size();
2967 ArdourMessage msg (editor, X_("cleanupresults"),
2969 No audio files were ready for cleanup\n\n\
2970 If this seems suprising, check for any existing\n\
2971 snapshots. These may still include regions that\n\
2972 require some unused files to continue to exist."));
2976 ArdourDialog results ("cleanup results");
2978 const gchar* list_titles[] = {
2983 Gtk::CList list (internationalize (list_titles));
2984 Gtk::ScrolledWindow list_scroller;
2986 Gtk::Button ok_button (_("OK"));
2988 const char* rowtext[1];
2990 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2992 vpacker.set_border_width (10);
2993 vpacker.set_spacing (10);
2995 if (rep.space < 1048576.0f) {
2997 txt.set_text (compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
2999 txt.set_text (compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
3003 txt.set_text (compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
3005 txt.set_text (compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
3009 vpacker.pack_start (txt, false, false);
3011 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
3012 rowtext[0] = (*i).c_str();
3013 list.rows().push_back (rowtext);
3016 list_scroller.add_with_viewport (list);
3017 list_scroller.set_size_request (-1, 250);
3019 vpacker.pack_start (list_scroller, true, true);
3020 vpacker.pack_start (ok_button, false, false);
3022 ok_button.signal_clicked().connect (Main::quit.slot ());
3023 results.Hiding.connect (Main::quit.slot ());
3025 results.add (vpacker);
3027 results.set_position (Gtk::WIN_POS_MOUSE);
3028 results.set_title (_("ardour: cleanup"));
3029 results.set_modal (true);
3034 ARDOUR_UI::cleanup ()
3037 /* shouldn't happen: menu item is insensitive */
3041 ArdourDialog checker (X_("cleanup confirm dialog"));
3042 Gtk::Label label (_("\
3043 Cleanup is a destructive operation.\n\
3044 ALL undo/redo information will be lost if you cleanup.\n\
3045 Unused audio files will be moved to a \"dead sounds\" location."));
3047 Gtk::Button ok_button (_("Proceed with cleanup"));
3048 Gtk::Button cancel_button (_("Cancel"));
3052 bbox.set_border_width (6);
3053 bbox.set_spacing (12);
3054 bbox.pack_start (ok_button, true, false);
3055 bbox.pack_start (cancel_button, true, false);
3057 vbox.set_border_width (6);
3058 vbox.set_spacing (12);
3059 vbox.pack_start (label, false, false);
3060 vbox.pack_start (bbox, false, false);
3063 checker.set_name (_("CleanupDialog"));
3064 checker.set_title (_("ardour cleanup"));
3065 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
3066 checker.set_position (Gtk::WIN_POS_MOUSE);
3068 checker.get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
3070 ok_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 1));
3071 cancel_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 0));
3075 if (checker.run_status() != 1) {
3079 Session::cleanup_report rep;
3081 editor->prepare_for_cleanup ();
3083 if (session->cleanup_sources (rep)) {
3087 display_cleanup_results (rep,
3090 The following %1 %2 were not in use.\n\
3091 The next time you flush the wastebasket\n\
3092 it will release an additional %3 %4bytes\n\
3098 ARDOUR_UI::flush_trash ()
3101 /* shouldn't happen: menu item is insensitive */
3105 Session::cleanup_report rep;
3107 if (session->cleanup_trash_sources (rep)) {
3111 display_cleanup_results (rep,
3113 _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
3117 ARDOUR_UI::add_route ()
3125 if (add_route_dialog == 0) {
3126 add_route_dialog = new AddRouteDialog;
3127 editor->ensure_float (*add_route_dialog);
3130 if (add_route_dialog->is_visible()) {
3131 /* we're already doing this */
3135 add_route_dialog->run ();
3137 if (add_route_dialog->run_status()) {
3141 if ((count = add_route_dialog->count()) <= 0) {
3145 uint32_t input_chan = add_route_dialog->channels ();
3146 uint32_t output_chan;
3147 string name_template = add_route_dialog->name_template ();
3148 bool track = add_route_dialog->track ();
3150 Session::AutoConnectOption oac = session->get_output_auto_connect();
3152 if (oac & Session::AutoConnectMaster) {
3153 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
3155 output_chan = input_chan;
3158 /* XXX do something with name template */
3162 session_add_audio_track (input_chan, output_chan);
3164 session_add_audio_bus (input_chan, output_chan);
3168 while (Main::events_pending()) {
3175 ARDOUR_UI::mixer_settings () const
3180 node = session->instant_xml(X_("Mixer"), session->path());
3182 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
3186 node = new XMLNode (X_("Mixer"));
3193 ARDOUR_UI::editor_settings () const
3198 node = session->instant_xml(X_("Editor"), session->path());
3200 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
3204 node = new XMLNode (X_("Editor"));
3210 ARDOUR_UI::keyboard_settings () const
3214 node = Config->extra_xml(X_("Keyboard"));
3217 node = new XMLNode (X_("Keyboard"));
3223 ARDOUR_UI::halt_on_xrun_message ()
3225 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
3227 ArdourMessage msg (editor, X_("haltonxrun"),
3228 _("Recording was stopped because your system could not keep up."));
3232 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
3234 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
3236 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
3240 delete deletion_list;
3244 ARDOUR_UI::disk_overrun_handler ()
3246 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3248 if (!have_disk_overrun_displayed) {
3249 have_disk_overrun_displayed = true;
3250 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
3251 The disk system on your computer\n\
3252 was not able to keep up with Ardour.\n\
3254 Specifically, it failed to write data to disk\n\
3255 quickly enough to keep up with recording.\n"));
3256 have_disk_overrun_displayed = false;
3261 ARDOUR_UI::disk_underrun_handler ()
3263 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3265 if (!have_disk_underrun_displayed) {
3266 have_disk_underrun_displayed = true;
3267 ArdourMessage msg (editor, X_("diskrate2 dialog"),
3268 (_("The disk system on your computer\n\
3269 was not able to keep up with Ardour.\n\
3271 Specifically, it failed to read data from disk\n\
3272 quickly enough to keep up with playback.\n")));
3273 have_disk_underrun_displayed = false;
3278 ARDOUR_UI::disk_underrun_message_gone ()
3280 have_disk_underrun_displayed = false;
3284 ARDOUR_UI::disk_overrun_message_gone ()
3286 have_disk_underrun_displayed = false;
3290 ARDOUR_UI::pending_state_dialog ()
3292 ArdourDialog dialog ("pending state dialog");
3293 Button use_button (_("Recover from crash"));
3294 Button cancel_button (_("Ignore crash data"));
3296 This session appears to have been in\n\
3297 middle of recording when ardour or\n\
3298 the computer was shutdown.\n\
3300 Ardour can recover any captured audio for\n\
3301 you, or it can ignore it. Please decide\n\
3302 what you would like to do.\n"));
3306 vpacker.set_border_width (12);
3307 vpacker.set_spacing (7);
3308 vpacker.pack_start (message);
3309 vpacker.pack_start (hpacker);
3311 hpacker.set_spacing (7);
3312 hpacker.pack_start (use_button);
3313 hpacker.pack_start (cancel_button);
3315 use_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 0));
3316 cancel_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 1));
3318 dialog.add (vpacker);
3319 dialog.set_position (GTK_WIN_POS_CENTER);
3322 dialog.get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
3326 if (dialog.run_status () == 0) {
3335 ARDOUR_UI::disconnect_from_jack ()
3338 if( engine->disconnect_from_jack ()) {
3339 ArdourMessage msg (editor, X_("nojack dialog"),
3340 _("Could not disconnect from JACK"));
3343 update_sample_rate (0);
3348 ARDOUR_UI::reconnect_to_jack ()
3351 if (engine->reconnect_to_jack ()) {
3352 ArdourMessage msg (editor, X_("nojack dialog"),
3353 _("Could not reconnect to JACK"));
3356 update_sample_rate (0);
3361 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
3363 engine->request_buffer_size (nframes);
3364 update_sample_rate (0);
3368 ARDOUR_UI::cmdline_new_session (string path)
3370 if (path[0] != '/') {
3371 char buf[PATH_MAX+1];
3374 getcwd (buf, sizeof (buf));
3381 new_session (false, path);
3383 _will_create_new_session_automatically = false; /* done it */
3384 return FALSE; /* don't call it again */