mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-04 20:55:48 +01:00
merge with master, fixing conflicts in 3 wscript files
This commit is contained in:
commit
2a6a16f980
64 changed files with 4195 additions and 3528 deletions
|
|
@ -113,6 +113,7 @@ typedef uint64_t microseconds_t;
|
|||
#include "rc_option_editor.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "route_params_ui.h"
|
||||
#include "session_dialog.h"
|
||||
#include "session_metadata_dialog.h"
|
||||
#include "session_option_editor.h"
|
||||
#include "shuttle_control.h"
|
||||
|
|
@ -160,7 +161,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
|||
|
||||
/* start of private members */
|
||||
|
||||
, _startup (0)
|
||||
, nsm (0)
|
||||
, _was_dirty (false)
|
||||
, _mixer_on_top (false)
|
||||
|
|
@ -195,6 +195,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
|||
, about (X_("about"), _("About"))
|
||||
, location_ui (X_("locations"), _("Locations"))
|
||||
, route_params (X_("inspector"), _("Tracks and Busses"))
|
||||
, audio_midi_setup (X_("audio-midi-setup"), _("Audio/MIDI Setup"))
|
||||
, session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
|
||||
, add_video_dialog (X_("add-video"), _("Add Tracks/Busses"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
|
||||
, bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
|
||||
|
|
@ -206,7 +207,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
|||
|
||||
, _status_bar_visibility (X_("status-bar"))
|
||||
, _feedback_exists (false)
|
||||
, _audio_midi_setup (0)
|
||||
{
|
||||
Gtkmm2ext::init(localedir);
|
||||
|
||||
|
|
@ -217,7 +217,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
|||
}
|
||||
|
||||
ui_config = new UIConfiguration();
|
||||
_audio_midi_setup = new EngineControl;
|
||||
|
||||
editor = 0;
|
||||
mixer = 0;
|
||||
|
|
@ -352,6 +351,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
|||
WM::Manager::instance().register_window (&add_route_dialog);
|
||||
WM::Manager::instance().register_window (&add_video_dialog);
|
||||
WM::Manager::instance().register_window (&route_params);
|
||||
WM::Manager::instance().register_window (&audio_midi_setup);
|
||||
WM::Manager::instance().register_window (&bundle_manager);
|
||||
WM::Manager::instance().register_window (&location_ui);
|
||||
WM::Manager::instance().register_window (&big_clock_window);
|
||||
|
|
@ -365,9 +365,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
|||
|
||||
(void) theme_manager.get (true);
|
||||
|
||||
starting.connect (sigc::mem_fun(*this, &ARDOUR_UI::startup));
|
||||
stopping.connect (sigc::mem_fun(*this, &ARDOUR_UI::shutdown));
|
||||
|
||||
_process_thread = new ProcessThread ();
|
||||
_process_thread->init ();
|
||||
|
||||
|
|
@ -406,58 +403,12 @@ ARDOUR_UI::engine_running ()
|
|||
if (first_time_engine_run) {
|
||||
post_engine();
|
||||
first_time_engine_run = false;
|
||||
}
|
||||
}
|
||||
|
||||
ActionManager::set_sensitive (ActionManager::engine_sensitive_actions, true);
|
||||
ActionManager::set_sensitive (ActionManager::engine_opposite_sensitive_actions, false);
|
||||
|
||||
Glib::RefPtr<Action> action;
|
||||
const char* action_name = 0;
|
||||
|
||||
switch (AudioEngine::instance()->samples_per_cycle()) {
|
||||
case 32:
|
||||
action_name = X_("JACKLatency32");
|
||||
break;
|
||||
case 64:
|
||||
action_name = X_("JACKLatency64");
|
||||
break;
|
||||
case 128:
|
||||
action_name = X_("JACKLatency128");
|
||||
break;
|
||||
case 512:
|
||||
action_name = X_("JACKLatency512");
|
||||
break;
|
||||
case 1024:
|
||||
action_name = X_("JACKLatency1024");
|
||||
break;
|
||||
case 2048:
|
||||
action_name = X_("JACKLatency2048");
|
||||
break;
|
||||
case 4096:
|
||||
action_name = X_("JACKLatency4096");
|
||||
break;
|
||||
case 8192:
|
||||
action_name = X_("JACKLatency8192");
|
||||
break;
|
||||
default:
|
||||
/* XXX can we do anything useful ? */
|
||||
break;
|
||||
}
|
||||
|
||||
if (action_name) {
|
||||
|
||||
action = ActionManager::get_action (X_("JACK"), action_name);
|
||||
|
||||
if (action) {
|
||||
Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
|
||||
ract->set_active ();
|
||||
}
|
||||
|
||||
update_disk_space ();
|
||||
update_cpu_load ();
|
||||
update_sample_rate (AudioEngine::instance()->sample_rate());
|
||||
update_timecode_format ();
|
||||
}
|
||||
update_disk_space ();
|
||||
update_cpu_load ();
|
||||
update_sample_rate (AudioEngine::instance()->sample_rate());
|
||||
update_timecode_format ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -485,13 +436,13 @@ ARDOUR_UI::engine_halted (const char* reason, bool free_reason)
|
|||
*/
|
||||
|
||||
if (strlen (reason)) {
|
||||
msgstr = string_compose (_("The audio backend (JACK) was shutdown because:\n\n%1"), reason);
|
||||
msgstr = string_compose (_("The audio backend was shutdown because:\n\n%1"), reason);
|
||||
} else {
|
||||
msgstr = string_compose (_("\
|
||||
JACK has either been shutdown or it\n\
|
||||
`The audio backend has either been shutdown or it\n\
|
||||
disconnected %1 because %1\n\
|
||||
was not fast enough. Try to restart\n\
|
||||
JACK, reconnect and save the session."), PROGRAM_NAME);
|
||||
the audio backend and save the session."), PROGRAM_NAME);
|
||||
}
|
||||
|
||||
MessageDialog msg (*editor, msgstr);
|
||||
|
|
@ -586,6 +537,10 @@ ARDOUR_UI::post_engine ()
|
|||
|
||||
ARDOUR_UI::~ARDOUR_UI ()
|
||||
{
|
||||
if (ui_config->dirty()) {
|
||||
ui_config->save_state();
|
||||
}
|
||||
|
||||
delete keyboard;
|
||||
delete editor;
|
||||
delete mixer;
|
||||
|
|
@ -762,8 +717,8 @@ ARDOUR_UI::check_announcements ()
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::startup ()
|
||||
int
|
||||
ARDOUR_UI::starting ()
|
||||
{
|
||||
Application* app = Application::instance ();
|
||||
char *nsm_url;
|
||||
|
|
@ -825,10 +780,33 @@ ARDOUR_UI::startup ()
|
|||
delete nsm;
|
||||
nsm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) {
|
||||
exit (1);
|
||||
} else {
|
||||
|
||||
if (ArdourStartup::required()) {
|
||||
ArdourStartup s;
|
||||
s.present ();
|
||||
main().run();
|
||||
s.hide ();
|
||||
switch (s.response ()) {
|
||||
case Gtk::RESPONSE_REJECT:
|
||||
return -1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to create this early because it may need to set the
|
||||
* audio backend end up.
|
||||
*/
|
||||
|
||||
audio_midi_setup.get (true);
|
||||
|
||||
/* go get a session */
|
||||
|
||||
if (get_session_parameters (false, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
use_config ();
|
||||
|
|
@ -843,6 +821,7 @@ ARDOUR_UI::startup ()
|
|||
_status_bar_visibility.update ();
|
||||
|
||||
BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1156,7 +1135,6 @@ ARDOUR_UI::update_sample_rate (framecnt_t)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
sample_rate_label.set_markup (buf);
|
||||
}
|
||||
|
||||
|
|
@ -1860,7 +1838,7 @@ ARDOUR_UI::transport_roll ()
|
|||
#if 0
|
||||
if (_session->config.get_external_sync()) {
|
||||
switch (Config->get_sync_source()) {
|
||||
case JACK:
|
||||
case Engine:
|
||||
break;
|
||||
default:
|
||||
/* transport controlled by the master */
|
||||
|
|
@ -1910,7 +1888,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
|
|||
|
||||
if (_session->config.get_external_sync()) {
|
||||
switch (Config->get_sync_source()) {
|
||||
case JACK:
|
||||
case Engine:
|
||||
break;
|
||||
default:
|
||||
/* transport controlled by the master */
|
||||
|
|
@ -2482,7 +2460,7 @@ ARDOUR_UI::ask_about_loading_existing_session (const std::string& session_path)
|
|||
}
|
||||
|
||||
int
|
||||
ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::string& session_name)
|
||||
ARDOUR_UI::build_session_from_dialog (SessionDialog& sd, const std::string& session_path, const std::string& session_name)
|
||||
{
|
||||
BusProfile bus_profile;
|
||||
|
||||
|
|
@ -2498,13 +2476,13 @@ ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::s
|
|||
|
||||
/* get settings from advanced section of NSD */
|
||||
|
||||
if (_startup->create_master_bus()) {
|
||||
bus_profile.master_out_channels = (uint32_t) _startup->master_channel_count();
|
||||
if (sd.create_master_bus()) {
|
||||
bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
|
||||
} else {
|
||||
bus_profile.master_out_channels = 0;
|
||||
}
|
||||
|
||||
if (_startup->connect_inputs()) {
|
||||
if (sd.connect_inputs()) {
|
||||
bus_profile.input_ac = AutoConnectPhysical;
|
||||
} else {
|
||||
bus_profile.input_ac = AutoConnectOption (0);
|
||||
|
|
@ -2512,16 +2490,16 @@ ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::s
|
|||
|
||||
bus_profile.output_ac = AutoConnectOption (0);
|
||||
|
||||
if (_startup->connect_outputs ()) {
|
||||
if (_startup->connect_outs_to_master()) {
|
||||
if (sd.connect_outputs ()) {
|
||||
if (sd.connect_outs_to_master()) {
|
||||
bus_profile.output_ac = AutoConnectMaster;
|
||||
} else if (_startup->connect_outs_to_physical()) {
|
||||
} else if (sd.connect_outs_to_physical()) {
|
||||
bus_profile.output_ac = AutoConnectPhysical;
|
||||
}
|
||||
}
|
||||
|
||||
bus_profile.requested_physical_in = (uint32_t) _startup->input_limit_count();
|
||||
bus_profile.requested_physical_out = (uint32_t) _startup->output_limit_count();
|
||||
bus_profile.requested_physical_in = (uint32_t) sd.input_limit_count();
|
||||
bus_profile.requested_physical_out = (uint32_t) sd.output_limit_count();
|
||||
}
|
||||
|
||||
if (build_session (session_path, session_name, bus_profile)) {
|
||||
|
|
@ -2557,6 +2535,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
string template_name;
|
||||
int ret = -1;
|
||||
bool likely_new = false;
|
||||
bool cancel_not_quit;
|
||||
|
||||
/* deal with any existing DIRTY session now, rather than later. don't
|
||||
* treat a non-dirty session this way, so that it stays visible
|
||||
|
|
@ -2567,6 +2546,11 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
ARDOUR_UI::instance()->video_timeline->sync_session_state();
|
||||
}
|
||||
|
||||
/* if there is already a session, relabel the button
|
||||
on the SessionDialog so that we don't Quit directly
|
||||
*/
|
||||
cancel_not_quit = (_session != 0);
|
||||
|
||||
if (_session && _session->dirty()) {
|
||||
if (unload_session (false)) {
|
||||
/* unload cancelled by user */
|
||||
|
|
@ -2580,6 +2564,20 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
template_name = load_template;
|
||||
}
|
||||
|
||||
session_name = basename_nosuffix (ARDOUR_COMMAND_LINE::session_name);
|
||||
session_path = ARDOUR_COMMAND_LINE::session_name;
|
||||
|
||||
if (!session_path.empty()) {
|
||||
if (Glib::file_test (session_path.c_str(), Glib::FILE_TEST_EXISTS)) {
|
||||
if (Glib::file_test (session_path.c_str(), Glib::FILE_TEST_IS_REGULAR)) {
|
||||
/* session/snapshot file, change path to be dir */
|
||||
session_path = Glib::path_get_dirname (session_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SessionDialog session_dialog (should_be_new, session_name, session_path, load_template, cancel_not_quit);
|
||||
|
||||
while (ret != 0) {
|
||||
|
||||
if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
|
||||
|
|
@ -2602,34 +2600,35 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
} else {
|
||||
session_path = "";
|
||||
session_name = "";
|
||||
session_dialog.clear_given ();
|
||||
}
|
||||
|
||||
if (should_be_new || session_name.empty()) {
|
||||
/* need the dialog to get info from user */
|
||||
|
||||
delete _startup;
|
||||
_startup = new ArdourStartup (should_be_new, session_name, session_path, load_template);
|
||||
|
||||
if (!_startup->ready_without_display()) {
|
||||
_startup->present ();
|
||||
main().run();
|
||||
_startup->hide ();
|
||||
}
|
||||
|
||||
switch (_startup->response()) {
|
||||
case RESPONSE_OK:
|
||||
break;
|
||||
default:
|
||||
if (quit_on_cancel) {
|
||||
exit (1);
|
||||
} else {
|
||||
return ret;
|
||||
cerr << "run dialog\n";
|
||||
|
||||
switch (session_dialog.run()) {
|
||||
case RESPONSE_ACCEPT:
|
||||
break;
|
||||
default:
|
||||
if (quit_on_cancel) {
|
||||
exit (1);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
session_dialog.hide ();
|
||||
}
|
||||
|
||||
/* if we run the startup dialog again, offer more than just "new session" */
|
||||
|
||||
should_be_new = false;
|
||||
|
||||
session_name = _startup->session_name (likely_new);
|
||||
|
||||
session_name = session_dialog.session_name (likely_new);
|
||||
session_path = session_dialog.session_folder ();
|
||||
|
||||
if (nsm) {
|
||||
likely_new = true;
|
||||
}
|
||||
|
|
@ -2646,8 +2645,8 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
continue;
|
||||
}
|
||||
|
||||
if (_startup->use_session_template()) {
|
||||
template_name = _startup->session_template_name();
|
||||
if (session_dialog.use_session_template()) {
|
||||
template_name = session_dialog.session_template_name();
|
||||
_session_is_new = true;
|
||||
}
|
||||
|
||||
|
|
@ -2664,12 +2663,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
|
||||
} else {
|
||||
|
||||
session_path = _startup->session_folder();
|
||||
session_path = session_dialog.session_folder();
|
||||
|
||||
char illegal = Session::session_name_is_legal (session_name);
|
||||
|
||||
if (illegal) {
|
||||
MessageDialog msg (*_startup,
|
||||
MessageDialog msg (session_dialog,
|
||||
string_compose (_("To ensure compatibility with various systems\n"
|
||||
"session names may not contain a '%1' character"),
|
||||
illegal));
|
||||
|
|
@ -2681,6 +2680,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
|
||||
if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
|
||||
|
||||
|
||||
if (likely_new && !nsm) {
|
||||
|
||||
std::string existing = Glib::build_filename (session_path, session_name);
|
||||
|
|
@ -2696,12 +2696,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
} else {
|
||||
|
||||
if (!likely_new) {
|
||||
if (_startup) {
|
||||
pop_back_splash (*_startup);
|
||||
} else {
|
||||
hide_splash ();
|
||||
}
|
||||
|
||||
pop_back_splash (session_dialog);
|
||||
MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
|
||||
msg.run ();
|
||||
ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
|
||||
|
|
@ -2709,10 +2704,11 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
}
|
||||
|
||||
char illegal = Session::session_name_is_legal(session_name);
|
||||
|
||||
if (illegal) {
|
||||
pop_back_splash (*_startup);
|
||||
MessageDialog msg (*_startup, string_compose(_("To ensure compatibility with various systems\n"
|
||||
"session names may not contain a '%1' character"), illegal));
|
||||
pop_back_splash (session_dialog);
|
||||
MessageDialog msg (session_dialog, string_compose(_("To ensure compatibility with various systems\n"
|
||||
"session names may not contain a '%1' character"), illegal));
|
||||
msg.run ();
|
||||
ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
|
||||
continue;
|
||||
|
|
@ -2723,7 +2719,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
|
||||
if (likely_new && template_name.empty()) {
|
||||
|
||||
ret = build_session_from_nsd (session_path, session_name);
|
||||
ret = build_session_from_dialog (session_dialog, session_path, session_name);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -2738,6 +2734,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
|||
_session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* clear this to avoid endless attempts to load the
|
||||
same session.
|
||||
*/
|
||||
|
||||
ARDOUR_COMMAND_LINE::session_name = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2830,22 +2832,12 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
|
|||
Gtk::MESSAGE_INFO,
|
||||
BUTTONS_OK);
|
||||
|
||||
msg.set_keep_above (true);
|
||||
msg.set_title (_("Loading Error"));
|
||||
msg.set_secondary_text (_("Click the Refresh button to try again."));
|
||||
msg.add_button (Stock::REFRESH, 1);
|
||||
msg.set_position (Gtk::WIN_POS_CENTER);
|
||||
pop_back_splash (msg);
|
||||
msg.present ();
|
||||
|
||||
int response = msg.run ();
|
||||
|
||||
switch (response) {
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
exit (1);
|
||||
}
|
||||
|
||||
(void) msg.run ();
|
||||
msg.hide ();
|
||||
|
||||
goto out;
|
||||
|
|
@ -3804,6 +3796,7 @@ ARDOUR_UI::disconnect_from_engine ()
|
|||
/* drop connection to AudioEngine::Halted so that we don't act
|
||||
* as if the engine unexpectedly shut down
|
||||
*/
|
||||
|
||||
halt_connection.disconnect ();
|
||||
|
||||
if (AudioEngine::instance()->stop ()) {
|
||||
|
|
@ -4136,41 +4129,12 @@ ARDOUR_UI::reset_route_peak_display (Route* route)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_audio_midi_setup ()
|
||||
{
|
||||
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-audio-midi-setup"));
|
||||
if (!act) {
|
||||
return;
|
||||
}
|
||||
|
||||
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
|
||||
if (tact->get_active()) {
|
||||
launch_audio_midi_setup ();
|
||||
} else {
|
||||
_audio_midi_setup->hide ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::launch_audio_midi_setup ()
|
||||
{
|
||||
if (!_audio_midi_setup) {
|
||||
_audio_midi_setup = new EngineControl ();
|
||||
}
|
||||
|
||||
_audio_midi_setup->present ();
|
||||
}
|
||||
|
||||
int
|
||||
ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
|
||||
{
|
||||
launch_audio_midi_setup ();
|
||||
audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
|
||||
|
||||
_audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
|
||||
|
||||
switch (_audio_midi_setup->run()) {
|
||||
switch (audio_midi_setup->run()) {
|
||||
case Gtk::RESPONSE_OK:
|
||||
return 0;
|
||||
case Gtk::RESPONSE_APPLY:
|
||||
|
|
@ -4179,3 +4143,5 @@ ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ class AddRouteDialog;
|
|||
class AddVideoDialog;
|
||||
class VideoTimeLine;
|
||||
class SystemExec;
|
||||
class ArdourStartup;
|
||||
class ArdourKeyboard;
|
||||
class AudioClock;
|
||||
class BigClockWindow;
|
||||
|
|
@ -98,6 +97,7 @@ class Mixer_UI;
|
|||
class PublicEditor;
|
||||
class RCOptionEditor;
|
||||
class RouteParams_UI;
|
||||
class SessionDialog;
|
||||
class SessionOptionEditor;
|
||||
class ShuttleControl;
|
||||
class Splash;
|
||||
|
|
@ -153,7 +153,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
bool get_smart_mode () const;
|
||||
|
||||
int get_session_parameters (bool quit_on_cancel, bool should_be_new = false, std::string load_template = "");
|
||||
int build_session_from_nsd (const std::string& session_name, const std::string& session_path);
|
||||
int build_session_from_dialog (SessionDialog&, const std::string& session_name, const std::string& session_path);
|
||||
bool ask_about_loading_existing_session (const std::string& session_path);
|
||||
|
||||
/// @return true if session was successfully unloaded.
|
||||
|
|
@ -312,11 +312,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
void toggle_session_options_window ();
|
||||
|
||||
private:
|
||||
ArdourStartup* _startup;
|
||||
Gtk::Tooltips _tooltips;
|
||||
Gtk::Tooltips _tooltips;
|
||||
NSM_Client *nsm;
|
||||
bool _was_dirty;
|
||||
bool _mixer_on_top;
|
||||
bool _was_dirty;
|
||||
bool _mixer_on_top;
|
||||
bool first_time_engine_run;
|
||||
|
||||
void goto_editor_window ();
|
||||
|
|
@ -331,8 +330,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
|
||||
static ARDOUR_UI *theArdourUI;
|
||||
|
||||
void startup ();
|
||||
void shutdown ();
|
||||
int starting ();
|
||||
|
||||
int ask_about_saving_session (const std::vector<std::string>& actions);
|
||||
|
||||
|
|
@ -603,6 +601,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
WM::Proxy<About> about;
|
||||
WM::Proxy<LocationUIWindow> location_ui;
|
||||
WM::Proxy<RouteParams_UI> route_params;
|
||||
WM::Proxy<EngineControl> audio_midi_setup;
|
||||
|
||||
/* Windows/Dialogs that require a creator method */
|
||||
|
||||
|
|
@ -670,8 +669,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
int pending_state_dialog ();
|
||||
int sr_mismatch_dialog (ARDOUR::framecnt_t, ARDOUR::framecnt_t);
|
||||
|
||||
void set_engine_buffer_size (ARDOUR::pframes_t);
|
||||
|
||||
Gtk::MenuItem* jack_disconnect_item;
|
||||
Gtk::MenuItem* jack_reconnect_item;
|
||||
Gtk::Menu* jack_bufsize_menu;
|
||||
|
|
@ -749,8 +746,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
std::string _announce_string;
|
||||
void check_announcements ();
|
||||
|
||||
EngineControl* _audio_midi_setup;
|
||||
void launch_audio_midi_setup ();
|
||||
int do_audio_midi_setup (uint32_t);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -50,14 +50,6 @@ namespace ARDOUR {
|
|||
|
||||
using namespace ARDOUR;
|
||||
|
||||
void
|
||||
ARDOUR_UI::shutdown ()
|
||||
{
|
||||
if (ui_config->dirty()) {
|
||||
ui_config->save_state();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::we_have_dependents ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -197,7 +197,6 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::register_toggle_action (common_actions, X_("toggle-mixer"), S_("Window|Mixer"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_mixer_window));
|
||||
ActionManager::register_action (common_actions, X_("toggle-editor-mixer"), _("Toggle Editor+Mixer"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_editor_mixer));
|
||||
ActionManager::register_toggle_action (common_actions, X_("toggle-meterbridge"), S_("Window|Meterbridge"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_meterbridge));
|
||||
ActionManager::register_toggle_action (common_actions, X_("toggle-audio-midi-setup"), S_("Window|Audio/MIDI Setup"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_audio_midi_setup));
|
||||
|
||||
act = ActionManager::register_action (common_actions, X_("NewMIDITracer"), _("MIDI Tracer"), sigc::mem_fun(*this, &ARDOUR_UI::new_midi_tracer_window));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
|
@ -396,60 +395,6 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::add_action_group (midi_actions);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::set_engine_buffer_size (pframes_t nframes)
|
||||
{
|
||||
Glib::RefPtr<Action> action;
|
||||
const char* action_name = 0;
|
||||
|
||||
switch (nframes) {
|
||||
case 32:
|
||||
action_name = X_("EngineLatency32");
|
||||
break;
|
||||
case 64:
|
||||
action_name = X_("EngineLatency64");
|
||||
break;
|
||||
case 128:
|
||||
action_name = X_("EngineLatency128");
|
||||
break;
|
||||
case 256:
|
||||
action_name = X_("EngineLatency256");
|
||||
break;
|
||||
case 512:
|
||||
action_name = X_("EngineLatency512");
|
||||
break;
|
||||
case 1024:
|
||||
action_name = X_("EngineLatency1024");
|
||||
break;
|
||||
case 2048:
|
||||
action_name = X_("EngineLatency2048");
|
||||
break;
|
||||
case 4096:
|
||||
action_name = X_("EngineLatency4096");
|
||||
break;
|
||||
case 8192:
|
||||
action_name = X_("EngineLatency8192");
|
||||
break;
|
||||
default:
|
||||
/* XXX can we do anything useful ? */
|
||||
break;
|
||||
}
|
||||
|
||||
if (action_name) {
|
||||
|
||||
action = ActionManager::get_action (X_("JACK"), action_name);
|
||||
|
||||
if (action) {
|
||||
Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
|
||||
|
||||
if (ract && ract->get_active()) {
|
||||
AudioEngine::instance()->request_buffer_size (nframes);
|
||||
update_sample_rate (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::build_menu_bar ()
|
||||
{
|
||||
|
|
@ -528,7 +473,7 @@ ARDOUR_UI::build_menu_bar ()
|
|||
_status_bar_visibility.add (&disk_space_label, X_("Disk"), _("Disk Space"), disk_space);
|
||||
_status_bar_visibility.add (&cpu_load_label, X_("DSP"), _("DSP"), true);
|
||||
_status_bar_visibility.add (&buffer_load_label, X_("Buffers"), _("Buffers"), true);
|
||||
_status_bar_visibility.add (&sample_rate_label, X_("JACK"), _("JACK Sampling Rate and Latency"), true);
|
||||
_status_bar_visibility.add (&sample_rate_label, X_("Audio"), _("Audio"), true);
|
||||
_status_bar_visibility.add (&timecode_format_label, X_("TCFormat"), _("Timecode Format"), true);
|
||||
_status_bar_visibility.add (&format_label, X_("Format"), _("File Format"), true);
|
||||
|
||||
|
|
@ -614,7 +559,7 @@ ARDOUR_UI::save_ardour_state ()
|
|||
window_node->add_child_nocopy (*tearoff_node);
|
||||
|
||||
Config->add_extra_xml (*window_node);
|
||||
Config->add_extra_xml (_audio_midi_setup->get_state());
|
||||
Config->add_extra_xml (audio_midi_setup->get_state());
|
||||
|
||||
Config->save_state();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@
|
|||
#include "ardour/rc_configuration.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#ifdef HAVE_LIBLO
|
||||
#include "ardour/osc.h"
|
||||
#endif
|
||||
|
||||
#include "audio_clock.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "actions.h"
|
||||
|
|
@ -60,7 +56,7 @@ ARDOUR_UI::toggle_external_sync()
|
|||
{
|
||||
if (_session) {
|
||||
if (_session->config.get_video_pullup() != 0.0f) {
|
||||
if (Config->get_sync_source() == JACK) {
|
||||
if (Config->get_sync_source() == Engine) {
|
||||
MessageDialog msg (
|
||||
_("It is not possible to use JACK as the the sync source\n\
|
||||
when the pull up/down setting is non-zero."));
|
||||
|
|
@ -342,16 +338,6 @@ ARDOUR_UI::parameter_changed (std::string p)
|
|||
|
||||
ActionManager::map_some_state ("options", "SendMMC", &RCConfiguration::get_send_mmc);
|
||||
|
||||
} else if (p == "use-osc") {
|
||||
|
||||
#ifdef HAVE_LIBLO
|
||||
if (Config->get_use_osc()) {
|
||||
osc->start ();
|
||||
} else {
|
||||
osc->stop ();
|
||||
}
|
||||
#endif
|
||||
|
||||
} else if (p == "keep-tearoffs") {
|
||||
ActionManager::map_some_state ("Common", "KeepTearoffs", &RCConfiguration::get_keep_tearoffs);
|
||||
} else if (p == "mmc-control") {
|
||||
|
|
@ -465,7 +451,7 @@ ARDOUR_UI::synchronize_sync_source_and_video_pullup ()
|
|||
act->set_sensitive (true);
|
||||
} else {
|
||||
/* can't sync to JACK if video pullup != 0.0 */
|
||||
if (Config->get_sync_source() == JACK) {
|
||||
if (Config->get_sync_source() == Engine) {
|
||||
act->set_sensitive (false);
|
||||
} else {
|
||||
act->set_sensitive (true);
|
||||
|
|
|
|||
|
|
@ -996,7 +996,7 @@ AudioClock::set_slave_info ()
|
|||
Slave* slave = _session->slave();
|
||||
|
||||
switch (sync_src) {
|
||||
case JACK:
|
||||
case Engine:
|
||||
_left_layout->set_markup (string_compose ("<span size=\"%1\">" TXTSPAN "%2</span></span>",
|
||||
INFO_FONT_SIZE, sync_source_to_string(sync_src, true)));
|
||||
_right_layout->set_text ("");
|
||||
|
|
|
|||
|
|
@ -2108,7 +2108,7 @@ Editor::transition_to_rolling (bool fwd)
|
|||
|
||||
if (_session->config.get_external_sync()) {
|
||||
switch (Config->get_sync_source()) {
|
||||
case JACK:
|
||||
case Engine:
|
||||
break;
|
||||
default:
|
||||
/* transport controlled by the master */
|
||||
|
|
|
|||
|
|
@ -1115,7 +1115,7 @@ EditorRegions::sorter (TreeModel::iterator a, TreeModel::iterator b)
|
|||
|
||||
switch (_sort_type) {
|
||||
case ByName:
|
||||
cmp = strcasecmp (region1->name().c_str(), region2->name().c_str());
|
||||
cmp = g_strcasecmp (region1->name().c_str(), region2->name().c_str());
|
||||
break;
|
||||
|
||||
case ByLength:
|
||||
|
|
@ -1140,7 +1140,7 @@ EditorRegions::sorter (TreeModel::iterator a, TreeModel::iterator b)
|
|||
break;
|
||||
|
||||
case BySourceFileName:
|
||||
cmp = strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
|
||||
cmp = g_strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
|
||||
break;
|
||||
|
||||
case BySourceFileLength:
|
||||
|
|
@ -1153,9 +1153,9 @@ EditorRegions::sorter (TreeModel::iterator a, TreeModel::iterator b)
|
|||
|
||||
case BySourceFileFS:
|
||||
if (region1->source()->name() == region2->source()->name()) {
|
||||
cmp = strcasecmp (region1->name().c_str(), region2->name().c_str());
|
||||
cmp = g_strcasecmp (region1->name().c_str(), region2->name().c_str());
|
||||
} else {
|
||||
cmp = strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
|
||||
cmp = g_strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "ardour_ui.h"
|
||||
#include "engine_dialog.h"
|
||||
#include "gui_thread.h"
|
||||
#include "utils.h"
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -78,20 +79,147 @@ EngineControl::EngineControl ()
|
|||
, aj_button (_("Start MIDI ALSA/JACK bridge"))
|
||||
, ignore_changes (0)
|
||||
, _desired_sample_rate (0)
|
||||
, no_push (true)
|
||||
, started_at_least_once (false)
|
||||
{
|
||||
if (!ARDOUR::AudioEngine::instance()->setup_required()) {
|
||||
_have_control = false;
|
||||
} else {
|
||||
_have_control = true;
|
||||
}
|
||||
using namespace Notebook_Helpers;
|
||||
vector<string> strings;
|
||||
Label* label;
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
int row;
|
||||
|
||||
set_name (X_("AudioMIDISetup"));
|
||||
|
||||
build_notebook ();
|
||||
/* the backend combo is the one thing that is ALWAYS visible
|
||||
*/
|
||||
|
||||
vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
|
||||
for (vector<const ARDOUR::AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
|
||||
strings.push_back ((*b)->name);
|
||||
}
|
||||
|
||||
set_popdown_strings (backend_combo, strings);
|
||||
backend_combo.set_active_text (strings.front());
|
||||
backend_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::backend_changed));
|
||||
|
||||
/* setup basic packing characteristics for the table used on the main
|
||||
* tab of the notebook
|
||||
*/
|
||||
|
||||
basic_packer.set_spacings (6);
|
||||
basic_packer.set_border_width (12);
|
||||
basic_packer.set_homogeneous (true);
|
||||
|
||||
/* pack it in */
|
||||
|
||||
basic_hbox.pack_start (basic_packer, false, false);
|
||||
|
||||
/* latency tab */
|
||||
|
||||
/* latency measurement tab */
|
||||
|
||||
lm_title.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Latency Measurement Tool")));
|
||||
|
||||
row = 0;
|
||||
lm_table.set_row_spacings (12);
|
||||
|
||||
lm_table.attach (lm_title, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
Gtk::Label* preamble;
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("<span weight=\"bold\">Turn down the volume on your hardware to a very low level.</span>"));
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Select two channels below and connect them using a cable or (less ideally) a speaker and microphone."));
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
label = manage (new Label (_("Output channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
Gtk::Alignment* misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_output_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
label = manage (new Label (_("Input channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_input_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, FILL, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
xopt = AttachOptions(0);
|
||||
|
||||
lm_measure_button.add (lm_start_stop_label);
|
||||
|
||||
lm_measure_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::latency_button_toggled));
|
||||
lm_use_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::use_latency_button_clicked));
|
||||
lm_use_button.set_sensitive (false);
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Once the channels are connected, click the \"Measure latency\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_measure_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
lm_table.attach (lm_results, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("When satisfied with the results, click the \"Use results\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_use_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
lm_results.set_markup ("<i>No measurement results yet</i>");
|
||||
|
||||
lm_vbox.set_border_width (12);
|
||||
lm_vbox.pack_start (lm_table, false, false);
|
||||
|
||||
/* pack it all up */
|
||||
|
||||
notebook.pages().push_back (TabElem (basic_vbox, _("Audio")));
|
||||
notebook.pages().push_back (TabElem (midi_vbox, _("MIDI")));
|
||||
notebook.pages().push_back (TabElem (lm_vbox, _("Latency")));
|
||||
notebook.set_border_width (12);
|
||||
|
||||
notebook.set_tab_pos (POS_RIGHT);
|
||||
notebook.show_all ();
|
||||
|
||||
notebook.set_name ("SettingsNotebook");
|
||||
|
||||
/* packup the notebook */
|
||||
|
||||
get_vbox()->set_border_width (12);
|
||||
get_vbox()->pack_start (notebook);
|
||||
|
||||
/* need a special function to print "all available channels" when the
|
||||
* channel counts hit zero.
|
||||
*/
|
||||
|
||||
input_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &input_channels));
|
||||
output_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &output_channels));
|
||||
|
||||
control_app_button.signal_clicked().connect (mem_fun (*this, &EngineControl::control_app_button_clicked));
|
||||
manage_control_app_sensitivity ();
|
||||
|
||||
|
|
@ -103,12 +231,31 @@ EngineControl::EngineControl ()
|
|||
|
||||
XMLNode* audio_setup = ARDOUR::Config->extra_xml ("AudioMIDISetup");
|
||||
|
||||
/* push a change as if we altered the backend */
|
||||
ARDOUR::AudioEngine::instance()->Running.connect (running_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_running, this), gui_context());
|
||||
ARDOUR::AudioEngine::instance()->Stopped.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_stopped, this), gui_context());
|
||||
ARDOUR::AudioEngine::instance()->Halted.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_stopped, this), gui_context());
|
||||
|
||||
backend_changed ();
|
||||
|
||||
if (audio_setup) {
|
||||
set_state (*audio_setup);
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect to signals */
|
||||
|
||||
driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
|
||||
sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::sample_rate_changed));
|
||||
buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed));
|
||||
device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
|
||||
|
||||
input_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
input_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
|
||||
notebook.signal_switch_page().connect (sigc::mem_fun (*this, &EngineControl::on_switch_page));
|
||||
|
||||
no_push = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -139,36 +286,58 @@ EngineControl::on_response (int response_id)
|
|||
void
|
||||
EngineControl::build_notebook ()
|
||||
{
|
||||
Label* label;
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
|
||||
/* clear the table */
|
||||
|
||||
Gtkmm2ext::container_clear (basic_vbox);
|
||||
Gtkmm2ext::container_clear (basic_packer);
|
||||
|
||||
label = manage (left_aligned_label (_("Audio System:")));
|
||||
basic_packer.attach (*label, 0, 1, 0, 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (backend_combo, 1, 2, 0, 1, xopt, (AttachOptions) 0);
|
||||
|
||||
if (_have_control) {
|
||||
build_full_control_notebook ();
|
||||
} else {
|
||||
build_no_control_notebook ();
|
||||
}
|
||||
|
||||
basic_vbox.pack_start (basic_hbox, false, false);
|
||||
|
||||
if (_have_control) {
|
||||
Gtk::HBox* hpacker = manage (new HBox);
|
||||
hpacker->set_border_width (12);
|
||||
hpacker->pack_start (control_app_button, false, false);
|
||||
hpacker->show ();
|
||||
control_app_button.show();
|
||||
basic_vbox.pack_start (*hpacker);
|
||||
}
|
||||
|
||||
basic_vbox.show_all ();
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::build_full_control_notebook ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
using namespace Notebook_Helpers;
|
||||
Label* label;
|
||||
vector<string> strings;
|
||||
int row = 0;
|
||||
|
||||
vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
|
||||
for (vector<const ARDOUR::AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
|
||||
strings.push_back ((*b)->name);
|
||||
}
|
||||
|
||||
set_popdown_strings (backend_combo, strings);
|
||||
backend_combo.set_active_text (strings.front());
|
||||
|
||||
basic_packer.set_spacings (6);
|
||||
basic_packer.set_border_width (12);
|
||||
basic_packer.set_homogeneous (true);
|
||||
|
||||
row = 0;
|
||||
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
int row = 1; // row zero == backend combo
|
||||
|
||||
label = manage (left_aligned_label (_("Audio System:")));
|
||||
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (backend_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
/* start packing it up */
|
||||
|
||||
label = manage (left_aligned_label (_("Driver:")));
|
||||
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (driver_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
if (backend->requires_driver_selection()) {
|
||||
label = manage (left_aligned_label (_("Driver:")));
|
||||
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (driver_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
}
|
||||
|
||||
label = manage (left_aligned_label (_("Device:")));
|
||||
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
|
||||
|
|
@ -236,126 +405,46 @@ EngineControl::build_notebook ()
|
|||
basic_packer.attach (*label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
basic_hbox.pack_start (basic_packer, false, false);
|
||||
basic_vbox.pack_start (basic_hbox, false, false);
|
||||
}
|
||||
|
||||
Gtk::HBox* hpacker = manage (new HBox);
|
||||
hpacker->set_border_width (12);
|
||||
hpacker->pack_start (control_app_button, false, false);
|
||||
hpacker->show ();
|
||||
control_app_button.show();
|
||||
basic_vbox.pack_start (*hpacker);
|
||||
void
|
||||
EngineControl::build_no_control_notebook ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
/* latency measurement tab */
|
||||
|
||||
lm_title.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Latency Measurement Tool")));
|
||||
|
||||
row = 0;
|
||||
lm_table.set_row_spacings (12);
|
||||
using namespace Notebook_Helpers;
|
||||
Label* label;
|
||||
vector<string> strings;
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
int row = 1; // row zero == backend combo
|
||||
const string msg = string_compose (_("The %1 audio backend was configured and started externally.\nThis limits your control over it."), backend->name());
|
||||
|
||||
lm_table.attach (lm_title, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
label = manage (new Label);
|
||||
label->set_markup (string_compose ("<span weight=\"bold\" foreground=\"red\">%1</span>", msg));
|
||||
basic_packer.attach (*label, 0, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
Gtk::Label* preamble;
|
||||
if (backend->can_change_sample_rate_when_running()) {
|
||||
label = manage (left_aligned_label (_("Sample rate:")));
|
||||
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
}
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("<span weight=\"bold\">Turn down the volume on your hardware to a very low level.</span>"));
|
||||
if (backend->can_change_buffer_size_when_running()) {
|
||||
label = manage (left_aligned_label (_("Buffer size:")));
|
||||
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (buffer_size_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
buffer_size_duration_label.set_alignment (0.0); /* left-align */
|
||||
basic_packer.attach (buffer_size_duration_label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
}
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
connect_disconnect_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::connect_disconnect_click));
|
||||
|
||||
basic_packer.attach (connect_disconnect_button, 0, 2, row, row+1, FILL, AttachOptions (0));
|
||||
row++;
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Select two channels below and connect them using a cable or (less ideally) a speaker and microphone."));
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
label = manage (new Label (_("Output channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
Gtk::Alignment* misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_output_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
label = manage (new Label (_("Input channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_input_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, FILL, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
xopt = AttachOptions(0);
|
||||
|
||||
lm_measure_button.add (lm_start_stop_label);
|
||||
|
||||
lm_measure_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::latency_button_toggled));
|
||||
lm_use_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::use_latency_button_clicked));
|
||||
lm_use_button.set_sensitive (false);
|
||||
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Once the channels are connected, click the \"Measure latency\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_measure_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
lm_table.attach (lm_results, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("When satisfied with the results, click the \"Use results\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_use_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
lm_results.set_markup ("<i>No measurement results yet</i>");
|
||||
|
||||
lm_vbox.set_border_width (12);
|
||||
lm_vbox.pack_start (lm_table, false, false);
|
||||
|
||||
/* pack it all up */
|
||||
|
||||
notebook.pages().push_back (TabElem (basic_vbox, _("Audio")));
|
||||
notebook.pages().push_back (TabElem (midi_vbox, _("MIDI")));
|
||||
notebook.pages().push_back (TabElem (lm_vbox, _("Latency")));
|
||||
notebook.set_border_width (12);
|
||||
|
||||
notebook.set_tab_pos (POS_RIGHT);
|
||||
notebook.show_all ();
|
||||
|
||||
notebook.set_name ("SettingsNotebook");
|
||||
|
||||
/* Connect to signals */
|
||||
|
||||
backend_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::backend_changed));
|
||||
driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
|
||||
sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::sample_rate_changed));
|
||||
buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed));
|
||||
device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
|
||||
|
||||
input_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
input_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
|
||||
input_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &input_channels));
|
||||
output_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &output_channels));
|
||||
|
||||
notebook.signal_switch_page().connect (sigc::mem_fun (*this, &EngineControl::on_switch_page));
|
||||
}
|
||||
|
||||
EngineControl::~EngineControl ()
|
||||
|
|
@ -470,6 +559,11 @@ EngineControl::refresh_midi_display ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::update_sensitivity ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::backend_changed ()
|
||||
{
|
||||
|
|
@ -485,16 +579,29 @@ EngineControl::backend_changed ()
|
|||
return;
|
||||
}
|
||||
|
||||
_have_control = ARDOUR::AudioEngine::instance()->setup_required ();
|
||||
|
||||
build_notebook ();
|
||||
setup_midi_tab_for_backend ();
|
||||
|
||||
if (backend->requires_driver_selection()) {
|
||||
vector<string> drivers = backend->enumerate_drivers();
|
||||
driver_combo.set_sensitive (true);
|
||||
set_popdown_strings (driver_combo, drivers);
|
||||
driver_combo.set_active_text (drivers.front());
|
||||
driver_changed ();
|
||||
|
||||
if (!drivers.empty()) {
|
||||
{
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
set_popdown_strings (driver_combo, drivers);
|
||||
driver_combo.set_active_text (drivers.front());
|
||||
}
|
||||
|
||||
driver_changed ();
|
||||
}
|
||||
|
||||
} else {
|
||||
driver_combo.set_sensitive (false);
|
||||
/* this will change the device text which will cause a call to
|
||||
* device changed which will set up parameters
|
||||
*/
|
||||
list_devices ();
|
||||
}
|
||||
|
||||
|
|
@ -540,33 +647,33 @@ EngineControl::list_devices ()
|
|||
available_devices.push_back (i->name);
|
||||
}
|
||||
|
||||
ignore_changes++;
|
||||
set_popdown_strings (device_combo, available_devices);
|
||||
ignore_changes--;
|
||||
|
||||
if (!available_devices.empty()) {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
input_latency.set_sensitive (true);
|
||||
output_latency.set_sensitive (true);
|
||||
input_channels.set_sensitive (true);
|
||||
output_channels.set_sensitive (true);
|
||||
|
||||
update_sensitivity ();
|
||||
|
||||
/* changing the text in the combo will trigger device_changed()
|
||||
which should populate the parameter controls
|
||||
*/
|
||||
|
||||
device_combo.set_active_text (available_devices.front());
|
||||
{
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
set_popdown_strings (device_combo, available_devices);
|
||||
device_combo.set_active_text (available_devices.front());
|
||||
}
|
||||
|
||||
device_changed ();
|
||||
|
||||
ok_button->set_sensitive (true);
|
||||
apply_button->set_sensitive (true);
|
||||
|
||||
} else {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
input_latency.set_sensitive (true);
|
||||
output_latency.set_sensitive (true);
|
||||
input_channels.set_sensitive (true);
|
||||
output_channels.set_sensitive (true);
|
||||
sample_rate_combo.set_sensitive (false);
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
input_latency.set_sensitive (false);
|
||||
output_latency.set_sensitive (false);
|
||||
input_channels.set_sensitive (false);
|
||||
output_channels.set_sensitive (false);
|
||||
ok_button->set_sensitive (false);
|
||||
apply_button->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EngineControl::driver_changed ()
|
||||
{
|
||||
|
|
@ -595,58 +702,94 @@ EngineControl::device_changed ()
|
|||
string device_name = device_combo.get_active_text ();
|
||||
vector<string> s;
|
||||
|
||||
/* don't allow programmatic change to sample_rate_combo to cause a
|
||||
recursive call to this method.
|
||||
*/
|
||||
|
||||
ignore_changes++;
|
||||
{
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
|
||||
/* sample rates */
|
||||
|
||||
string desired;
|
||||
/* don't allow programmatic change to combos to cause a
|
||||
recursive call to this method.
|
||||
*/
|
||||
|
||||
/* sample rates */
|
||||
|
||||
string desired;
|
||||
|
||||
vector<float> sr;
|
||||
|
||||
vector<float> sr = backend->available_sample_rates (device_name);
|
||||
for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) {
|
||||
s.push_back (rate_as_string (*x));
|
||||
if (*x == _desired_sample_rate) {
|
||||
desired = s.back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
set_popdown_strings (sample_rate_combo, s);
|
||||
|
||||
if (desired.empty()) {
|
||||
sample_rate_combo.set_active_text (s.front());
|
||||
if (_have_control) {
|
||||
sr = backend->available_sample_rates (device_name);
|
||||
} else {
|
||||
sample_rate_combo.set_active_text (desired);
|
||||
|
||||
sr.push_back (8000.0f);
|
||||
sr.push_back (16000.0f);
|
||||
sr.push_back (32000.0f);
|
||||
sr.push_back (44100.0f);
|
||||
sr.push_back (48000.0f);
|
||||
sr.push_back (88200.0f);
|
||||
sr.push_back (96000.0f);
|
||||
sr.push_back (192000.0f);
|
||||
sr.push_back (384000.0f);
|
||||
}
|
||||
} else {
|
||||
/* hmm ... how to tell the user about the fact that we have no
|
||||
* available sample rates.
|
||||
|
||||
for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) {
|
||||
s.push_back (rate_as_string (*x));
|
||||
if (*x == _desired_sample_rate) {
|
||||
desired = s.back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
set_popdown_strings (sample_rate_combo, s);
|
||||
|
||||
if (desired.empty()) {
|
||||
sample_rate_combo.set_active_text (s.front());
|
||||
} else {
|
||||
sample_rate_combo.set_active_text (desired);
|
||||
}
|
||||
|
||||
} else {
|
||||
sample_rate_combo.set_sensitive (false);
|
||||
}
|
||||
|
||||
/* buffer sizes */
|
||||
|
||||
vector<uint32_t> bs;
|
||||
|
||||
if (_have_control) {
|
||||
bs = backend->available_buffer_sizes(device_name);
|
||||
} else if (backend->can_change_buffer_size_when_running()) {
|
||||
bs.push_back (8);
|
||||
bs.push_back (16);
|
||||
bs.push_back (32);
|
||||
bs.push_back (64);
|
||||
bs.push_back (128);
|
||||
bs.push_back (256);
|
||||
bs.push_back (512);
|
||||
bs.push_back (1024);
|
||||
bs.push_back (2048);
|
||||
bs.push_back (4096);
|
||||
bs.push_back (8192);
|
||||
}
|
||||
s.clear ();
|
||||
for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) {
|
||||
s.push_back (bufsize_as_string (*x));
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
set_popdown_strings (buffer_size_combo, s);
|
||||
|
||||
buffer_size_combo.set_active_text (s.front());
|
||||
show_buffer_duration ();
|
||||
} else {
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
}
|
||||
|
||||
/* XXX theoretically need to set min + max channel counts here
|
||||
*/
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
}
|
||||
|
||||
|
||||
vector<uint32_t> bs = backend->available_buffer_sizes(device_name);
|
||||
s.clear ();
|
||||
for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) {
|
||||
s.push_back (bufsize_as_string (*x));
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
set_popdown_strings (buffer_size_combo, s);
|
||||
buffer_size_combo.set_active_text (s.front());
|
||||
show_buffer_duration ();
|
||||
} else {
|
||||
/* hmm ... how to tell the user about the fact that we have no
|
||||
* available buffer sizes.
|
||||
*/
|
||||
}
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
|
||||
ignore_changes--;
|
||||
|
||||
/* pick up any saved state for this device */
|
||||
|
||||
|
|
@ -657,18 +800,6 @@ EngineControl::device_changed ()
|
|||
push_state_to_backend (false);
|
||||
}
|
||||
|
||||
string
|
||||
EngineControl::rate_as_string (float r)
|
||||
{
|
||||
char buf[32];
|
||||
if (fmod (r, 1000.0f)) {
|
||||
snprintf (buf, sizeof (buf), "%.1f kHz", r/1000.0);
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), "%.0f kHz", r/1000.0);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
string
|
||||
EngineControl::bufsize_as_string (uint32_t sz)
|
||||
{
|
||||
|
|
@ -774,6 +905,10 @@ EngineControl::get_saved_state_for_currently_displayed_backend_and_device ()
|
|||
EngineControl::State*
|
||||
EngineControl::save_state ()
|
||||
{
|
||||
if (!_have_control) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool existing = true;
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
|
|
@ -808,10 +943,15 @@ EngineControl::store_state (State& state)
|
|||
void
|
||||
EngineControl::maybe_display_saved_state ()
|
||||
{
|
||||
if (!_have_control) {
|
||||
return;
|
||||
}
|
||||
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
if (state) {
|
||||
ignore_changes++;
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
|
||||
if (!_desired_sample_rate) {
|
||||
sample_rate_combo.set_active_text (rate_as_string (state->sample_rate));
|
||||
}
|
||||
|
|
@ -822,7 +962,6 @@ EngineControl::maybe_display_saved_state ()
|
|||
show_buffer_duration ();
|
||||
input_latency.set_value (state->input_latency);
|
||||
output_latency.set_value (state->output_latency);
|
||||
ignore_changes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -952,6 +1091,7 @@ EngineControl::set_state (const XMLNode& root)
|
|||
/* now see if there was an active state and switch the setup to it */
|
||||
|
||||
for (StateList::const_iterator i = states.begin(); i != states.end(); ++i) {
|
||||
|
||||
if ((*i).active) {
|
||||
ignore_changes++;
|
||||
backend_combo.set_active_text ((*i).backend);
|
||||
|
|
@ -971,6 +1111,10 @@ EngineControl::set_state (const XMLNode& root)
|
|||
int
|
||||
EngineControl::push_state_to_backend (bool start)
|
||||
{
|
||||
if (no_push) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
|
||||
if (!backend) {
|
||||
|
|
@ -992,47 +1136,60 @@ EngineControl::push_state_to_backend (bool start)
|
|||
uint32_t ichan = get_input_channels ();
|
||||
|
||||
if (_have_control) {
|
||||
|
||||
/* we can control the backend */
|
||||
|
||||
if (backend->requires_driver_selection()) {
|
||||
if (get_driver() != backend->driver_name()) {
|
||||
change_driver = true;
|
||||
if (started_at_least_once) {
|
||||
|
||||
/* we can control the backend */
|
||||
|
||||
if (backend->requires_driver_selection()) {
|
||||
if (get_driver() != backend->driver_name()) {
|
||||
change_driver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_device_name() != backend->device_name()) {
|
||||
change_device = true;
|
||||
}
|
||||
|
||||
if (get_rate() != backend->sample_rate()) {
|
||||
change_rate = true;
|
||||
}
|
||||
|
||||
if (get_buffer_size() != backend->buffer_size()) {
|
||||
change_bufsize = true;
|
||||
}
|
||||
|
||||
/* zero-requested channels means "all available" */
|
||||
|
||||
if (get_device_name() != backend->device_name()) {
|
||||
if (ichan == 0) {
|
||||
ichan = backend->input_channels();
|
||||
}
|
||||
|
||||
if (ochan == 0) {
|
||||
ochan = backend->output_channels();
|
||||
}
|
||||
|
||||
if (ichan != backend->input_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (ochan != backend->output_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (get_input_latency() != backend->systemic_input_latency() ||
|
||||
get_output_latency() != backend->systemic_output_latency()) {
|
||||
change_latency = true;
|
||||
}
|
||||
} else {
|
||||
/* backend never started, so we have to force a group
|
||||
of settings.
|
||||
*/
|
||||
change_driver = true;
|
||||
change_device = true;
|
||||
}
|
||||
|
||||
if (get_rate() != backend->sample_rate()) {
|
||||
change_rate = true;
|
||||
}
|
||||
|
||||
if (get_buffer_size() != backend->buffer_size()) {
|
||||
change_bufsize = true;
|
||||
}
|
||||
|
||||
/* zero-requested channels means "all available" */
|
||||
|
||||
if (ichan == 0) {
|
||||
ichan = backend->input_channels();
|
||||
}
|
||||
|
||||
if (ochan == 0) {
|
||||
ochan = backend->output_channels();
|
||||
}
|
||||
|
||||
if (ichan != backend->input_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (ochan != backend->output_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (get_input_latency() != backend->systemic_input_latency() ||
|
||||
get_output_latency() != backend->systemic_output_latency()) {
|
||||
change_latency = true;
|
||||
}
|
||||
|
||||
|
|
@ -1175,26 +1332,28 @@ EngineControl::post_push ()
|
|||
* necessary
|
||||
*/
|
||||
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
if (!state) {
|
||||
state = save_state ();
|
||||
assert (state);
|
||||
if (_have_control) {
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
if (!state) {
|
||||
state = save_state ();
|
||||
assert (state);
|
||||
}
|
||||
|
||||
/* all off */
|
||||
|
||||
for (StateList::iterator i = states.begin(); i != states.end(); ++i) {
|
||||
(*i).active = false;
|
||||
}
|
||||
|
||||
/* mark this one active (to be used next time the dialog is
|
||||
* shown)
|
||||
*/
|
||||
|
||||
state->active = true;
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
}
|
||||
|
||||
/* all off */
|
||||
|
||||
for (StateList::iterator i = states.begin(); i != states.end(); ++i) {
|
||||
(*i).active = false;
|
||||
}
|
||||
|
||||
/* mark this one active (to be used next time the dialog is
|
||||
* shown)
|
||||
*/
|
||||
|
||||
state->active = true;
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
|
||||
/* schedule a redisplay of MIDI ports */
|
||||
|
||||
|
|
@ -1482,3 +1641,42 @@ EngineControl::on_delete_event (GdkEventAny* ev)
|
|||
return ArdourDialog::on_delete_event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::engine_running ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
buffer_size_combo.set_active_text (bufsize_as_string (backend->buffer_size()));
|
||||
sample_rate_combo.set_active_text (rate_as_string (backend->sample_rate()));
|
||||
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
|
||||
connect_disconnect_button.set_label (string_compose (_("Disconnect from %1"), backend->name()));
|
||||
|
||||
started_at_least_once = true;
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::engine_stopped ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
connect_disconnect_button.set_label (string_compose (_("Connect to %1"), backend->name()));
|
||||
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::connect_disconnect_click()
|
||||
{
|
||||
if (ARDOUR::AudioEngine::instance()->running()) {
|
||||
ARDOUR_UI::instance()->disconnect_from_engine ();
|
||||
} else {
|
||||
ARDOUR_UI::instance()->reconnect_to_engine ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,11 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
Gtk::Adjustment ports_adjustment;
|
||||
Gtk::SpinButton ports_spinner;
|
||||
|
||||
Gtk::Label have_control_text;
|
||||
Gtk::Button control_app_button;
|
||||
|
||||
Gtk::Button connect_disconnect_button;
|
||||
|
||||
/* latency measurement */
|
||||
|
||||
Gtk::ComboBoxText lm_output_channel_combo;
|
||||
|
|
@ -106,9 +109,9 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
|
||||
uint32_t ignore_changes;
|
||||
uint32_t _desired_sample_rate;
|
||||
|
||||
static bool engine_running ();
|
||||
|
||||
bool no_push;
|
||||
bool started_at_least_once;
|
||||
|
||||
void driver_changed ();
|
||||
void backend_changed ();
|
||||
void sample_rate_changed ();
|
||||
|
|
@ -119,7 +122,6 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
void setup_midi_tab_for_jack ();
|
||||
void refresh_midi_display ();
|
||||
|
||||
std::string rate_as_string (float);
|
||||
std::string bufsize_as_string (uint32_t);
|
||||
|
||||
float get_rate() const;
|
||||
|
|
@ -174,6 +176,8 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
static bool print_channel_count (Gtk::SpinButton*);
|
||||
|
||||
void build_notebook ();
|
||||
void build_full_control_notebook ();
|
||||
void build_no_control_notebook ();
|
||||
|
||||
void on_response (int);
|
||||
void control_app_button_clicked ();
|
||||
|
|
@ -181,6 +185,7 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
void manage_control_app_sensitivity ();
|
||||
int push_state_to_backend (bool start);
|
||||
void post_push ();
|
||||
void update_sensitivity ();
|
||||
|
||||
/* latency measurement */
|
||||
void latency_button_toggled ();
|
||||
|
|
@ -190,9 +195,16 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
void disable_latency_tab ();
|
||||
void start_latency_detection ();
|
||||
void end_latency_detection ();
|
||||
|
||||
|
||||
void on_switch_page (GtkNotebookPage*, guint page_num);
|
||||
bool on_delete_event (GdkEventAny*);
|
||||
|
||||
void engine_running ();
|
||||
void engine_stopped ();
|
||||
PBD::ScopedConnection running_connection;
|
||||
PBD::ScopedConnection stopped_connection;
|
||||
|
||||
void connect_disconnect_click ();
|
||||
};
|
||||
|
||||
#endif /* __gtk2_ardour_engine_dialog_h__ */
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#include <sigc++/bind.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdint.h>
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
|
|
@ -732,13 +732,13 @@ piano_keyboard_set_keyboard_layout(PianoKeyboard *pk, const char *layout)
|
|||
{
|
||||
assert(layout);
|
||||
|
||||
if (!strcasecmp(layout, "QWERTY")) {
|
||||
if (!g_strcasecmp(layout, "QWERTY")) {
|
||||
bind_keys_qwerty(pk);
|
||||
|
||||
} else if (!strcasecmp(layout, "QWERTZ")) {
|
||||
} else if (!g_strcasecmp(layout, "QWERTZ")) {
|
||||
bind_keys_qwertz(pk);
|
||||
|
||||
} else if (!strcasecmp(layout, "AZERTY")) {
|
||||
} else if (!g_strcasecmp(layout, "AZERTY")) {
|
||||
bind_keys_azerty(pk);
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -250,8 +250,6 @@ KeyEditor::populate ()
|
|||
//kinda kludgy way to avoid displaying menu items as mappable
|
||||
if ( parts[1] == _("Main_menu") )
|
||||
continue;
|
||||
if ( parts[1] == _("JACK") )
|
||||
continue;
|
||||
if ( parts[1] == _("redirectmenu") )
|
||||
continue;
|
||||
if ( parts[1] == _("Editor_menus") )
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
#include "pbd/boost_debug.h"
|
||||
#endif
|
||||
|
||||
#include <jack/jack.h>
|
||||
|
||||
#include "ardour/revision.h"
|
||||
#include "ardour/version.h"
|
||||
#include "ardour/ardour.h"
|
||||
|
|
@ -81,17 +79,10 @@ static const char* localedir = LOCALEDIR;
|
|||
void
|
||||
gui_jack_error ()
|
||||
{
|
||||
MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
|
||||
MessageDialog win (string_compose (_("%1 could not connect to the audio backend."), PROGRAM_NAME),
|
||||
false,
|
||||
Gtk::MESSAGE_INFO,
|
||||
Gtk::BUTTONS_NONE);
|
||||
win.set_secondary_text(string_compose (_("There are several possible reasons:\n\
|
||||
\n\
|
||||
1) JACK is not running.\n\
|
||||
2) JACK is running as another user, perhaps root.\n\
|
||||
3) There is already another client called \"%1\".\n\
|
||||
\n\
|
||||
Please consider the possibilities, and perhaps (re)start JACK."), PROGRAM_NAME));
|
||||
|
||||
win.add_button (Stock::QUIT, RESPONSE_CLOSE);
|
||||
win.set_default_response (RESPONSE_CLOSE);
|
||||
|
|
@ -530,6 +521,7 @@ int main (int argc, char *argv[])
|
|||
|
||||
ui->run (text_receiver);
|
||||
Gtkmm2ext::Application::instance()->cleanup();
|
||||
delete ui;
|
||||
ui = 0;
|
||||
|
||||
ARDOUR::cleanup ();
|
||||
|
|
|
|||
|
|
@ -698,7 +698,7 @@ MixerStrip::output_press (GdkEventButton *ev)
|
|||
{
|
||||
using namespace Menu_Helpers;
|
||||
if (!_session->engine().connected()) {
|
||||
MessageDialog msg (_("Not connected to JACK - no I/O changes are possible"));
|
||||
MessageDialog msg (_("Not connected to audio engine - no I/O changes are possible"));
|
||||
msg.run ();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -826,7 +826,7 @@ MixerStrip::input_press (GdkEventButton *ev)
|
|||
citems.clear();
|
||||
|
||||
if (!_session->engine().connected()) {
|
||||
MessageDialog msg (_("Not connected to JACK - no I/O changes are possible"));
|
||||
MessageDialog msg (_("Not connected to audio engine - no I/O changes are possible"));
|
||||
msg.run ();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -537,13 +537,13 @@ struct PluginMenuCompareByCreator {
|
|||
bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
|
||||
int cmp;
|
||||
|
||||
cmp = strcasecmp (a->creator.c_str(), b->creator.c_str());
|
||||
cmp = g_strcasecmp (a->creator.c_str(), b->creator.c_str());
|
||||
|
||||
if (cmp < 0) {
|
||||
return true;
|
||||
} else if (cmp == 0) {
|
||||
/* same creator ... compare names */
|
||||
if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
|
||||
if (g_strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -555,7 +555,7 @@ struct PluginMenuCompareByName {
|
|||
bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
|
||||
int cmp;
|
||||
|
||||
cmp = strcasecmp (a->name.c_str(), b->name.c_str());
|
||||
cmp = g_strcasecmp (a->name.c_str(), b->name.c_str());
|
||||
|
||||
if (cmp < 0) {
|
||||
return true;
|
||||
|
|
@ -573,13 +573,13 @@ struct PluginMenuCompareByCategory {
|
|||
bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
|
||||
int cmp;
|
||||
|
||||
cmp = strcasecmp (a->category.c_str(), b->category.c_str());
|
||||
cmp = g_strcasecmp (a->category.c_str(), b->category.c_str());
|
||||
|
||||
if (cmp < 0) {
|
||||
return true;
|
||||
} else if (cmp == 0) {
|
||||
/* same category ... compare names */
|
||||
if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
|
||||
if (g_strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2577
gtk2_ardour/po/de.po
2577
gtk2_ardour/po/de.po
File diff suppressed because it is too large
Load diff
|
|
@ -2151,7 +2151,7 @@ ProcessorBox::get_editor_window (boost::shared_ptr<Processor> processor, bool us
|
|||
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
|
||||
|
||||
if (!_session->engine().connected()) {
|
||||
MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
|
||||
MessageDialog msg ( _("Not connected to audio engine - no I/O changes are possible"));
|
||||
msg.run ();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1146,7 +1146,7 @@ RCOptionEditor::RCOptionEditor ()
|
|||
|
||||
tsf = new BoolOption (
|
||||
"seamless-loop",
|
||||
_("Do seamless looping (not possible when slaved to MTC, JACK etc)"),
|
||||
_("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
|
||||
sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
|
||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
|
||||
);
|
||||
|
|
@ -1464,12 +1464,10 @@ RCOptionEditor::RCOptionEditor ()
|
|||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
|
||||
);
|
||||
|
||||
#ifndef __APPLE__
|
||||
/* no JACK monitoring on CoreAudio */
|
||||
if (AudioEngine::instance()->port_engine().can_monitor_input()) {
|
||||
mm->add (HardwareMonitoring, _("via Audio Driver"));
|
||||
}
|
||||
#endif
|
||||
|
||||
mm->add (SoftwareMonitoring, _("ardour"));
|
||||
mm->add (ExternalMonitoring, _("audio hardware"));
|
||||
|
||||
|
|
|
|||
1075
gtk2_ardour/session_dialog.cc
Normal file
1075
gtk2_ardour/session_dialog.cc
Normal file
File diff suppressed because it is too large
Load diff
240
gtk2_ardour/session_dialog.h
Normal file
240
gtk2_ardour/session_dialog.h
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
Copyright (C) 2010 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __gtk2_ardour_session_dialog_h__
|
||||
#define __gtk2_ardour_session_dialog_h__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <gdkmm/pixbuf.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <gtkmm/drawingarea.h>
|
||||
#include <gtkmm/expander.h>
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/radiobutton.h>
|
||||
#include <gtkmm/filechooserbutton.h>
|
||||
#include <gtkmm/scrolledwindow.h>
|
||||
#include <gtkmm/treeview.h>
|
||||
#include <gtkmm/treestore.h>
|
||||
#include <gtkmm/checkbutton.h>
|
||||
#include <gtkmm/table.h>
|
||||
#include <gtkmm/frame.h>
|
||||
#include <gtkmm/spinbutton.h>
|
||||
#include <gtkmm/liststore.h>
|
||||
#include <gtkmm/combobox.h>
|
||||
|
||||
#include "ardour/utils.h"
|
||||
|
||||
#include "ardour_dialog.h"
|
||||
|
||||
class EngineControl;
|
||||
|
||||
class SessionDialog : public ArdourDialog {
|
||||
public:
|
||||
SessionDialog (bool require_new, const std::string& session_name, const std::string& session_path,
|
||||
const std::string& template_name, bool cancel_not_quit);
|
||||
~SessionDialog ();
|
||||
|
||||
void clear_given ();
|
||||
|
||||
std::string session_name (bool& should_be_new);
|
||||
std::string session_folder ();
|
||||
|
||||
bool use_session_template();
|
||||
std::string session_template_name();
|
||||
|
||||
// advanced session options
|
||||
|
||||
bool create_master_bus() const;
|
||||
int master_channel_count() const;
|
||||
|
||||
bool connect_inputs() const;
|
||||
bool limit_inputs_used_for_connection() const;
|
||||
int input_limit_count() const;
|
||||
|
||||
bool connect_outputs() const;
|
||||
bool limit_outputs_used_for_connection() const;
|
||||
int output_limit_count() const;
|
||||
|
||||
bool connect_outs_to_master() const;
|
||||
bool connect_outs_to_physical() const;
|
||||
|
||||
private:
|
||||
bool new_only;
|
||||
std::string _provided_session_name;
|
||||
std::string _provided_session_path;
|
||||
|
||||
bool on_delete_event (GdkEventAny*);
|
||||
|
||||
Gtk::Button* cancel_button;
|
||||
Gtk::Button* open_button;
|
||||
Gtk::Button* back_button;
|
||||
Gtk::Button* quit_button;
|
||||
|
||||
bool back_button_pressed (GdkEventButton*);
|
||||
|
||||
Gtk::Frame info_frame;
|
||||
|
||||
/* initial choice page */
|
||||
|
||||
void setup_initial_choice_box ();
|
||||
Gtk::VBox ic_vbox;
|
||||
Gtk::Button ic_new_session_button;
|
||||
void new_session_button_clicked ();
|
||||
|
||||
/* recent sessions */
|
||||
|
||||
void setup_existing_session_page ();
|
||||
|
||||
struct RecentSessionsSorter {
|
||||
bool operator() (std::pair<std::string,std::string> a, std::pair<std::string,std::string> b) const {
|
||||
return cmp_nocase(a.first, b.first) == -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
RecentSessionModelColumns() {
|
||||
add (visible_name);
|
||||
add (tip);
|
||||
add (fullpath);
|
||||
add (sample_rate);
|
||||
add (disk_format);
|
||||
}
|
||||
Gtk::TreeModelColumn<std::string> visible_name;
|
||||
Gtk::TreeModelColumn<std::string> tip;
|
||||
Gtk::TreeModelColumn<std::string> fullpath;
|
||||
Gtk::TreeModelColumn<std::string> sample_rate;
|
||||
Gtk::TreeModelColumn<std::string> disk_format;
|
||||
};
|
||||
|
||||
RecentSessionModelColumns recent_session_columns;
|
||||
Gtk::TreeView recent_session_display;
|
||||
Glib::RefPtr<Gtk::TreeStore> recent_session_model;
|
||||
Gtk::ScrolledWindow recent_scroller;
|
||||
Gtk::Label recent_label;
|
||||
Gtk::FileChooserButton existing_session_chooser;
|
||||
int redisplay_recent_sessions ();
|
||||
void recent_session_row_selected ();
|
||||
void recent_row_activated (const Gtk::TreePath& path, Gtk::TreeViewColumn* col);
|
||||
|
||||
void existing_session_selected ();
|
||||
void session_selected ();
|
||||
|
||||
/* new sessions */
|
||||
|
||||
void setup_new_session_page ();
|
||||
Gtk::Entry new_name_entry;
|
||||
Gtk::FileChooserButton new_folder_chooser;
|
||||
|
||||
struct SessionTemplateColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
SessionTemplateColumns () {
|
||||
add (name);
|
||||
add (path);
|
||||
}
|
||||
|
||||
Gtk::TreeModelColumn<std::string> name;
|
||||
Gtk::TreeModelColumn<std::string> path;
|
||||
};
|
||||
|
||||
SessionTemplateColumns session_template_columns;
|
||||
Glib::RefPtr<Gtk::ListStore> template_model;
|
||||
Gtk::ComboBox template_chooser;
|
||||
|
||||
Gtk::VBox session_new_vbox;
|
||||
Gtk::VBox session_existing_vbox;
|
||||
Gtk::Expander more_new_session_options_button;
|
||||
Gtk::CheckButton use_template_button;
|
||||
std::string load_template_override;
|
||||
|
||||
void more_new_session_options_button_clicked();
|
||||
void new_name_changed ();
|
||||
void new_name_activated ();
|
||||
void populate_session_templates ();
|
||||
|
||||
/* more options for new sessions */
|
||||
|
||||
Gtk::VBox more_options_vbox;
|
||||
|
||||
Gtk::Label chan_count_label_1;
|
||||
Gtk::Label chan_count_label_3;
|
||||
Gtk::Label chan_count_label_4;
|
||||
Gtk::Table advanced_table;
|
||||
Gtk::HBox input_port_limit_hbox;
|
||||
Gtk::VBox input_port_vbox;
|
||||
Gtk::Table input_table;
|
||||
Gtk::HBox input_hbox;
|
||||
|
||||
Gtk::Label bus_label;
|
||||
Gtk::Frame bus_frame;
|
||||
Gtk::Table bus_table;
|
||||
Gtk::HBox bus_hbox;
|
||||
|
||||
Gtk::Label input_label;
|
||||
Gtk::Frame input_frame;
|
||||
Gtk::HBox output_port_limit_hbox;
|
||||
Gtk::VBox output_port_vbox;
|
||||
Gtk::VBox output_conn_vbox;
|
||||
Gtk::VBox output_vbox;
|
||||
Gtk::HBox output_hbox;
|
||||
|
||||
Gtk::Label output_label;
|
||||
Gtk::Frame output_frame;
|
||||
Gtk::VBox advanced_vbox;
|
||||
Gtk::Label advanced_label;
|
||||
|
||||
Gtk::CheckButton _create_master_bus;
|
||||
Gtk::SpinButton _master_bus_channel_count;
|
||||
|
||||
Gtk::CheckButton _connect_inputs;
|
||||
Gtk::CheckButton _limit_input_ports;
|
||||
Gtk::SpinButton _input_limit_count;
|
||||
|
||||
Gtk::CheckButton _connect_outputs;
|
||||
Gtk::CheckButton _limit_output_ports;
|
||||
Gtk::SpinButton _output_limit_count;
|
||||
|
||||
Gtk::RadioButtonGroup connect_outputs_group;
|
||||
Gtk::RadioButton _connect_outputs_to_master;
|
||||
Gtk::RadioButton _connect_outputs_to_physical;
|
||||
|
||||
Gtk::Adjustment _output_limit_count_adj;
|
||||
Gtk::Adjustment _input_limit_count_adj;
|
||||
Gtk::Adjustment _master_bus_channel_count_adj;
|
||||
|
||||
void connect_inputs_clicked ();
|
||||
void connect_outputs_clicked ();
|
||||
void limit_inputs_clicked ();
|
||||
void limit_outputs_clicked ();
|
||||
void master_bus_button_clicked ();
|
||||
void setup_more_options_box ();
|
||||
|
||||
/* always there */
|
||||
|
||||
Glib::RefPtr<Pango::Layout> layout;
|
||||
|
||||
bool _existing_session_chooser_used; ///< set to true when the existing session chooser has been used
|
||||
|
||||
Gtk::Label info_scroller_label;
|
||||
std::string::size_type info_scroller_count;
|
||||
bool info_scroller_update();
|
||||
sigc::connection info_scroller_connection;
|
||||
void updates_button_clicked ();
|
||||
};
|
||||
|
||||
#endif /* __gtk2_ardour_session_dialog_h__ */
|
||||
|
|
@ -334,7 +334,7 @@ SessionOptionEditor::parameter_changed (std::string const & p)
|
|||
{
|
||||
OptionEditor::parameter_changed (p);
|
||||
if (p == "external-sync") {
|
||||
if (Config->get_sync_source() == JACK) {
|
||||
if (Config->get_sync_source() == Engine) {
|
||||
_vpu->set_sensitive(!_session_config->get_external_sync());
|
||||
} else {
|
||||
_vpu->set_sensitive(true);
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
#include <sstream>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/stock.h>
|
||||
|
|
@ -1473,7 +1473,7 @@ SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths
|
|||
|
||||
for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
|
||||
|
||||
char tmpc[MAXPATHLEN+1];
|
||||
char tmpc[PATH_MAX+1];
|
||||
|
||||
snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
|
||||
|
||||
|
|
|
|||
BIN
gtk2_ardour/small-splash.png
Normal file
BIN
gtk2_ardour/small-splash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
File diff suppressed because it is too large
Load diff
|
|
@ -26,6 +26,7 @@
|
|||
#include <gtkmm/assistant.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <gtkmm/drawingarea.h>
|
||||
#include <gtkmm/expander.h>
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/radiobutton.h>
|
||||
#include <gtkmm/filechooserbutton.h>
|
||||
|
|
@ -45,32 +46,10 @@ class EngineControl;
|
|||
|
||||
class ArdourStartup : public Gtk::Assistant {
|
||||
public:
|
||||
ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name);
|
||||
ArdourStartup ();
|
||||
~ArdourStartup ();
|
||||
|
||||
bool ready_without_display () const;
|
||||
|
||||
std::string session_name (bool& should_be_new);
|
||||
std::string session_folder ();
|
||||
|
||||
bool use_session_template();
|
||||
std::string session_template_name();
|
||||
|
||||
// advanced session options
|
||||
|
||||
bool create_master_bus() const;
|
||||
int master_channel_count() const;
|
||||
|
||||
bool connect_inputs() const;
|
||||
bool limit_inputs_used_for_connection() const;
|
||||
int input_limit_count() const;
|
||||
|
||||
bool connect_outputs() const;
|
||||
bool limit_outputs_used_for_connection() const;
|
||||
int output_limit_count() const;
|
||||
|
||||
bool connect_outs_to_master() const;
|
||||
bool connect_outs_to_physical() const;
|
||||
static bool required ();
|
||||
|
||||
gint response () const {
|
||||
return _response;
|
||||
|
|
@ -80,17 +59,12 @@ class ArdourStartup : public Gtk::Assistant {
|
|||
gint _response;
|
||||
bool config_modified;
|
||||
bool new_user;
|
||||
bool need_session_info;
|
||||
bool new_only;
|
||||
std::string _provided_session_name;
|
||||
std::string _provided_session_path;
|
||||
|
||||
std::string been_here_before_path () const;
|
||||
static std::string been_here_before_path ();
|
||||
|
||||
void on_apply ();
|
||||
void on_cancel ();
|
||||
bool on_delete_event (GdkEventAny*);
|
||||
void on_prepare (Gtk::Widget*);
|
||||
|
||||
static ArdourStartup *the_startup;
|
||||
|
||||
|
|
@ -108,15 +82,7 @@ class ArdourStartup : public Gtk::Assistant {
|
|||
Gtk::FileChooserButton* default_dir_chooser;
|
||||
void default_dir_changed();
|
||||
void setup_first_page ();
|
||||
|
||||
/* initial choice page */
|
||||
|
||||
void setup_initial_choice_page ();
|
||||
Gtk::VBox ic_vbox;
|
||||
Gtk::RadioButton ic_new_session_button;
|
||||
Gtk::RadioButton ic_existing_session_button;
|
||||
bool initial_button_clicked(GdkEventButton*);
|
||||
void initial_button_activated();
|
||||
Gtk::FileChooserButton new_folder_chooser;
|
||||
|
||||
/* monitoring choices */
|
||||
|
||||
|
|
@ -134,134 +100,6 @@ class ArdourStartup : public Gtk::Assistant {
|
|||
Gtk::RadioButton no_monitor_section_button;
|
||||
void setup_monitor_section_choice_page ();
|
||||
|
||||
/* session page (could be new or existing) */
|
||||
|
||||
void setup_session_page ();
|
||||
Gtk::VBox session_vbox;
|
||||
Gtk::HBox session_hbox;
|
||||
|
||||
/* recent sessions */
|
||||
|
||||
void setup_existing_session_page ();
|
||||
|
||||
struct RecentSessionsSorter {
|
||||
bool operator() (std::pair<std::string,std::string> a, std::pair<std::string,std::string> b) const {
|
||||
return cmp_nocase(a.first, b.first) == -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
RecentSessionModelColumns() {
|
||||
add (visible_name);
|
||||
add (tip);
|
||||
add (fullpath);
|
||||
}
|
||||
Gtk::TreeModelColumn<std::string> visible_name;
|
||||
Gtk::TreeModelColumn<std::string> tip;
|
||||
Gtk::TreeModelColumn<std::string> fullpath;
|
||||
};
|
||||
|
||||
RecentSessionModelColumns recent_session_columns;
|
||||
Gtk::TreeView recent_session_display;
|
||||
Glib::RefPtr<Gtk::TreeStore> recent_session_model;
|
||||
Gtk::ScrolledWindow recent_scroller;
|
||||
Gtk::FileChooserButton existing_session_chooser;
|
||||
int redisplay_recent_sessions ();
|
||||
void recent_session_row_selected ();
|
||||
void recent_row_activated (const Gtk::TreePath& path, Gtk::TreeViewColumn* col);
|
||||
|
||||
void existing_session_selected ();
|
||||
|
||||
/* new sessions */
|
||||
|
||||
void setup_new_session_page ();
|
||||
Gtk::Entry new_name_entry;
|
||||
Gtk::FileChooserButton new_folder_chooser;
|
||||
Gtk::FileChooserButton session_template_chooser;
|
||||
|
||||
struct SessionTemplateColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
SessionTemplateColumns () {
|
||||
add (name);
|
||||
add (path);
|
||||
}
|
||||
|
||||
Gtk::TreeModelColumn<std::string> name;
|
||||
Gtk::TreeModelColumn<std::string> path;
|
||||
};
|
||||
|
||||
SessionTemplateColumns session_template_columns;
|
||||
Glib::RefPtr<Gtk::ListStore> template_model;
|
||||
Gtk::ComboBox template_chooser;
|
||||
|
||||
Gtk::VBox session_new_vbox;
|
||||
Gtk::VBox session_existing_vbox;
|
||||
Gtk::CheckButton more_new_session_options_button;
|
||||
Gtk::RadioButtonGroup session_template_group;
|
||||
Gtk::RadioButton use_session_as_template_button;
|
||||
Gtk::RadioButton use_template_button;
|
||||
std::string load_template_override;
|
||||
|
||||
void more_new_session_options_button_clicked();
|
||||
void new_name_changed ();
|
||||
void populate_session_templates ();
|
||||
|
||||
/* more options for new sessions */
|
||||
|
||||
Gtk::VBox more_options_vbox;
|
||||
|
||||
Gtk::Label chan_count_label_1;
|
||||
Gtk::Label chan_count_label_3;
|
||||
Gtk::Label chan_count_label_4;
|
||||
Gtk::Table advanced_table;
|
||||
Gtk::HBox input_port_limit_hbox;
|
||||
Gtk::VBox input_port_vbox;
|
||||
Gtk::Table input_table;
|
||||
Gtk::HBox input_hbox;
|
||||
|
||||
Gtk::Label bus_label;
|
||||
Gtk::Frame bus_frame;
|
||||
Gtk::Table bus_table;
|
||||
Gtk::HBox bus_hbox;
|
||||
|
||||
Gtk::Label input_label;
|
||||
Gtk::Frame input_frame;
|
||||
Gtk::HBox output_port_limit_hbox;
|
||||
Gtk::VBox output_port_vbox;
|
||||
Gtk::VBox output_conn_vbox;
|
||||
Gtk::VBox output_vbox;
|
||||
Gtk::HBox output_hbox;
|
||||
|
||||
Gtk::Label output_label;
|
||||
Gtk::Frame output_frame;
|
||||
Gtk::VBox advanced_vbox;
|
||||
Gtk::Label advanced_label;
|
||||
|
||||
Gtk::CheckButton _create_master_bus;
|
||||
Gtk::SpinButton _master_bus_channel_count;
|
||||
|
||||
Gtk::CheckButton _connect_inputs;
|
||||
Gtk::CheckButton _limit_input_ports;
|
||||
Gtk::SpinButton _input_limit_count;
|
||||
|
||||
Gtk::CheckButton _connect_outputs;
|
||||
Gtk::CheckButton _limit_output_ports;
|
||||
Gtk::SpinButton _output_limit_count;
|
||||
|
||||
Gtk::RadioButtonGroup connect_outputs_group;
|
||||
Gtk::RadioButton _connect_outputs_to_master;
|
||||
Gtk::RadioButton _connect_outputs_to_physical;
|
||||
|
||||
Gtk::Adjustment _output_limit_count_adj;
|
||||
Gtk::Adjustment _input_limit_count_adj;
|
||||
Gtk::Adjustment _master_bus_channel_count_adj;
|
||||
|
||||
void connect_inputs_clicked ();
|
||||
void connect_outputs_clicked ();
|
||||
void limit_inputs_clicked ();
|
||||
void limit_outputs_clicked ();
|
||||
void master_bus_button_clicked ();
|
||||
void setup_more_options_page ();
|
||||
|
||||
/* final page */
|
||||
|
||||
void setup_final_page ();
|
||||
|
|
@ -278,21 +116,12 @@ class ArdourStartup : public Gtk::Assistant {
|
|||
gint default_folder_page_index;
|
||||
gint monitoring_page_index;
|
||||
gint monitor_section_page_index;
|
||||
gint session_page_index;
|
||||
gint initial_choice_index;
|
||||
gint final_page_index;
|
||||
gint session_options_page_index;
|
||||
|
||||
void move_along_now ();
|
||||
|
||||
bool _existing_session_chooser_used; ///< set to true when the existing session chooser has been used
|
||||
void setup_prerelease_page ();
|
||||
|
||||
Gtk::Label info_scroller_label;
|
||||
std::string::size_type info_scroller_count;
|
||||
bool info_scroller_update();
|
||||
sigc::connection info_scroller_connection;
|
||||
void updates_button_clicked ();
|
||||
};
|
||||
|
||||
#endif /* __gtk2_ardour_startup_h__ */
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#include <sigc++/bind.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <clocale>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <sys/stat.h>
|
||||
|
|
@ -401,7 +402,7 @@ emulate_key_event (Gtk::Widget* w, unsigned int keyval)
|
|||
ev.state = 0;
|
||||
ev.keyval = keyval;
|
||||
ev.length = 0;
|
||||
ev.string = (const gchar*) "";
|
||||
ev.string = const_cast<gchar*> ("");
|
||||
ev.hardware_keycode = keymapkey[0].keycode;
|
||||
ev.group = keymapkey[0].group;
|
||||
g_free(keymapkey);
|
||||
|
|
@ -862,3 +863,15 @@ unique_random_color (list<Gdk::Color>& used_colors)
|
|||
/* XXX need throttle here to make sure we don't spin for ever */
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
rate_as_string (float r)
|
||||
{
|
||||
char buf[32];
|
||||
if (fmod (r, 1000.0f)) {
|
||||
snprintf (buf, sizeof (buf), "%.1f kHz", r/1000.0);
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), "%.0f kHz", r/1000.0);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,4 +86,6 @@ std::string escape_angled_brackets (std::string const &);
|
|||
|
||||
Gdk::Color unique_random_color (std::list<Gdk::Color> &);
|
||||
|
||||
std::string rate_as_string (float r);
|
||||
|
||||
#endif /* __ardour_gtk_utils_h__ */
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@ VideoMonitor::xjadeo_sync_setup ()
|
|||
|
||||
bool my_manual_seek = true;
|
||||
if (_session->config.get_external_sync()) {
|
||||
if (ARDOUR::Config->get_sync_source() == ARDOUR::JACK)
|
||||
if (ARDOUR::Config->get_sync_source() == ARDOUR::Engine)
|
||||
my_manual_seek = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XM
|
|||
ProxyBase::~ProxyBase ()
|
||||
{
|
||||
delete vistracker;
|
||||
delete _window;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ gtk2_ardour_sources = [
|
|||
'search_path_option.cc',
|
||||
'selection.cc',
|
||||
'send_ui.cc',
|
||||
'session_dialog.cc',
|
||||
'session_import_dialog.cc',
|
||||
'session_metadata_dialog.cc',
|
||||
'session_option_editor.cc',
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace ARDOUR {
|
|||
*/
|
||||
bool init (bool with_vst, bool try_optimization, const char* localedir);
|
||||
void init_post_engine ();
|
||||
int cleanup ();
|
||||
void cleanup ();
|
||||
bool no_auto_connect ();
|
||||
void make_property_quarks ();
|
||||
|
||||
|
|
|
|||
|
|
@ -399,13 +399,25 @@ class AudioBackend : public PortEngine {
|
|||
* stacksize. The thread will begin executing @param func, and will exit
|
||||
* when that function returns.
|
||||
*/
|
||||
virtual int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize) = 0;
|
||||
virtual int create_process_thread (boost::function<void()> func) = 0;
|
||||
|
||||
/** Wait for the thread specified by @param thread to exit.
|
||||
/** Wait for all processing threads to exit.
|
||||
*
|
||||
* Return zero on success, non-zero on failure.
|
||||
*/
|
||||
virtual int wait_for_process_thread_exit (AudioBackendNativeThread thread) = 0;
|
||||
virtual int join_process_threads () = 0;
|
||||
|
||||
/** Return true if execution context is in a backend thread
|
||||
*/
|
||||
virtual bool in_process_thread () = 0;
|
||||
|
||||
/** Return the minimum stack size of audio threads in bytes
|
||||
*/
|
||||
static size_t thread_stack_size () { return 100000; }
|
||||
|
||||
/** Return number of processing threads
|
||||
*/
|
||||
virtual uint32_t process_thread_count () = 0;
|
||||
|
||||
virtual void update_latencies () = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -100,8 +100,12 @@ public:
|
|||
pframes_t sample_time_at_cycle_start ();
|
||||
pframes_t samples_since_cycle_start ();
|
||||
bool get_sync_offset (pframes_t& offset) const;
|
||||
int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize);
|
||||
int wait_for_process_thread_exit (AudioBackendNativeThread);
|
||||
|
||||
int create_process_thread (boost::function<void()> func);
|
||||
int join_process_threads ();
|
||||
bool in_process_thread ();
|
||||
uint32_t process_thread_count ();
|
||||
|
||||
bool is_realtime() const;
|
||||
bool connected() const;
|
||||
|
||||
|
|
@ -225,6 +229,7 @@ public:
|
|||
std::string _latency_output_name;
|
||||
framecnt_t _latency_signal_latency;
|
||||
bool _started_for_latency;
|
||||
bool _in_destructor;
|
||||
|
||||
void meter_thread ();
|
||||
void start_metering_thread ();
|
||||
|
|
@ -232,9 +237,6 @@ public:
|
|||
|
||||
static gint m_meter_exit;
|
||||
|
||||
void parameter_changed (const std::string&);
|
||||
PBD::ScopedConnection config_connection;
|
||||
|
||||
typedef std::map<std::string,AudioBackendInfo*> BackendMap;
|
||||
BackendMap _backends;
|
||||
AudioBackendInfo* backend_discover (const std::string&);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@
|
|||
#include <glib.h>
|
||||
#include <cassert>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "pbd/semutils.h"
|
||||
|
||||
#include "ardour/types.h"
|
||||
|
|
@ -59,8 +57,6 @@ class Graph : public SessionHandleRef
|
|||
public:
|
||||
Graph (Session & session);
|
||||
|
||||
uint32_t threads_in_use () const { return _thread_list.size(); }
|
||||
|
||||
void prep();
|
||||
void trigger (GraphNode * n);
|
||||
void rechain (boost::shared_ptr<RouteList>, GraphEdges const &);
|
||||
|
|
@ -93,7 +89,6 @@ protected:
|
|||
virtual void session_going_away ();
|
||||
|
||||
private:
|
||||
std::list<AudioBackendNativeThread> _thread_list;
|
||||
volatile bool _quit_threads;
|
||||
|
||||
void reset_thread_list ();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ CONFIG_VARIABLE (int, mtc_qf_speed_tolerance, "mtc-qf-speed-tolerance", 5)
|
|||
CONFIG_VARIABLE (bool, timecode_sync_frame_rate, "timecode-sync-frame-rate", true)
|
||||
CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
|
||||
CONFIG_VARIABLE (bool, timecode_source_2997, "timecode-source-2997", false)
|
||||
CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", JACK)
|
||||
CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", Engine)
|
||||
CONFIG_VARIABLE (std::string, ltc_source_port, "ltc-source-port", "system:capture_1")
|
||||
CONFIG_VARIABLE (bool, send_ltc, "send-ltc", false)
|
||||
CONFIG_VARIABLE (bool, ltc_send_continuously, "ltc-send-continuously", true)
|
||||
|
|
|
|||
|
|
@ -161,6 +161,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
virtual ~Session ();
|
||||
|
||||
static int get_info_from_path (const std::string& xmlpath, float& sample_rate, SampleFormat& data_format);
|
||||
|
||||
std::string path() const { return _path; }
|
||||
std::string name() const { return _name; }
|
||||
std::string snap_name() const { return _current_snapshot_name; }
|
||||
|
|
@ -509,7 +511,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
static PBD::Signal1<void, framepos_t> EndTimeChanged;
|
||||
|
||||
void request_sync_source (Slave*);
|
||||
bool synced_to_jack() const { return config.get_external_sync() && Config->get_sync_source() == JACK; }
|
||||
bool synced_to_engine() const { return config.get_external_sync() && Config->get_sync_source() == Engine; }
|
||||
|
||||
double transport_speed() const { return _transport_speed; }
|
||||
bool transport_stopped() const { return _transport_speed == 0.0f; }
|
||||
|
|
@ -879,15 +881,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
MIDI::MachineControl& mmc() { return *_mmc; }
|
||||
|
||||
/* Callbacks specifically related to JACK, and called directly
|
||||
* from the JACK audio backend.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_JACK_SESSION
|
||||
void jack_session_event (jack_session_event_t* event);
|
||||
#endif
|
||||
void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
|
||||
|
||||
protected:
|
||||
friend class AudioEngine;
|
||||
void set_block_size (pframes_t nframes);
|
||||
|
|
@ -1617,7 +1610,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
void setup_ltc ();
|
||||
void setup_click ();
|
||||
void setup_click_state (const XMLNode&);
|
||||
void setup_bundles ();
|
||||
|
||||
static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
|||
|
|
@ -486,11 +486,11 @@ class MIDIClock_Slave : public Slave {
|
|||
bool _starting;
|
||||
};
|
||||
|
||||
class JACK_Slave : public Slave
|
||||
class Engine_Slave : public Slave
|
||||
{
|
||||
public:
|
||||
JACK_Slave (AudioEngine&);
|
||||
~JACK_Slave ();
|
||||
Engine_Slave (AudioEngine&);
|
||||
~Engine_Slave ();
|
||||
|
||||
bool speed_and_position (double& speed, framepos_t& pos);
|
||||
|
||||
|
|
|
|||
|
|
@ -489,7 +489,12 @@ namespace ARDOUR {
|
|||
};
|
||||
|
||||
enum SyncSource {
|
||||
JACK,
|
||||
/* These are "synonyms". It is important for JACK to be first
|
||||
both here and in enums.cc, so that the string "JACK" is
|
||||
correctly recognized in older session and preference files.
|
||||
*/
|
||||
JACK = 0,
|
||||
Engine = 0,
|
||||
MTC,
|
||||
MIDIClock,
|
||||
LTC
|
||||
|
|
@ -610,16 +615,6 @@ namespace ARDOUR {
|
|||
uint32_t max; //< samples
|
||||
};
|
||||
|
||||
/* PLATFORM SPECIFIC #ifdef's here */
|
||||
|
||||
/** Define the native thread type used on the platform */
|
||||
typedef pthread_t AudioBackendNativeThread;
|
||||
static inline bool self_thread_equal (AudioBackendNativeThread thr) {
|
||||
return pthread_equal (thr, pthread_self());
|
||||
}
|
||||
|
||||
/* PLATFORM SPECIFIC #endif's here */
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ AudioEngine::AudioEngine ()
|
|||
, _latency_flush_frames (0)
|
||||
, _latency_signal_latency (0)
|
||||
, _started_for_latency (false)
|
||||
, _in_destructor (false)
|
||||
{
|
||||
g_atomic_int_set (&m_meter_exit, 0);
|
||||
discover_backends ();
|
||||
|
|
@ -86,15 +87,9 @@ AudioEngine::AudioEngine ()
|
|||
|
||||
AudioEngine::~AudioEngine ()
|
||||
{
|
||||
_in_destructor = true;
|
||||
stop_metering_thread ();
|
||||
drop_backend ();
|
||||
|
||||
config_connection.disconnect ();
|
||||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock tm (_process_lock);
|
||||
session_removed.signal ();
|
||||
stop_metering_thread ();
|
||||
}
|
||||
}
|
||||
|
||||
AudioEngine*
|
||||
|
|
@ -477,6 +472,7 @@ AudioEngine::discover_backends ()
|
|||
|
||||
Glib::PatternSpec so_extension_pattern("*backend.so");
|
||||
Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
|
||||
Glib::PatternSpec dll_extension_pattern("*backend.dll");
|
||||
|
||||
find_matching_files_in_search_path (backend_search_path (),
|
||||
so_extension_pattern, backend_modules);
|
||||
|
|
@ -484,6 +480,9 @@ AudioEngine::discover_backends ()
|
|||
find_matching_files_in_search_path (backend_search_path (),
|
||||
dylib_extension_pattern, backend_modules);
|
||||
|
||||
find_matching_files_in_search_path (backend_search_path (),
|
||||
dll_extension_pattern, backend_modules);
|
||||
|
||||
DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
|
||||
|
||||
for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
|
||||
|
|
@ -824,21 +823,39 @@ AudioEngine::get_sync_offset (pframes_t& offset) const
|
|||
}
|
||||
|
||||
int
|
||||
AudioEngine::create_process_thread (boost::function<void()> func, AudioBackendNativeThread* thr, size_t stacksize)
|
||||
AudioEngine::create_process_thread (boost::function<void()> func)
|
||||
{
|
||||
if (!_backend) {
|
||||
return -1;
|
||||
}
|
||||
return _backend->create_process_thread (func, thr, stacksize);
|
||||
return _backend->create_process_thread (func);
|
||||
}
|
||||
|
||||
int
|
||||
AudioEngine::wait_for_process_thread_exit (AudioBackendNativeThread thr)
|
||||
AudioEngine::join_process_threads ()
|
||||
{
|
||||
if (!_backend) {
|
||||
return -1;
|
||||
}
|
||||
return _backend->join_process_threads ();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioEngine::in_process_thread ()
|
||||
{
|
||||
if (!_backend) {
|
||||
return false;
|
||||
}
|
||||
return _backend->in_process_thread ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AudioEngine::process_thread_count ()
|
||||
{
|
||||
if (!_backend) {
|
||||
return 0;
|
||||
}
|
||||
return _backend->wait_for_process_thread_exit (thr);
|
||||
return _backend->process_thread_count ();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -980,6 +997,11 @@ AudioEngine::update_latencies ()
|
|||
void
|
||||
AudioEngine::halted_callback (const char* why)
|
||||
{
|
||||
if (_in_destructor) {
|
||||
/* everything is under control */
|
||||
return;
|
||||
}
|
||||
|
||||
stop_metering_thread ();
|
||||
_running = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
|
||||
JACK_Slave::JACK_Slave (AudioEngine& e)
|
||||
Engine_Slave::Engine_Slave (AudioEngine& e)
|
||||
: engine (e)
|
||||
{
|
||||
double x;
|
||||
|
|
@ -35,24 +35,24 @@ JACK_Slave::JACK_Slave (AudioEngine& e)
|
|||
speed_and_position (x, p);
|
||||
}
|
||||
|
||||
JACK_Slave::~JACK_Slave ()
|
||||
Engine_Slave::~Engine_Slave ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
JACK_Slave::locked() const
|
||||
Engine_Slave::locked() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JACK_Slave::ok() const
|
||||
Engine_Slave::ok() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JACK_Slave::speed_and_position (double& sp, framepos_t& position)
|
||||
Engine_Slave::speed_and_position (double& sp, framepos_t& position)
|
||||
{
|
||||
switch (engine.transport_state()) {
|
||||
case TransportStopped:
|
||||
|
|
@ -336,6 +336,7 @@ setup_enum_writer ()
|
|||
|
||||
REGISTER_ENUM (MTC);
|
||||
REGISTER_ENUM (JACK);
|
||||
REGISTER_ENUM (Engine);
|
||||
REGISTER_ENUM (MIDIClock);
|
||||
REGISTER_ENUM (LTC);
|
||||
REGISTER (_SyncSource);
|
||||
|
|
|
|||
|
|
@ -366,9 +366,15 @@ ARDOUR::init_post_engine ()
|
|||
ARDOUR::PluginManager::instance().refresh ();
|
||||
}
|
||||
|
||||
int
|
||||
ARDOUR::cleanup ()
|
||||
void
|
||||
ARDOUR::cleanup ()
|
||||
{
|
||||
if (!libardour_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
ARDOUR::AudioEngine::destroy ();
|
||||
|
||||
delete Library;
|
||||
#ifdef HAVE_LRDF
|
||||
lrdf_cleanup ();
|
||||
|
|
@ -382,7 +388,8 @@ ARDOUR::cleanup ()
|
|||
vstfx_exit();
|
||||
#endif
|
||||
PBD::cleanup ();
|
||||
return 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -544,7 +551,11 @@ ARDOUR::get_available_sync_options ()
|
|||
{
|
||||
vector<SyncSource> ret;
|
||||
|
||||
ret.push_back (JACK);
|
||||
boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
|
||||
if (backend && backend->name() == "JACK") {
|
||||
ret.push_back (Engine);
|
||||
}
|
||||
|
||||
ret.push_back (MTC);
|
||||
ret.push_back (MIDIClock);
|
||||
ret.push_back (LTC);
|
||||
|
|
|
|||
|
|
@ -97,29 +97,24 @@ Graph::reset_thread_list ()
|
|||
number of threads.
|
||||
*/
|
||||
|
||||
if (_thread_list.size() == num_threads) {
|
||||
if (AudioEngine::instance()->process_thread_count() == num_threads) {
|
||||
return;
|
||||
}
|
||||
|
||||
Glib::Threads::Mutex::Lock lm (_session.engine().process_lock());
|
||||
AudioBackendNativeThread a_thread;
|
||||
|
||||
if (!_thread_list.empty()) {
|
||||
if (AudioEngine::instance()->process_thread_count() != 0) {
|
||||
drop_threads ();
|
||||
}
|
||||
|
||||
if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this), &a_thread, 100000) != 0) {
|
||||
if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this)) != 0) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
_thread_list.push_back (a_thread);
|
||||
|
||||
for (uint32_t i = 1; i < num_threads; ++i) {
|
||||
if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::helper_thread, this), &a_thread, 100000) != 0) {
|
||||
if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::helper_thread, this))) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
_thread_list.push_back (a_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,17 +136,15 @@ Graph::drop_threads ()
|
|||
{
|
||||
_quit_threads = true;
|
||||
|
||||
for (unsigned int i=0; i< _thread_list.size(); i++) {
|
||||
uint32_t thread_count = AudioEngine::instance()->process_thread_count ();
|
||||
|
||||
for (unsigned int i=0; i < thread_count; i++) {
|
||||
_execution_sem.signal ();
|
||||
}
|
||||
|
||||
_callback_start_sem.signal ();
|
||||
|
||||
for (list<AudioBackendNativeThread>::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) {
|
||||
AudioEngine::instance()->wait_for_process_thread_exit (*i);
|
||||
}
|
||||
|
||||
_thread_list.clear ();
|
||||
AudioEngine::instance()->join_process_threads ();
|
||||
|
||||
_execution_tokens = 0;
|
||||
|
||||
|
|
@ -584,10 +577,5 @@ Graph::process_one_route (Route* route)
|
|||
bool
|
||||
Graph::in_process_thread () const
|
||||
{
|
||||
for (list<AudioBackendNativeThread>::const_iterator i = _thread_list.begin (); i != _thread_list.end(); ++i) {
|
||||
if (self_thread_equal (*i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return AudioEngine::instance()->in_process_thread ();
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -276,6 +276,21 @@ Session::Session (AudioEngine &eng,
|
|||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
/* if a mix template was provided, then ::create() will
|
||||
* have copied it into the session and we need to load it
|
||||
* so that we have the state ready for ::set_state()
|
||||
* after the engine is started.
|
||||
*
|
||||
* Note that we do NOT try to get the sample rate from
|
||||
* the template at this time, though doing so would
|
||||
* be easy if we decided this was an appropriate part
|
||||
* of a template.
|
||||
*/
|
||||
|
||||
if (!mix_template.empty() && load_state (_current_snapshot_name)) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (load_state (_current_snapshot_name)) {
|
||||
|
|
@ -393,7 +408,7 @@ Session::immediately_post_engine ()
|
|||
|
||||
_engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
|
||||
|
||||
if (synced_to_jack()) {
|
||||
if (synced_to_engine()) {
|
||||
_engine.transport_stop ();
|
||||
}
|
||||
|
||||
|
|
@ -577,14 +592,21 @@ Session::setup_ltc ()
|
|||
void
|
||||
Session::setup_click ()
|
||||
{
|
||||
XMLNode* child = 0;
|
||||
|
||||
_clicking = false;
|
||||
_click_io.reset (new ClickIO (*this, "click"));
|
||||
_click_gain.reset (new Amp (*this));
|
||||
_click_gain->activate ();
|
||||
|
||||
if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
|
||||
if (state_tree) {
|
||||
setup_click_state (*state_tree->root());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::setup_click_state (const XMLNode& node)
|
||||
{
|
||||
const XMLNode* child = 0;
|
||||
|
||||
if ((child = find_named_node (node, "Click")) != 0) {
|
||||
|
||||
/* existing state for Click */
|
||||
int c = 0;
|
||||
|
|
@ -1406,7 +1428,7 @@ Session::audible_frame () const
|
|||
offset = current_block_size;
|
||||
}
|
||||
|
||||
if (synced_to_jack()) {
|
||||
if (synced_to_engine()) {
|
||||
tf = _engine.transport_frame();
|
||||
} else {
|
||||
tf = _transport_frame;
|
||||
|
|
|
|||
|
|
@ -494,9 +494,10 @@ Session::create (const string& session_template, BusProfile* bus_profile)
|
|||
ifstream in(in_path.c_str());
|
||||
|
||||
if (in) {
|
||||
string out_path = _path;
|
||||
out_path += _name;
|
||||
out_path += statefile_suffix;
|
||||
/* no need to call legalize_for_path() since the string
|
||||
* in session_template is already a legal path name
|
||||
*/
|
||||
string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
|
||||
|
||||
ofstream out(out_path.c_str());
|
||||
|
||||
|
|
@ -1317,13 +1318,7 @@ Session::set_state (const XMLNode& node, int version)
|
|||
if ((child = find_named_node (node, "Click")) == 0) {
|
||||
warning << _("Session: XML state has no click section") << endmsg;
|
||||
} else if (_click_io) {
|
||||
const XMLNodeList& children (child->children());
|
||||
XMLNodeList::const_iterator i = children.begin();
|
||||
_click_io->set_state (**i, version);
|
||||
++i;
|
||||
if (i != children.end()) {
|
||||
_click_gain->set_state (**i, version);
|
||||
}
|
||||
setup_click_state (node);
|
||||
}
|
||||
|
||||
if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
|
||||
|
|
@ -3781,3 +3776,68 @@ Session::rename (const std::string& new_name)
|
|||
|
||||
#undef RENAME
|
||||
}
|
||||
|
||||
int
|
||||
Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
|
||||
{
|
||||
if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tree.read (xmlpath)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
|
||||
{
|
||||
XMLTree tree;
|
||||
bool found_sr = false;
|
||||
bool found_data_format = false;
|
||||
|
||||
if (get_session_info_from_path (tree, xmlpath)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sample rate */
|
||||
|
||||
const XMLProperty* prop;
|
||||
if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {
|
||||
sample_rate = atoi (prop->value());
|
||||
found_sr = true;
|
||||
}
|
||||
|
||||
const XMLNodeList& children (tree.root()->children());
|
||||
for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
|
||||
const XMLNode* child = *c;
|
||||
if (child->name() == "Config") {
|
||||
const XMLNodeList& options (child->children());
|
||||
for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
|
||||
const XMLNode* option = *oc;
|
||||
const XMLProperty* name = option->property("name");
|
||||
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (name->value() == "native-file-data-format") {
|
||||
const XMLProperty* value = option->property ("value");
|
||||
if (value) {
|
||||
SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
|
||||
data_format = fmt;
|
||||
found_data_format = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_data_format) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !(found_sr && found_data_format); // zero if they are both found
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ Session::timecode_time (Timecode::Time &t)
|
|||
int
|
||||
Session::backend_sync_callback (TransportState state, framepos_t pos)
|
||||
{
|
||||
bool slave = synced_to_jack();
|
||||
bool slave = synced_to_engine();
|
||||
|
||||
switch (state) {
|
||||
case TransportStopped:
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ Session::request_sync_source (Slave* new_slave)
|
|||
|
||||
seamless = Config->get_seamless_loop ();
|
||||
|
||||
if (dynamic_cast<JACK_Slave*>(new_slave)) {
|
||||
if (dynamic_cast<Engine_Slave*>(new_slave)) {
|
||||
/* JACK cannot support seamless looping at present */
|
||||
Config->set_seamless_loop (false);
|
||||
} else {
|
||||
|
|
@ -514,13 +514,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
if (auto_return_enabled ||
|
||||
(ptw & PostTransportLocate) ||
|
||||
(_requested_return_frame >= 0) ||
|
||||
synced_to_jack()) {
|
||||
synced_to_engine()) {
|
||||
|
||||
if (pending_locate_flush) {
|
||||
flush_all_inserts ();
|
||||
}
|
||||
|
||||
if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
|
||||
if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
|
||||
!(ptw & PostTransportLocate)) {
|
||||
|
||||
/* no explicit locate queued */
|
||||
|
|
@ -543,7 +543,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
|
||||
/* don't try to handle loop play when synced to JACK */
|
||||
|
||||
if (!synced_to_jack()) {
|
||||
if (!synced_to_engine()) {
|
||||
|
||||
Location *location = _locations->auto_loop_location();
|
||||
|
||||
|
|
@ -734,7 +734,7 @@ Session::set_play_loop (bool yn)
|
|||
return;
|
||||
}
|
||||
|
||||
if (yn && Config->get_seamless_loop() && synced_to_jack()) {
|
||||
if (yn && Config->get_seamless_loop() && synced_to_engine()) {
|
||||
warning << string_compose (
|
||||
_("Seamless looping cannot be supported while %1 is using JACK transport.\n"
|
||||
"Recommend changing the configured options"), PROGRAM_NAME)
|
||||
|
|
@ -811,7 +811,7 @@ Session::flush_all_inserts ()
|
|||
void
|
||||
Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
|
||||
{
|
||||
if (synced_to_jack()) {
|
||||
if (synced_to_engine()) {
|
||||
|
||||
double sp;
|
||||
framepos_t pos;
|
||||
|
|
@ -926,7 +926,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
|
|||
|
||||
bool transport_was_stopped = !transport_rolling();
|
||||
|
||||
if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
|
||||
if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
|
||||
realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
|
||||
transport_was_stopped = true;
|
||||
} else {
|
||||
|
|
@ -1067,7 +1067,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a
|
|||
set_track_monitor_input_status (true);
|
||||
}
|
||||
|
||||
if (synced_to_jack ()) {
|
||||
if (synced_to_engine ()) {
|
||||
if (clear_state) {
|
||||
/* do this here because our response to the slave won't
|
||||
take care of it.
|
||||
|
|
@ -1090,7 +1090,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a
|
|||
set_track_monitor_input_status (false);
|
||||
}
|
||||
|
||||
if (synced_to_jack()) {
|
||||
if (synced_to_engine()) {
|
||||
_engine.transport_start ();
|
||||
} else {
|
||||
start_transport ();
|
||||
|
|
@ -1100,7 +1100,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a
|
|||
|
||||
/* not zero, not 1.0 ... varispeed */
|
||||
|
||||
if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
|
||||
if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
|
||||
warning << string_compose (
|
||||
_("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
|
||||
PROGRAM_NAME)
|
||||
|
|
@ -1429,8 +1429,8 @@ Session::switch_to_sync_source (SyncSource src)
|
|||
}
|
||||
break;
|
||||
|
||||
case JACK:
|
||||
if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
|
||||
case Engine:
|
||||
if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1438,7 +1438,7 @@ Session::switch_to_sync_source (SyncSource src)
|
|||
return;
|
||||
}
|
||||
|
||||
new_slave = new JACK_Slave (*AudioEngine::instance());
|
||||
new_slave = new Engine_Slave (*AudioEngine::instance());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1632,9 +1632,9 @@ bool
|
|||
Session::maybe_stop (framepos_t limit)
|
||||
{
|
||||
if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
|
||||
if (synced_to_jack () && config.get_jack_time_master ()) {
|
||||
if (synced_to_engine () && config.get_jack_time_master ()) {
|
||||
_engine.transport_stop ();
|
||||
} else if (!synced_to_jack ()) {
|
||||
} else if (!synced_to_engine ()) {
|
||||
stop_transport ();
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -397,12 +397,12 @@ string_to_sync_source (string str)
|
|||
}
|
||||
|
||||
if (str == _("JACK")) {
|
||||
return JACK;
|
||||
return Engine;
|
||||
}
|
||||
|
||||
fatal << string_compose (_("programming error: unknown sync source string \"%1\""), str) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return JACK;
|
||||
return Engine;
|
||||
}
|
||||
|
||||
/** @param sh Return a short version of the string */
|
||||
|
|
@ -410,7 +410,10 @@ const char*
|
|||
sync_source_to_string (SyncSource src, bool sh)
|
||||
{
|
||||
switch (src) {
|
||||
case JACK:
|
||||
case Engine:
|
||||
/* no other backends offer sync for now ... deal with this if we
|
||||
* ever have to.
|
||||
*/
|
||||
return _("JACK");
|
||||
|
||||
case MTC:
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ libardour_sources = [
|
|||
'diskstream.cc',
|
||||
'element_import_handler.cc',
|
||||
'element_importer.cc',
|
||||
'engine_slave.cc',
|
||||
'enums.cc',
|
||||
'event_type_map.cc',
|
||||
'export_channel.cc',
|
||||
|
|
@ -104,7 +105,6 @@ libardour_sources = [
|
|||
'interpolation.cc',
|
||||
'io.cc',
|
||||
'io_processor.cc',
|
||||
'jack_slave.cc',
|
||||
'kmeterdsp.cc',
|
||||
'ladspa_plugin.cc',
|
||||
'ladspa_search_path.cc',
|
||||
|
|
@ -182,7 +182,6 @@ libardour_sources = [
|
|||
'session_events.cc',
|
||||
'session_export.cc',
|
||||
'session_handle.cc',
|
||||
'session_jack.cc',
|
||||
'session_ltc.cc',
|
||||
'session_metadata.cc',
|
||||
'session_midi.cc',
|
||||
|
|
@ -246,8 +245,6 @@ def configure(conf):
|
|||
path_prefix + 'version.cc',
|
||||
'libardour3', conf.env['MAJOR'], conf.env['MINOR'], 0)
|
||||
autowaf.configure(conf)
|
||||
autowaf.check_pkg(conf, 'jack', uselib_store='JACK',
|
||||
atleast_version='0.118.2')
|
||||
if Options.options.dist_target == 'auto':
|
||||
if re.search ("linux", sys.platform) != None:
|
||||
autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA')
|
||||
|
|
@ -304,9 +301,6 @@ def configure(conf):
|
|||
conf.check(header_name='sys/vfs.h', define_name='HAVE_SYS_VFS_H',mandatory=False)
|
||||
conf.check(header_name='sys/statvfs.h', define_name='HAVE_SYS_STATVFS_H',mandatory=False)
|
||||
|
||||
conf.check(header_name='jack/session.h', uselib = [ 'JACK' ],
|
||||
define_name='HAVE_JACK_SESSION')
|
||||
|
||||
conf.check(header_name='unistd.h', define_name='HAVE_UNISTD',mandatory=False)
|
||||
|
||||
if flac_supported():
|
||||
|
|
@ -343,11 +337,11 @@ def build(bld):
|
|||
obj.name = 'ardour'
|
||||
obj.target = 'ardour'
|
||||
obj.uselib = ['GLIBMM','GTHREAD','AUBIO','SIGCPP','XML','UUID',
|
||||
'JACK', 'ALSA', 'SNDFILE','SAMPLERATE','LRDF',
|
||||
'AUDIOUNITS', 'OSX','BOOST','CURL','DL']
|
||||
'SNDFILE','SAMPLERATE','LRDF','AUDIOUNITS',
|
||||
'OSX','BOOST','CURL','DL']
|
||||
obj.use = ['libpbd','libmidipp','libevoral','libvamphost',
|
||||
'libvampplugin','libtaglib','librubberband',
|
||||
'libaudiographer','libltc']
|
||||
'libaudiographer','libltc','libtimecode']
|
||||
obj.vnum = LIBARDOUR_LIB_VERSION
|
||||
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
|
||||
obj.defines = [
|
||||
|
|
@ -410,7 +404,7 @@ def build(bld):
|
|||
testcommon.includes = obj.includes + ['test', '../pbd', '..']
|
||||
testcommon.source = ['test/test_globals.cc', 'test/testrunner.cc', 'test/test_needing_session.cc',
|
||||
'test/test_common.cc', 'test/dummy_lxvst.cc', 'test/audio_region_test.cc', 'test/test_util.cc']
|
||||
testcommon.uselib = ['CPPUNIT','SIGCPP','JACK','GLIBMM','GTHREAD',
|
||||
testcommon.uselib = ['CPPUNIT','SIGCPP','GLIBMM','GTHREAD',
|
||||
'SAMPLERATE','XML','LRDF','COREAUDIO']
|
||||
testcommon.use = ['libpbd','libmidipp','libevoral','libvamphost',
|
||||
'libvampplugin','libtaglib','librubberband',
|
||||
|
|
@ -488,7 +482,7 @@ def build(bld):
|
|||
|
||||
session_load_tester.includes = obj.includes
|
||||
session_load_tester.includes.append ('test')
|
||||
session_load_tester.uselib = ['CPPUNIT','SIGCPP','JACK','GLIBMM','GTHREAD',
|
||||
session_load_tester.uselib = ['CPPUNIT','SIGCPP','GLIBMM','GTHREAD',
|
||||
'SAMPLERATE','XML','LRDF','COREAUDIO']
|
||||
session_load_tester.use = ['libpbd','libmidipp','ardour']
|
||||
session_load_tester.name = 'libardour-session-load-tester'
|
||||
|
|
@ -523,7 +517,7 @@ def build(bld):
|
|||
|
||||
profilingobj.includes = obj.includes
|
||||
profilingobj.includes.append ('test')
|
||||
profilingobj.uselib = ['CPPUNIT','SIGCPP','JACK','GLIBMM','GTHREAD',
|
||||
profilingobj.uselib = ['CPPUNIT','SIGCPP','GLIBMM','GTHREAD',
|
||||
'SAMPLERATE','XML','LRDF','COREAUDIO']
|
||||
profilingobj.use = ['libpbd','libmidipp','ardour']
|
||||
profilingobj.name = 'libardour-profiling'
|
||||
|
|
@ -550,7 +544,7 @@ def create_ardour_test_program(bld, includes, name, target, sources):
|
|||
testobj = bld(features = 'cxx cxxprogram')
|
||||
testobj.includes = includes + ['test', '../pbd', '..']
|
||||
testobj.source = sources
|
||||
testobj.uselib = ['CPPUNIT','SIGCPP','JACK','GLIBMM','GTHREAD',
|
||||
testobj.uselib = ['CPPUNIT','SIGCPP','GLIBMM','GTHREAD',
|
||||
'SAMPLERATE','XML','LRDF','COREAUDIO']
|
||||
testobj.use = ['libpbd','libmidipp','libevoral','libvamphost',
|
||||
'libvampplugin','libtaglib','librubberband',
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ deinstantiate ()
|
|||
static bool
|
||||
already_configured ()
|
||||
{
|
||||
return JackConnection::server_running ();
|
||||
return !JackConnection::in_control ();
|
||||
}
|
||||
|
||||
static ARDOUR::AudioBackendInfo _descriptor = {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "jack_audiobackend.h"
|
||||
#include "jack_connection.h"
|
||||
#include "jack_utils.h"
|
||||
#include "jack_session.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ using namespace PBD;
|
|||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
|
||||
#define GET_PRIVATE_JACK_POINTER(localvar) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; }
|
||||
#define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; }
|
||||
|
||||
|
|
@ -63,6 +65,7 @@ JACKAudioBackend::JACKAudioBackend (AudioEngine& e, boost::shared_ptr<JackConnec
|
|||
, _target_systemic_output_latency (0)
|
||||
, _current_sample_rate (0)
|
||||
, _current_buffer_size (0)
|
||||
, _session (0)
|
||||
{
|
||||
_jack_connection->Connected.connect_same_thread (jack_connection_connection, boost::bind (&JACKAudioBackend::when_connected_to_jack, this));
|
||||
_jack_connection->Disconnected.connect_same_thread (disconnect_connection, boost::bind (&JACKAudioBackend::disconnected, this, _1));
|
||||
|
|
@ -513,7 +516,10 @@ JACKAudioBackend::start ()
|
|||
{
|
||||
if (!available()) {
|
||||
|
||||
if (!_jack_connection->server_running()) {
|
||||
if (_jack_connection->in_control()) {
|
||||
/* we will be starting JACK, so set up the
|
||||
command that JACK will use when it (auto-)starts
|
||||
*/
|
||||
setup_jack_startup_command ();
|
||||
}
|
||||
|
||||
|
|
@ -744,7 +750,8 @@ JACKAudioBackend::jack_timebase_callback (jack_transport_state_t state, pframes_
|
|||
ARDOUR::Session* session = engine.session();
|
||||
|
||||
if (session) {
|
||||
session->jack_timebase_callback (state, nframes, pos, new_position);
|
||||
JACKSession jsession (session);
|
||||
jsession.timebase_callback (state, nframes, pos, new_position);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -789,7 +796,6 @@ JACKAudioBackend::_xrun_callback (void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JACK_SESSION
|
||||
void
|
||||
JACKAudioBackend::_session_callback (jack_session_event_t *event, void *arg)
|
||||
{
|
||||
|
|
@ -797,10 +803,10 @@ JACKAudioBackend::_session_callback (jack_session_event_t *event, void *arg)
|
|||
ARDOUR::Session* session = jab->engine.session();
|
||||
|
||||
if (session) {
|
||||
session->jack_session_event (event);
|
||||
JACKSession jsession (session);
|
||||
jsession.session_event (event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
JACKAudioBackend::_freewheel_callback (int onoff, void *arg)
|
||||
|
|
@ -822,25 +828,72 @@ JACKAudioBackend::_latency_callback (jack_latency_callback_mode_t mode, void* ar
|
|||
}
|
||||
|
||||
int
|
||||
JACKAudioBackend::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
|
||||
JACKAudioBackend::create_process_thread (boost::function<void()> f)
|
||||
{
|
||||
GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
|
||||
ThreadData* td = new ThreadData (this, f, stacksize);
|
||||
|
||||
if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
|
||||
jack_native_thread_t thread_id;
|
||||
ThreadData* td = new ThreadData (this, f, thread_stack_size());
|
||||
|
||||
if (jack_client_create_thread (_priv_jack, &thread_id, jack_client_real_time_priority (_priv_jack),
|
||||
jack_is_realtime (_priv_jack), _start_process_thread, td)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
_jack_threads.push_back(thread_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
JACKAudioBackend::wait_for_process_thread_exit (AudioBackendNativeThread thr)
|
||||
JACKAudioBackend::join_process_threads ()
|
||||
{
|
||||
void* status;
|
||||
/* this doesn't actively try to stop the thread, it just waits till it exits */
|
||||
return pthread_join (thr, &status);
|
||||
GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
|
||||
|
||||
int ret = 0;
|
||||
|
||||
for (std::vector<jack_native_thread_t>::const_iterator i = _jack_threads.begin ();
|
||||
i != _jack_threads.end(); i++) {
|
||||
|
||||
#if defined(USING_JACK2_EXPANSION_OF_JACK_API) || defined(PLATFORM_WINDOWS)
|
||||
if (jack_client_stop_thread (_priv_jack, *i) != 0) {
|
||||
#else
|
||||
void* status;
|
||||
if (pthread_join (*i, &status) != 0) {
|
||||
#endif
|
||||
error << "AudioEngine: cannot stop process thread" << endmsg;
|
||||
ret += -1;
|
||||
}
|
||||
}
|
||||
|
||||
_jack_threads.clear();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
JACKAudioBackend::in_process_thread ()
|
||||
{
|
||||
for (std::vector<jack_native_thread_t>::const_iterator i = _jack_threads.begin ();
|
||||
i != _jack_threads.end(); i++) {
|
||||
|
||||
#ifdef COMPILER_MINGW
|
||||
if (*i == GetCurrentThread()) {
|
||||
return true;
|
||||
}
|
||||
#else // pthreads
|
||||
if (pthread_equal (*i, pthread_self()) != 0) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
JACKAudioBackend::process_thread_count ()
|
||||
{
|
||||
return _jack_threads.size();
|
||||
}
|
||||
|
||||
void*
|
||||
|
|
@ -960,6 +1013,7 @@ JACKAudioBackend::disconnected (const char* why)
|
|||
engine.halted_callback (why); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
JACKAudioBackend::cpu_load() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,15 +30,14 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <jack/jack.h>
|
||||
#ifdef HAVE_JACK_SESSION
|
||||
#include <jack/session.h>
|
||||
#endif
|
||||
|
||||
#include "ardour/audio_backend.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class JackConnection;
|
||||
class JACKSession;
|
||||
|
||||
class JACKAudioBackend : public AudioBackend {
|
||||
public:
|
||||
|
|
@ -103,8 +102,10 @@ class JACKAudioBackend : public AudioBackend {
|
|||
|
||||
size_t raw_buffer_size (DataType t);
|
||||
|
||||
int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize);
|
||||
int wait_for_process_thread_exit (AudioBackendNativeThread);
|
||||
int create_process_thread (boost::function<void()> func);
|
||||
int join_process_threads ();
|
||||
bool in_process_thread ();
|
||||
uint32_t process_thread_count ();
|
||||
|
||||
void transport_start ();
|
||||
void transport_stop ();
|
||||
|
|
@ -184,6 +185,8 @@ class JACKAudioBackend : public AudioBackend {
|
|||
bool _freewheeling;
|
||||
std::map<DataType,size_t> _raw_buffer_sizes;
|
||||
|
||||
std::vector<jack_native_thread_t> _jack_threads;
|
||||
|
||||
static int _xrun_callback (void *arg);
|
||||
static void* _process_thread (void *arg);
|
||||
static int _sample_rate_callback (pframes_t nframes, void *arg);
|
||||
|
|
@ -192,9 +195,7 @@ class JACKAudioBackend : public AudioBackend {
|
|||
static int _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
|
||||
static void _freewheel_callback (int , void *arg);
|
||||
static void _latency_callback (jack_latency_callback_mode_t, void*);
|
||||
#ifdef HAVE_JACK_SESSION
|
||||
static void _session_callback (jack_session_event_t *event, void *arg);
|
||||
#endif
|
||||
|
||||
void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
|
||||
int jack_sync_callback (jack_transport_state_t, jack_position_t*);
|
||||
|
|
@ -257,6 +258,12 @@ class JACKAudioBackend : public AudioBackend {
|
|||
|
||||
void when_connected_to_jack ();
|
||||
PBD::ScopedConnection jack_connection_connection;
|
||||
|
||||
/* Object to manage interactions with Session in a way that
|
||||
keeps JACK out of libardour directly
|
||||
*/
|
||||
|
||||
JACKSession* _session;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ using std::vector;
|
|||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
bool JackConnection::_in_control = false;
|
||||
|
||||
static void jack_halted_callback (void* arg)
|
||||
{
|
||||
JackConnection* jc = static_cast<JackConnection*> (arg);
|
||||
|
|
@ -54,17 +56,9 @@ JackConnection::JackConnection (const std::string& arg1, const std::string& arg2
|
|||
, _client_name (arg1)
|
||||
, session_uuid (arg2)
|
||||
{
|
||||
_in_control = !server_running();
|
||||
}
|
||||
/* See if the server is already up
|
||||
*/
|
||||
|
||||
JackConnection::~JackConnection ()
|
||||
{
|
||||
close ();
|
||||
}
|
||||
|
||||
bool
|
||||
JackConnection::server_running ()
|
||||
{
|
||||
EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
|
||||
boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
|
||||
|
||||
|
|
@ -83,10 +77,15 @@ JackConnection::server_running ()
|
|||
|
||||
if (status == 0) {
|
||||
jack_client_close (c);
|
||||
return true;
|
||||
_in_control = false;
|
||||
} else {
|
||||
_in_control = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
JackConnection::~JackConnection ()
|
||||
{
|
||||
close ();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -106,19 +105,6 @@ JackConnection::open ()
|
|||
global_epa->restore ();
|
||||
}
|
||||
|
||||
/* check to see if the server is already running so that we know if we
|
||||
* are starting it.
|
||||
*/
|
||||
|
||||
jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status);
|
||||
|
||||
if (status == 0) {
|
||||
_in_control = false;
|
||||
jack_client_close (c);
|
||||
} else {
|
||||
_in_control = true;
|
||||
}
|
||||
|
||||
/* ensure that PATH or equivalent includes likely locations of the JACK
|
||||
* server, in case the user's default does not.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,15 +27,13 @@ class JackConnection {
|
|||
void halted_callback ();
|
||||
void halted_info_callback (jack_status_t, const char*);
|
||||
|
||||
bool in_control() const { return _in_control; }
|
||||
static bool in_control() { return _in_control; }
|
||||
|
||||
static bool server_running();
|
||||
|
||||
private:
|
||||
jack_client_t* volatile _jack;
|
||||
std::string _client_name;
|
||||
std::string session_uuid;
|
||||
bool _in_control;
|
||||
static bool _in_control;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 1999-2013 Paul Davis
|
||||
Copyright (C) 2013 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -18,16 +18,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef WAF_BUILD
|
||||
#include "libardour-config.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <glibmm/miscutils.h>
|
||||
|
||||
#include "jack/jack.h"
|
||||
#include "jack/session.h"
|
||||
#include <jack/jack.h>
|
||||
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/filename_extensions.h"
|
||||
|
|
@ -35,12 +30,22 @@
|
|||
#include "ardour/session_directory.h"
|
||||
#include "ardour/tempo.h"
|
||||
|
||||
#include "jack_session.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using std::string;
|
||||
|
||||
#ifdef HAVE_JACK_SESSION
|
||||
JACKSession::JACKSession (Session* s)
|
||||
: SessionHandlePtr (s)
|
||||
{
|
||||
}
|
||||
|
||||
JACKSession::~JACKSession ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Session::jack_session_event (jack_session_event_t* event)
|
||||
JACKSession::session_event (jack_session_event_t* event)
|
||||
{
|
||||
char timebuf[128], *tmp;
|
||||
time_t n;
|
||||
|
|
@ -54,7 +59,7 @@ Session::jack_session_event (jack_session_event_t* event)
|
|||
|
||||
if (event->type == JackSessionSaveTemplate)
|
||||
{
|
||||
if (save_template( timebuf )) {
|
||||
if (_session->save_template( timebuf )) {
|
||||
event->flags = JackSessionSaveError;
|
||||
} else {
|
||||
string cmd ("ardour3 -P -U ");
|
||||
|
|
@ -67,10 +72,10 @@ Session::jack_session_event (jack_session_event_t* event)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (save_state (timebuf)) {
|
||||
if (_session->save_state (timebuf)) {
|
||||
event->flags = JackSessionSaveError;
|
||||
} else {
|
||||
std::string xml_path (_session_dir->root_path());
|
||||
std::string xml_path (_session->session_directory().root_path());
|
||||
std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
|
||||
xml_path = Glib::build_filename (xml_path, legalized_filename);
|
||||
|
||||
|
|
@ -95,66 +100,69 @@ Session::jack_session_event (jack_session_event_t* event)
|
|||
}
|
||||
|
||||
if (event->type == JackSessionSaveAndQuit) {
|
||||
Quit (); /* EMIT SIGNAL */
|
||||
_session->Quit (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
jack_session_event_free( event );
|
||||
jack_session_event_free (event);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Session::jack_timebase_callback (jack_transport_state_t /*state*/,
|
||||
JACKSession::timebase_callback (jack_transport_state_t /*state*/,
|
||||
pframes_t /*nframes*/,
|
||||
jack_position_t* pos,
|
||||
int /*new_position*/)
|
||||
{
|
||||
Timecode::BBT_Time bbt;
|
||||
TempoMap& tempo_map (_session->tempo_map());
|
||||
framepos_t tf = _session->transport_frame ();
|
||||
|
||||
/* BBT info */
|
||||
|
||||
if (_tempo_map) {
|
||||
|
||||
TempoMetric metric (_tempo_map->metric_at (_transport_frame));
|
||||
|
||||
try {
|
||||
_tempo_map->bbt_time_rt (_transport_frame, bbt);
|
||||
|
||||
pos->bar = bbt.bars;
|
||||
pos->beat = bbt.beats;
|
||||
pos->tick = bbt.ticks;
|
||||
|
||||
// XXX still need to set bar_start_tick
|
||||
|
||||
pos->beats_per_bar = metric.meter().divisions_per_bar();
|
||||
pos->beat_type = metric.meter().note_divisor();
|
||||
pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
|
||||
pos->beats_per_minute = metric.tempo().beats_per_minute();
|
||||
|
||||
pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
|
||||
|
||||
} catch (...) {
|
||||
/* no message */
|
||||
}
|
||||
TempoMetric metric (tempo_map.metric_at (tf));
|
||||
|
||||
try {
|
||||
tempo_map.bbt_time_rt (tf, bbt);
|
||||
|
||||
pos->bar = bbt.bars;
|
||||
pos->beat = bbt.beats;
|
||||
pos->tick = bbt.ticks;
|
||||
|
||||
// XXX still need to set bar_start_tick
|
||||
|
||||
pos->beats_per_bar = metric.meter().divisions_per_bar();
|
||||
pos->beat_type = metric.meter().note_divisor();
|
||||
pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
|
||||
pos->beats_per_minute = metric.tempo().beats_per_minute();
|
||||
|
||||
pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
|
||||
|
||||
} catch (...) {
|
||||
/* no message */
|
||||
}
|
||||
|
||||
#ifdef HAVE_JACK_VIDEO_SUPPORT
|
||||
//poke audio video ratio so Ardour can track Video Sync
|
||||
pos->audio_frames_per_video_frame = frame_rate() / timecode_frames_per_second();
|
||||
pos->audio_frames_per_video_frame = _session->frame_rate() / _session->timecode_frames_per_second();
|
||||
pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_JACK_TIMCODE_SUPPORT
|
||||
/* This is not yet defined in JACK */
|
||||
|
||||
/* Timecode info */
|
||||
|
||||
pos->timecode_offset = config.get_timecode_offset();
|
||||
t.timecode_frame_rate = timecode_frames_per_second();
|
||||
pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode;
|
||||
pos->timecode_offset = _session->config.get_timecode_offset();
|
||||
t.timecode_frame_rate = _session->timecode_frames_per_second();
|
||||
pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_JACK_LOOPING_SUPPORT
|
||||
/* This is not yet defined in JACK */
|
||||
if (_transport_speed) {
|
||||
|
||||
if (play_loop) {
|
||||
|
||||
Location* location = _locations.auto_loop_location();
|
||||
Location* location = _session->locations()->auto_loop_location();
|
||||
|
||||
if (location) {
|
||||
|
||||
47
libs/backends/jack/jack_session.h
Normal file
47
libs/backends/jack/jack_session.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright (C) 2013 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ardour_jack_audiobackend_jack_session_h__
|
||||
#define __ardour_jack_audiobackend_jack_session_h__
|
||||
|
||||
#include <jack/session.h>
|
||||
#include <jack/transport.h>
|
||||
|
||||
#include "ardour/types.h"
|
||||
#include "ardour/session_handle.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
|
||||
class JACKSession : public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
JACKSession (ARDOUR::Session* s);
|
||||
~JACKSession ();
|
||||
|
||||
void session_event (jack_session_event_t* event);
|
||||
void timebase_callback (jack_transport_state_t /*state*/,
|
||||
ARDOUR::pframes_t /*nframes*/,
|
||||
jack_position_t* pos,
|
||||
int /*new_position*/);
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
||||
#endif /* __ardour_jack_audiobackend_jack_session_h__ */
|
||||
|
|
@ -37,10 +37,10 @@ def build(bld):
|
|||
'jack_connection.cc',
|
||||
'jack_audiobackend.cc',
|
||||
'jack_portengine.cc',
|
||||
'jack_utils.cc'
|
||||
'jack_utils.cc',
|
||||
'jack_session.cc',
|
||||
]
|
||||
obj.includes = ['.']
|
||||
obj.cxxflags = [ '-fPIC' ]
|
||||
obj.name = 'jack_audiobackend'
|
||||
obj.target = 'jack_audiobackend'
|
||||
if Options.options.dist_target == 'mingw':
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ UI::UI (string namestr, int *argc, char ***argv)
|
|||
|
||||
UI::~UI ()
|
||||
{
|
||||
_receiver.hangup ();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
UI::caller_is_ui_thread ()
|
||||
{
|
||||
|
|
@ -265,12 +265,14 @@ UI::run (Receiver &old_receiver)
|
|||
|
||||
Glib::signal_idle().connect (bind_return (mem_fun (old_receiver, &Receiver::hangup), false));
|
||||
|
||||
starting ();
|
||||
if (starting ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_active = true;
|
||||
theMain->run ();
|
||||
_active = false;
|
||||
stopping ();
|
||||
_receiver.hangup ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,8 +156,7 @@ class UI : public AbstractUI<UIRequest>
|
|||
stopping just after we return from it (at the top level)
|
||||
*/
|
||||
|
||||
sigc::signal<void> starting;
|
||||
sigc::signal<void> stopping;
|
||||
virtual int starting() = 0;
|
||||
|
||||
sigc::signal<void> theme_changed;
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,12 @@ PBD::stacktrace (std::ostream& out, int levels)
|
|||
|
||||
#else
|
||||
|
||||
std::string
|
||||
PBD::demangle (std::string const & l)
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
void
|
||||
PBD::stacktrace (std::ostream& out, int /*levels*/)
|
||||
{
|
||||
|
|
|
|||
12
wscript
12
wscript
|
|
@ -57,7 +57,7 @@ def fetch_gcc_version (CC):
|
|||
return version
|
||||
|
||||
def fetch_git_revision ():
|
||||
cmd = "LANG= git describe --tags HEAD"
|
||||
cmd = "git describe --tags HEAD"
|
||||
output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines()
|
||||
rev = output[0].decode('utf-8')
|
||||
return rev
|
||||
|
|
@ -603,7 +603,12 @@ def configure(conf):
|
|||
if Options.options.boost_sp_debug:
|
||||
conf.env.append_value('CXXFLAGS', '-DBOOST_SP_ENABLE_DEBUG_HOOKS')
|
||||
|
||||
autowaf.check_header(conf, 'cxx', 'jack/session.h', define="JACK_SESSION", mandatory = False)
|
||||
conf.check_cxx(fragment = "#include <boost/version.hpp>\nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n",
|
||||
execute = "1",
|
||||
mandatory = True,
|
||||
msg = 'Checking for boost library >= 1.39',
|
||||
okmsg = 'ok',
|
||||
errmsg = 'too old\nPlease install boost version 1.39 or higher.')
|
||||
|
||||
autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.2')
|
||||
autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.2')
|
||||
|
|
@ -675,8 +680,6 @@ def configure(conf):
|
|||
else:
|
||||
conf.define('LXVST_SUPPORT', 1)
|
||||
conf.env['LXVST_SUPPORT'] = True
|
||||
if bool(conf.env['JACK_SESSION']):
|
||||
conf.define('HAVE_JACK_SESSION', 1)
|
||||
conf.define('WINDOWS_KEY', opts.windows_key)
|
||||
conf.env['PROGRAM_NAME'] = opts.program_name
|
||||
if opts.rt_alloc_debug:
|
||||
|
|
@ -738,7 +741,6 @@ const char* const ardour_config_info = "\\n\\
|
|||
write_config_text('FLAC', conf.is_defined('HAVE_FLAC'))
|
||||
write_config_text('FPU optimization', opts.fpu_optimization)
|
||||
write_config_text('Freedesktop files', opts.freedesktop)
|
||||
write_config_text('JACK session support', conf.is_defined('JACK_SESSION'))
|
||||
write_config_text('LV2 UI embedding', conf.is_defined('HAVE_SUIL'))
|
||||
write_config_text('LV2 support', conf.is_defined('LV2_SUPPORT'))
|
||||
write_config_text('LXVST support', conf.is_defined('LXVST_SUPPORT'))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue