mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
start work on the changes to EngineControl (dialog) to integrate with new backend design, and add "requires-driver" concept to AudioBackend to handle JACK specifically
This commit is contained in:
parent
333a3c9d02
commit
7218bd91de
10 changed files with 250 additions and 882 deletions
|
|
@ -17,6 +17,7 @@ export ARDOUR_DATA_PATH=$TOP:$TOP/build:$TOP/gtk2_ardour:$TOP/build/gtk2_ardour:
|
||||||
export ARDOUR_MIDIMAPS_PATH=$TOP/midi_maps:.
|
export ARDOUR_MIDIMAPS_PATH=$TOP/midi_maps:.
|
||||||
export ARDOUR_MCP_PATH=$TOP/mcp:.
|
export ARDOUR_MCP_PATH=$TOP/mcp:.
|
||||||
export ARDOUR_EXPORT_FORMATS_PATH=$TOP/export:.
|
export ARDOUR_EXPORT_FORMATS_PATH=$TOP/export:.
|
||||||
|
export ARDOUR_BACKEND_PATH=$TOP/build/libs/ardour
|
||||||
|
|
||||||
#
|
#
|
||||||
# even though we set the above variables, ardour requires that these
|
# even though we set the above variables, ardour requires that these
|
||||||
|
|
|
||||||
|
|
@ -397,7 +397,6 @@ ARDOUR_UI::attach_to_engine ()
|
||||||
engine->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
|
engine->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
|
||||||
|
|
||||||
engine->Halted.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::engine_halted, this, _1, false));
|
engine->Halted.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::engine_halted, this, _1, false));
|
||||||
engine->BackendAvailable.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::post_engine, this));
|
|
||||||
|
|
||||||
ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports);
|
ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -47,80 +47,67 @@ class EngineControl : public Gtk::VBox {
|
||||||
void set_state (const XMLNode&);
|
void set_state (const XMLNode&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gtk::Adjustment periods_adjustment;
|
/* core fields used by all backends */
|
||||||
Gtk::SpinButton periods_spinner;
|
|
||||||
Gtk::Adjustment ports_adjustment;
|
|
||||||
Gtk::SpinButton ports_spinner;
|
|
||||||
Gtk::Adjustment input_latency_adjustment;
|
|
||||||
Gtk::SpinButton input_latency;
|
|
||||||
Gtk::Adjustment output_latency_adjustment;
|
|
||||||
Gtk::SpinButton output_latency;
|
|
||||||
Gtk::Label latency_label;
|
|
||||||
|
|
||||||
Gtk::CheckButton realtime_button;
|
Gtk::ComboBoxText backend_combo;
|
||||||
Gtk::CheckButton no_memory_lock_button;
|
Gtk::ComboBoxText input_device_combo;
|
||||||
Gtk::CheckButton unlock_memory_button;
|
Gtk::ComboBoxText output_device_combo;
|
||||||
Gtk::CheckButton soft_mode_button;
|
Gtk::ComboBoxText sample_rate_combo;
|
||||||
Gtk::CheckButton monitor_button;
|
Gtk::ComboBoxText buffer_size_combo;
|
||||||
Gtk::CheckButton force16bit_button;
|
Gtk::Adjustment input_latency_adjustment;
|
||||||
Gtk::CheckButton hw_monitor_button;
|
Gtk::SpinButton input_latency;
|
||||||
Gtk::CheckButton hw_meter_button;
|
Gtk::Adjustment output_latency_adjustment;
|
||||||
Gtk::CheckButton verbose_output_button;
|
Gtk::SpinButton output_latency;
|
||||||
|
Gtk::Adjustment input_channels_adjustment;
|
||||||
|
Gtk::SpinButton input_channels;
|
||||||
|
Gtk::Adjustment output_channels_adjustment;
|
||||||
|
Gtk::SpinButton output_channels;
|
||||||
|
Gtk::Adjustment ports_adjustment;
|
||||||
|
Gtk::SpinButton ports_spinner;
|
||||||
|
Gtk::Label latency_label;
|
||||||
|
|
||||||
Gtk::Button start_button;
|
/* JACK specific */
|
||||||
Gtk::Button stop_button;
|
|
||||||
Gtk::HButtonBox button_box;
|
Gtk::CheckButton realtime_button;
|
||||||
|
Gtk::CheckButton no_memory_lock_button;
|
||||||
|
Gtk::CheckButton unlock_memory_button;
|
||||||
|
Gtk::CheckButton soft_mode_button;
|
||||||
|
Gtk::CheckButton monitor_button;
|
||||||
|
Gtk::CheckButton force16bit_button;
|
||||||
|
Gtk::CheckButton hw_monitor_button;
|
||||||
|
Gtk::CheckButton hw_meter_button;
|
||||||
|
Gtk::CheckButton verbose_output_button;
|
||||||
|
|
||||||
|
|
||||||
|
Gtk::ComboBoxText preset_combo;
|
||||||
|
Gtk::ComboBoxText serverpath_combo;
|
||||||
|
Gtk::ComboBoxText driver_combo;
|
||||||
|
Gtk::ComboBoxText interface_combo;
|
||||||
|
Gtk::ComboBoxText timeout_combo;
|
||||||
|
Gtk::ComboBoxText dither_mode_combo;
|
||||||
|
Gtk::ComboBoxText audio_mode_combo;
|
||||||
|
Gtk::ComboBoxText midi_driver_combo;
|
||||||
|
|
||||||
|
Gtk::Table basic_packer;
|
||||||
|
Gtk::Table options_packer;
|
||||||
|
Gtk::Table device_packer;
|
||||||
|
Gtk::HBox basic_hbox;
|
||||||
|
Gtk::HBox options_hbox;
|
||||||
|
Gtk::HBox device_hbox;
|
||||||
|
Gtk::Notebook notebook;
|
||||||
|
|
||||||
|
bool _used;
|
||||||
|
|
||||||
|
static bool engine_running ();
|
||||||
|
|
||||||
|
void driver_changed ();
|
||||||
|
void backend_changed ();
|
||||||
|
|
||||||
Gtk::ComboBoxText sample_rate_combo;
|
void redisplay_latency ();
|
||||||
Gtk::ComboBoxText period_size_combo;
|
uint32_t get_rate();
|
||||||
|
void audio_mode_changed ();
|
||||||
Gtk::ComboBoxText preset_combo;
|
void interface_changed ();
|
||||||
Gtk::ComboBoxText serverpath_combo;
|
void list_devices ();
|
||||||
Gtk::ComboBoxText driver_combo;
|
|
||||||
Gtk::ComboBoxText interface_combo;
|
|
||||||
Gtk::ComboBoxText timeout_combo;
|
|
||||||
Gtk::ComboBoxText dither_mode_combo;
|
|
||||||
Gtk::ComboBoxText audio_mode_combo;
|
|
||||||
Gtk::ComboBoxText input_device_combo;
|
|
||||||
Gtk::ComboBoxText output_device_combo;
|
|
||||||
Gtk::ComboBoxText midi_driver_combo;
|
|
||||||
|
|
||||||
Gtk::Table basic_packer;
|
|
||||||
Gtk::Table options_packer;
|
|
||||||
Gtk::Table device_packer;
|
|
||||||
Gtk::HBox basic_hbox;
|
|
||||||
Gtk::HBox options_hbox;
|
|
||||||
Gtk::HBox device_hbox;
|
|
||||||
Gtk::Notebook notebook;
|
|
||||||
|
|
||||||
bool _used;
|
|
||||||
|
|
||||||
static bool engine_running ();
|
|
||||||
|
|
||||||
void driver_changed ();
|
|
||||||
void build_command_line (std::vector<std::string>&);
|
|
||||||
|
|
||||||
std::map<std::string,std::vector<std::string> > devices;
|
|
||||||
std::vector<std::string> backend_devs;
|
|
||||||
void enumerate_devices (const std::string& driver);
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
std::vector<std::string> enumerate_coreaudio_devices ();
|
|
||||||
#else
|
|
||||||
std::vector<std::string> enumerate_alsa_devices ();
|
|
||||||
std::vector<std::string> enumerate_oss_devices ();
|
|
||||||
std::vector<std::string> enumerate_netjack_devices ();
|
|
||||||
std::vector<std::string> enumerate_freebob_devices ();
|
|
||||||
std::vector<std::string> enumerate_ffado_devices ();
|
|
||||||
std::vector<std::string> enumerate_dummy_devices ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void redisplay_latency ();
|
|
||||||
uint32_t get_rate();
|
|
||||||
void audio_mode_changed ();
|
|
||||||
std::vector<std::string> server_strings;
|
|
||||||
void find_jack_servers (std::vector<std::string>&);
|
|
||||||
std::string get_device_name (const std::string& driver, const std::string& human_readable_name);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __gtk2_ardour_engine_dialog_h__ */
|
#endif /* __gtk2_ardour_engine_dialog_h__ */
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,33 @@ class AudioBackend {
|
||||||
|
|
||||||
/* Discovering devices and parameters */
|
/* Discovering devices and parameters */
|
||||||
|
|
||||||
|
/** Return true if this backend requires the selection of a "driver"
|
||||||
|
* before any device can be selected. Return false otherwise.
|
||||||
|
*
|
||||||
|
* Intended mainly to differentiate between meta-APIs like JACK
|
||||||
|
* which can still expose different backends (such as ALSA or CoreAudio
|
||||||
|
* or FFADO or netjack) and those like ASIO or CoreAudio which
|
||||||
|
* do not.
|
||||||
|
*/
|
||||||
|
virtual bool requires_driver_selection() const { return false; }
|
||||||
|
|
||||||
|
/** If the return value of requires_driver_selection() is true,
|
||||||
|
* then this function can return the list of known driver names.
|
||||||
|
*
|
||||||
|
* If the return value of requires_driver_selection() is false,
|
||||||
|
* then this function should not be called. If it is called
|
||||||
|
* its return value is an empty vector of strings.
|
||||||
|
*/
|
||||||
|
virtual std::vector<std::string> enumerate_drivers() const { return std::vector<std::string>(); }
|
||||||
|
|
||||||
|
/** Returns zero if the backend can successfully use @param name as the
|
||||||
|
* driver, non-zero otherwise.
|
||||||
|
*
|
||||||
|
* Should not be used unless the backend returns true from
|
||||||
|
* requires_driver_selection()
|
||||||
|
*/
|
||||||
|
virtual int set_driver (const std::string& /*drivername*/) { return 0; }
|
||||||
|
|
||||||
/** Returns a collection of strings identifying devices known
|
/** Returns a collection of strings identifying devices known
|
||||||
* to this backend. Any of these strings may be used to identify a
|
* to this backend. Any of these strings may be used to identify a
|
||||||
* device in other calls to the backend, though any of them may become
|
* device in other calls to the backend, though any of them may become
|
||||||
|
|
@ -358,8 +385,8 @@ struct AudioBackendInfo {
|
||||||
* configured and does not need (re)configuration in order
|
* configured and does not need (re)configuration in order
|
||||||
* to be usable. Return false otherwise.
|
* to be usable. Return false otherwise.
|
||||||
*
|
*
|
||||||
* Note that this may return true if (re)configuration is possible,
|
* Note that this may return true if (re)configuration, even though
|
||||||
* but not required.
|
* not currently required, is still possible.
|
||||||
*/
|
*/
|
||||||
bool (*already_configured)();
|
bool (*already_configured)();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,8 @@ public:
|
||||||
int discover_backends();
|
int discover_backends();
|
||||||
std::vector<const AudioBackendInfo*> available_backends() const;
|
std::vector<const AudioBackendInfo*> available_backends() const;
|
||||||
std::string current_backend_name () const;
|
std::string current_backend_name () const;
|
||||||
int set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
|
boost::shared_ptr<AudioBackend> set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
|
||||||
|
boost::shared_ptr<AudioBackend> current_backend() const { return _backend; }
|
||||||
bool setup_required () const;
|
bool setup_required () const;
|
||||||
|
|
||||||
ProcessThread* main_thread() const { return _main_thread; }
|
ProcessThread* main_thread() const { return _main_thread; }
|
||||||
|
|
@ -172,13 +173,6 @@ public:
|
||||||
PBD::Signal0<void> Running;
|
PBD::Signal0<void> Running;
|
||||||
PBD::Signal0<void> Stopped;
|
PBD::Signal0<void> Stopped;
|
||||||
|
|
||||||
/* these two are emitted as we create backends that
|
|
||||||
can actually be used to do stuff (e.g. register ports)
|
|
||||||
*/
|
|
||||||
|
|
||||||
PBD::Signal0<void> BackendAvailable;
|
|
||||||
PBD::Signal0<void> BackendRemoved;
|
|
||||||
|
|
||||||
static AudioEngine* instance() { return _instance; }
|
static AudioEngine* instance() { return _instance; }
|
||||||
static void destroy();
|
static void destroy();
|
||||||
void died ();
|
void died ();
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,12 @@ class JACKAudioBackend : public AudioBackend {
|
||||||
bool connected() const;
|
bool connected() const;
|
||||||
bool is_realtime () const;
|
bool is_realtime () const;
|
||||||
|
|
||||||
|
bool requires_driver_selection() const;
|
||||||
|
std::vector<std::string> enumerate_drivers () const;
|
||||||
|
int set_driver (const std::string&);
|
||||||
|
|
||||||
std::vector<std::string> enumerate_devices () const;
|
std::vector<std::string> enumerate_devices () const;
|
||||||
|
|
||||||
std::vector<float> available_sample_rates (const std::string& device) const;
|
std::vector<float> available_sample_rates (const std::string& device) const;
|
||||||
std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
|
std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
|
||||||
uint32_t available_input_channel_count (const std::string& device) const;
|
uint32_t available_input_channel_count (const std::string& device) const;
|
||||||
|
|
@ -151,6 +156,7 @@ class JACKAudioBackend : public AudioBackend {
|
||||||
|
|
||||||
/* pffooo */
|
/* pffooo */
|
||||||
|
|
||||||
|
std::string _target_driver;
|
||||||
std::string _target_device;
|
std::string _target_device;
|
||||||
float _target_sample_rate;
|
float _target_sample_rate;
|
||||||
uint32_t _target_buffer_size;
|
uint32_t _target_buffer_size;
|
||||||
|
|
|
||||||
|
|
@ -561,18 +561,16 @@ AudioEngine::drop_backend ()
|
||||||
if (_backend) {
|
if (_backend) {
|
||||||
_backend->stop ();
|
_backend->stop ();
|
||||||
_backend.reset ();
|
_backend.reset ();
|
||||||
|
|
||||||
BackendRemoved(); /* EMIT SIGNAL */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
boost::shared_ptr<AudioBackend>
|
||||||
AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
|
AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
|
||||||
{
|
{
|
||||||
BackendMap::iterator b = _backends.find (name);
|
BackendMap::iterator b = _backends.find (name);
|
||||||
|
|
||||||
if (b == _backends.end()) {
|
if (b == _backends.end()) {
|
||||||
return -1;
|
return boost::shared_ptr<AudioBackend>();
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_backend ();
|
drop_backend ();
|
||||||
|
|
@ -590,12 +588,10 @@ AudioEngine::set_backend (const std::string& name, const std::string& arg1, cons
|
||||||
|
|
||||||
} catch (exception& e) {
|
} catch (exception& e) {
|
||||||
error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
|
error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
|
||||||
return -1;
|
return boost::shared_ptr<AudioBackend>();
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendAvailable (); /* EMIT SIGNAL */
|
return _backend;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BACKEND PROXY WRAPPERS */
|
/* BACKEND PROXY WRAPPERS */
|
||||||
|
|
|
||||||
|
|
@ -90,16 +90,13 @@ extern "C" {
|
||||||
* must be non-mangled.
|
* must be non-mangled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using namespace ARDOUR;
|
ARDOUR::AudioBackendInfo descriptor = {
|
||||||
|
|
||||||
AudioBackendInfo descriptor = {
|
|
||||||
"JACK",
|
"JACK",
|
||||||
instantiate,
|
instantiate,
|
||||||
deinstantiate,
|
deinstantiate,
|
||||||
backend_factory,
|
backend_factory,
|
||||||
portengine_factory,
|
portengine_factory,
|
||||||
already_configured
|
already_configured,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,11 +88,31 @@ JACKAudioBackend::is_realtime () const
|
||||||
return jack_is_realtime (_priv_jack);
|
return jack_is_realtime (_priv_jack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JACKAudioBackend::requires_driver_selection() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string>
|
||||||
|
JACKAudioBackend::enumerate_drivers () const
|
||||||
|
{
|
||||||
|
vector<string> s;
|
||||||
|
get_jack_audio_driver_names (s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
JACKAudioBackend::set_driver (const std::string& name)
|
||||||
|
{
|
||||||
|
_target_driver = name;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
vector<string>
|
vector<string>
|
||||||
JACKAudioBackend::enumerate_devices () const
|
JACKAudioBackend::enumerate_devices () const
|
||||||
{
|
{
|
||||||
vector<string> devices;
|
return get_jack_device_names_for_audio_driver (_target_driver);
|
||||||
return devices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<float>
|
vector<float>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue