mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-21 06:06:25 +01:00
Switch to internal time code when MTC input is switched to off, disabling MTC timecode source when not MTC input is set. Fixed Bug when it was impossible to switch to internal timecode source when transport was started with MTC.
1862 lines
62 KiB
C++
1862 lines
62 KiB
C++
/*
|
|
Copyright (C) 2014 Waves Audio Ltd.
|
|
|
|
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.
|
|
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string>
|
|
#include <stdio.h>
|
|
|
|
#include "tracks_control_panel.h"
|
|
#include "waves_button.h"
|
|
#include "pbd/unwind.h"
|
|
|
|
#include <gtkmm2ext/utils.h>
|
|
|
|
#include "ardour/types.h"
|
|
#include "ardour/engine_state_controller.h"
|
|
#include "ardour/rc_configuration.h"
|
|
#include "ardour/recent_sessions.h"
|
|
#include "ardour/filename_extensions.h"
|
|
|
|
#include "ardour/utils.h"
|
|
#include "ardour_ui.h"
|
|
#include "gui_thread.h"
|
|
#include "utils.h"
|
|
#include "i18n.h"
|
|
#include "pbd/convert.h"
|
|
|
|
#include "timecode/time.h"
|
|
#include "time.h"
|
|
|
|
#include "open_file_dialog_proxy.h"
|
|
#include "yes_no_dialog.h"
|
|
#include "ok_dialog.h"
|
|
|
|
using namespace ARDOUR;
|
|
using namespace Gtk;
|
|
using namespace Gtkmm2ext;
|
|
using namespace PBD;
|
|
using namespace Glib;
|
|
using namespace Timecode;
|
|
|
|
#define dbg_msg(a) MessageDialog (a, PROGRAM_NAME).run();
|
|
|
|
namespace {
|
|
|
|
static const char* audio_capture_name_prefix = "system:capture:";
|
|
static const char* audio_playback_name_prefix = "system:playback:";
|
|
static const char* midi_port_name_prefix = "system_midi:";
|
|
static const char* midi_capture_suffix = " capture";
|
|
static const char* midi_playback_suffix = " playback";
|
|
|
|
struct MidiDeviceDescriptor {
|
|
std::string name;
|
|
std::string capture_name;
|
|
bool capture_active;
|
|
std::string playback_name;
|
|
bool playback_active;
|
|
|
|
MidiDeviceDescriptor(const std::string& name) :
|
|
name(name),
|
|
capture_name(""),
|
|
capture_active(false),
|
|
playback_name(""),
|
|
playback_active(false)
|
|
{}
|
|
|
|
bool operator==(const MidiDeviceDescriptor& rhs) {
|
|
return name == rhs.name;
|
|
}
|
|
};
|
|
|
|
typedef std::vector<MidiDeviceDescriptor> MidiDeviceDescriptorVec;
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::init ()
|
|
{
|
|
_ok_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_ok));
|
|
_cancel_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_cancel));
|
|
_apply_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_apply));
|
|
|
|
_audio_settings_tab_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_a_settings_tab_button_clicked));
|
|
_midi_settings_tab_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_a_settings_tab_button_clicked));
|
|
_session_settings_tab_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_a_settings_tab_button_clicked));
|
|
_general_settings_tab_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_a_settings_tab_button_clicked));
|
|
|
|
_all_inputs_on_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_all_inputs_on_button));
|
|
_all_inputs_off_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_all_inputs_off_button));
|
|
_all_outputs_on_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_all_outputs_on_button));
|
|
_all_outputs_off_button.signal_clicked.connect (sigc::mem_fun (*this, &TracksControlPanel::on_all_outputs_off_button));
|
|
|
|
_multi_out_button.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_multi_out));
|
|
_stereo_out_button.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_stereo_out));
|
|
|
|
_browse_button.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_browse_button));
|
|
|
|
EngineStateController::instance ()->EngineRunning.connect (running_connection, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::engine_running, this), gui_context());
|
|
EngineStateController::instance ()->EngineStopped.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::engine_stopped, this), gui_context());
|
|
EngineStateController::instance ()->EngineHalted.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::engine_stopped, this), gui_context());
|
|
|
|
/* Subscribe for udpates from EngineStateController */
|
|
EngineStateController::instance()->PortRegistrationChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_port_registration_update, this), gui_context());
|
|
EngineStateController::instance()->BufferSizeChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_buffer_size_update, this), gui_context());
|
|
EngineStateController::instance()->DeviceListChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_device_list_update, this, _1), gui_context());
|
|
EngineStateController::instance()->InputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_audio_input_configuration_changed, this), gui_context());
|
|
EngineStateController::instance()->OutputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_audio_output_configuration_changed, this), gui_context());
|
|
EngineStateController::instance()->MIDIInputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_midi_input_configuration_changed, this), gui_context());
|
|
EngineStateController::instance()->MIDIOutputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_midi_output_configuration_changed, this), gui_context());
|
|
EngineStateController::instance()->MTCInputChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_mtc_input_changed, this, _1), gui_context());
|
|
EngineStateController::instance()->DeviceError.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_device_error, this), gui_context());
|
|
|
|
/* Global configuration parameters update */
|
|
Config->ParameterChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_parameter_changed, this, _1), gui_context());
|
|
|
|
_engine_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_engine_dropdown_item_clicked));
|
|
_device_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_device_dropdown_item_clicked));
|
|
_sample_rate_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_sample_rate_dropdown_item_clicked));
|
|
_buffer_size_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_buffer_size_dropdown_item_clicked));
|
|
_mtc_in_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_mtc_input_chosen));
|
|
|
|
/* Session configuration parameters update */
|
|
_file_type_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_file_type_dropdown_item_clicked));
|
|
_bit_depth_dropdown.selected_item_changed.connect (sigc::mem_fun(*this, &TracksControlPanel::on_bit_depth_dropdown_item_clicked));
|
|
_frame_rate_dropdown.selected_item_changed.connect (sigc::mem_fun (*this, &TracksControlPanel::on_frame_rate_item_clicked));
|
|
|
|
_name_tracks_after_driver.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_name_tracks_after_driver));
|
|
_reset_tracks_name_to_default.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_reset_tracks_name_to_default));
|
|
|
|
_control_panel_button.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_control_panel_button));
|
|
|
|
_yes_button.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_yes_button));
|
|
_no_button.signal_clicked.connect(sigc::mem_fun (*this, &TracksControlPanel::on_no_button));
|
|
_yes_button.set_visible(false);
|
|
_no_button.set_visible(false);
|
|
|
|
populate_engine_dropdown ();
|
|
populate_device_dropdown ();
|
|
|
|
populate_mtc_in_dropdown ();
|
|
|
|
populate_output_mode ();
|
|
|
|
populate_file_type_dropdown ();
|
|
populate_input_channels ();
|
|
populate_output_channels ();
|
|
populate_midi_ports ();
|
|
populate_default_session_path ();
|
|
|
|
// Init session Settings
|
|
populate_bit_depth_dropdown();
|
|
populate_frame_rate_dropdown();
|
|
populate_auto_lock_timer_dropdown();
|
|
populate_auto_save_timer_dropdown();
|
|
populate_pre_record_buffer_dropdown();
|
|
|
|
_audio_settings_tab_button.set_active(true);
|
|
|
|
display_general_preferences ();
|
|
}
|
|
|
|
DeviceConnectionControl& TracksControlPanel::add_device_capture_control(std::string port_name, bool active, uint16_t capture_number, std::string track_name)
|
|
{
|
|
std::string device_capture_name("");
|
|
std::string pattern(audio_capture_name_prefix);
|
|
ARDOUR::remove_pattern_from_string(port_name, pattern, device_capture_name);
|
|
|
|
DeviceConnectionControl &capture_control = *manage (new DeviceConnectionControl(device_capture_name, active, capture_number, track_name));
|
|
|
|
char * id_str = new char [port_name.length()+1];
|
|
std::strcpy (id_str, port_name.c_str());
|
|
capture_control.set_data(DeviceConnectionControl::id_name, id_str);
|
|
|
|
_device_capture_list.pack_start (capture_control, false, false);
|
|
capture_control.signal_active_changed.connect (sigc::mem_fun (*this, &TracksControlPanel::on_capture_active_changed));
|
|
return capture_control;
|
|
}
|
|
|
|
DeviceConnectionControl& TracksControlPanel::add_device_playback_control(std::string port_name, bool active, uint16_t playback_number)
|
|
{
|
|
std::string device_playback_name("");
|
|
std::string pattern(audio_playback_name_prefix);
|
|
ARDOUR::remove_pattern_from_string(port_name, pattern, device_playback_name);
|
|
|
|
DeviceConnectionControl &playback_control = *manage (new DeviceConnectionControl(device_playback_name, active, playback_number));
|
|
|
|
char * id_str = new char [port_name.length()+1];
|
|
std::strcpy (id_str, port_name.c_str());
|
|
playback_control.set_data(DeviceConnectionControl::id_name, id_str);
|
|
|
|
_device_playback_list.pack_start (playback_control, false, false);
|
|
playback_control.signal_active_changed.connect(sigc::mem_fun (*this, &TracksControlPanel::on_playback_active_changed));
|
|
return playback_control;
|
|
}
|
|
|
|
MidiDeviceConnectionControl& TracksControlPanel::add_midi_device_control(const std::string& midi_device_name,
|
|
const std::string& capture_name, bool capture_active,
|
|
const std::string& playback_name, bool playback_active)
|
|
{
|
|
MidiDeviceConnectionControl &midi_device_control = *manage (new MidiDeviceConnectionControl(midi_device_name, !capture_name.empty(), capture_active, !playback_name.empty(), playback_active));
|
|
|
|
if (!capture_name.empty()) {
|
|
char * capture_id_str = new char [capture_name.length()+1];
|
|
std::strcpy (capture_id_str, capture_name.c_str());
|
|
midi_device_control.set_data(MidiDeviceConnectionControl::capture_id_name, capture_id_str);
|
|
}
|
|
|
|
if (!playback_name.empty()) {
|
|
char * playback_id_str = new char [playback_name.length()+1];
|
|
std::strcpy (playback_id_str, playback_name.c_str());
|
|
midi_device_control.set_data(MidiDeviceConnectionControl::playback_id_name, playback_id_str);
|
|
}
|
|
|
|
_midi_device_list.pack_start (midi_device_control, false, false);
|
|
midi_device_control.signal_capture_active_changed.connect (sigc::mem_fun (*this, &TracksControlPanel::on_midi_capture_active_changed));
|
|
midi_device_control.signal_playback_active_changed.connect(sigc::mem_fun (*this, &TracksControlPanel::on_midi_playback_active_changed));
|
|
return midi_device_control;
|
|
}
|
|
|
|
namespace {
|
|
// Strings which are shown to user in the Preference panel
|
|
const std::string string_CAF = "Caf";
|
|
const std::string string_BWav = "BWav";
|
|
const std::string string_Aiff = "Aiff";
|
|
const std::string string_Wav64 = "Wave64";
|
|
|
|
std::string
|
|
HeaderFormat_to_string(HeaderFormat header_format)
|
|
{
|
|
switch (header_format) {
|
|
case CAF:
|
|
return string_CAF;
|
|
case BWF:
|
|
return string_BWav;
|
|
case AIFF:
|
|
return string_Aiff;
|
|
case WAVE64:
|
|
return string_Wav64;
|
|
default:
|
|
return std::string("");
|
|
}
|
|
|
|
return std::string("");
|
|
}
|
|
|
|
HeaderFormat
|
|
string_to_HeaderFormat(std::string s)
|
|
{
|
|
if(s == string_CAF)
|
|
return CAF;
|
|
|
|
if(s == string_BWav)
|
|
return BWF;
|
|
|
|
if(s == string_Aiff)
|
|
return AIFF;
|
|
|
|
if(s == string_Wav64)
|
|
return WAVE64;
|
|
|
|
//defaul value
|
|
return BWF;
|
|
}
|
|
|
|
std::string
|
|
xml_string_to_user_string(std::string xml_string);
|
|
|
|
enum SessionProperty {
|
|
Native_File_Header_Format,
|
|
Native_File_Data_Format,
|
|
Timecode_Format
|
|
};
|
|
|
|
std::string
|
|
read_property_from_last_session(SessionProperty session_property)
|
|
{
|
|
ARDOUR::RecentSessions rs;
|
|
ARDOUR::read_recent_sessions (rs);
|
|
|
|
if( rs.size() > 0 )
|
|
{
|
|
std::string full_session_name = Glib::build_filename( rs[0].second, rs[0].first );
|
|
full_session_name += statefile_suffix;
|
|
|
|
// read property from session projectfile
|
|
boost::shared_ptr<XMLTree> state_tree(new XMLTree());
|
|
|
|
if (!state_tree->read (full_session_name))
|
|
return std::string("");
|
|
|
|
XMLNode& root (*state_tree->root());
|
|
|
|
if (root.name() != X_("Session"))
|
|
return std::string("");
|
|
|
|
XMLNode* config_main_node = root.child ("Config");
|
|
if( !config_main_node )
|
|
return std::string("");
|
|
|
|
XMLNodeList config_nodes_list = config_main_node->children();
|
|
XMLNodeConstIterator config_node_iter = config_nodes_list.begin();
|
|
|
|
std::string required_property_name;
|
|
|
|
switch (session_property) {
|
|
case Native_File_Header_Format:
|
|
required_property_name = "native-file-header-format";
|
|
break;
|
|
case Native_File_Data_Format:
|
|
required_property_name = "native-file-data-format";
|
|
break;
|
|
case Timecode_Format:
|
|
required_property_name = "timecode-format";
|
|
break;
|
|
default:
|
|
return std::string("");
|
|
}
|
|
|
|
for (; config_node_iter != config_nodes_list.end(); ++config_node_iter)
|
|
{
|
|
XMLNode* config_node = *config_node_iter;
|
|
XMLProperty* prop = NULL;
|
|
|
|
if ( (prop = config_node->property ("name")) != 0 )
|
|
if( prop->value() == required_property_name )
|
|
if ( (prop = config_node->property ("value")) != 0 )
|
|
return xml_string_to_user_string( prop->value() );
|
|
}
|
|
}
|
|
|
|
return std::string("");
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
// Strings which are shown to user in the Preference panel
|
|
const std::string string_bit32 = "32 bit floating point";
|
|
const std::string string_bit24 = "24 bit";
|
|
const std::string string_bit16 = "16 bit";
|
|
|
|
std::string
|
|
SampleFormat_to_string(SampleFormat sample_format)
|
|
{
|
|
switch (sample_format) {
|
|
case FormatFloat:
|
|
return string_bit32;
|
|
case FormatInt24:
|
|
return string_bit24;
|
|
case FormatInt16:
|
|
return string_bit16;
|
|
}
|
|
|
|
return std::string("");
|
|
}
|
|
|
|
SampleFormat
|
|
string_to_SampleFormat(std::string s)
|
|
{
|
|
if(s == string_bit32)
|
|
return FormatFloat;
|
|
|
|
if(s == string_bit24)
|
|
return FormatInt24;
|
|
|
|
if(s == string_bit16)
|
|
return FormatInt16;
|
|
|
|
// default value
|
|
return FormatInt24;
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_bit_depth_dropdown()
|
|
{
|
|
// Get BIT_DEPTH from last used session
|
|
std::string sample_format_string = read_property_from_last_session(Native_File_Data_Format);
|
|
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
SampleFormat sample_format = string_to_SampleFormat(sample_format_string);
|
|
ardour_ui->set_sample_format( sample_format );
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_bit_depth_dropdown.set_text ( SampleFormat_to_string(sample_format) );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
namespace {
|
|
const std::string string_24fps = "24 fps";
|
|
const std::string string_25fps = "25 fps";
|
|
const std::string string_30fps = "30 fps";
|
|
const std::string string_23976fps = "23.976 fps";
|
|
const std::string string_2997fps = "29.97 fps";
|
|
|
|
std::string
|
|
TimecodeFormat_to_string(Timecode::TimecodeFormat timecode_format)
|
|
{
|
|
|
|
switch (timecode_format) {
|
|
case timecode_24:
|
|
return string_24fps;
|
|
case timecode_25:
|
|
return string_25fps;
|
|
case timecode_30:
|
|
return string_30fps;
|
|
case timecode_23976:
|
|
return string_23976fps;
|
|
case timecode_2997:
|
|
return string_2997fps;
|
|
|
|
default:
|
|
return std::string("");
|
|
}
|
|
|
|
return std::string("");
|
|
}
|
|
|
|
Timecode::TimecodeFormat
|
|
string_to_TimecodeFormat(std::string s)
|
|
{
|
|
if(s == string_24fps)
|
|
return timecode_24;
|
|
if(s == string_25fps)
|
|
return timecode_25;
|
|
if(s == string_30fps)
|
|
return timecode_30;
|
|
if(s == string_23976fps)
|
|
return timecode_23976;
|
|
if(s == string_2997fps)
|
|
return timecode_2997;
|
|
|
|
//defaul value
|
|
return timecode_25;
|
|
}
|
|
|
|
std::string
|
|
xml_string_to_user_string(std::string xml_string)
|
|
{
|
|
// Bit depth format
|
|
if(xml_string == enum_2_string (FormatFloat))
|
|
return string_bit32;
|
|
|
|
if(xml_string == enum_2_string (FormatInt24))
|
|
return string_bit24;
|
|
|
|
if(xml_string == enum_2_string (FormatInt16))
|
|
return string_bit16;
|
|
|
|
|
|
// Header format (File type)
|
|
if(xml_string == enum_2_string(CAF))
|
|
return string_CAF;
|
|
|
|
if(xml_string == enum_2_string(BWF))
|
|
return string_BWav;
|
|
|
|
if(xml_string == enum_2_string(AIFF))
|
|
return string_Aiff;
|
|
|
|
if(xml_string == enum_2_string(WAVE64))
|
|
return string_Wav64;
|
|
|
|
// fps (Timecode)
|
|
if(xml_string == enum_2_string(Timecode::timecode_24))
|
|
return string_24fps;
|
|
|
|
if(xml_string == enum_2_string(Timecode::timecode_25))
|
|
return string_25fps;
|
|
|
|
if(xml_string == enum_2_string(Timecode::timecode_30))
|
|
return string_30fps;
|
|
|
|
if(xml_string == enum_2_string(Timecode::timecode_23976))
|
|
return string_23976fps;
|
|
|
|
if(xml_string == enum_2_string(Timecode::timecode_2997))
|
|
return string_2997fps;
|
|
|
|
return std::string("");
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_frame_rate_dropdown()
|
|
{
|
|
// Get FRAME_RATE from last used session
|
|
std::string last_used_frame_rate = read_property_from_last_session(Timecode_Format);
|
|
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
Timecode::TimecodeFormat timecode_format = string_to_TimecodeFormat(last_used_frame_rate);
|
|
ardour_ui->set_timecode_format( timecode_format );
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_frame_rate_dropdown.set_text ( TimecodeFormat_to_string(timecode_format) );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_auto_lock_timer_dropdown()
|
|
{
|
|
int time = ARDOUR_UI::config()->get_auto_lock_timer();
|
|
std::stringstream ss;
|
|
ss << time;
|
|
std::string str_time = ss.str() + " Min";
|
|
|
|
_auto_lock_timer_dropdown.set_text( str_time );
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_auto_save_timer_dropdown()
|
|
{
|
|
int time = ARDOUR_UI::config()->get_auto_save_timer();
|
|
std::stringstream ss;
|
|
ss << time;
|
|
std::string str_time = ss.str() + " Min";
|
|
|
|
_auto_save_timer_dropdown.set_text( str_time );
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_pre_record_buffer_dropdown()
|
|
{
|
|
int time = ARDOUR_UI::config()->get_pre_record_buffer();
|
|
std::stringstream ss;
|
|
ss << time;
|
|
std::string str_time = ss.str() + " Min";
|
|
|
|
_pre_record_buffer_dropdown.set_text( str_time );
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::refresh_session_settings_info()
|
|
{
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
if( !ardour_ui )
|
|
return;
|
|
|
|
Session* session = ardour_ui->the_session();
|
|
if( !session )
|
|
return;
|
|
_bit_depth_dropdown.set_text( SampleFormat_to_string(session->config.get_native_file_data_format()) );
|
|
_file_type_dropdown.set_text( HeaderFormat_to_string(session->config.get_native_file_header_format()) );
|
|
_frame_rate_dropdown.set_text( TimecodeFormat_to_string(session->config.get_timecode_format()) );
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_default_session_path()
|
|
{
|
|
std::string std_path = Config->get_default_session_parent_dir();
|
|
bool folderExist = Glib::file_test(std_path, FILE_TEST_EXISTS);
|
|
|
|
if ( !folderExist )
|
|
Config->set_default_session_parent_dir(Glib::get_home_dir());
|
|
|
|
_default_open_path.set_text(Config->get_default_session_parent_dir());
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_engine_dropdown()
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::vector<const AudioBackendInfo*> backends;
|
|
EngineStateController::instance()->available_backends(backends);
|
|
|
|
if (backends.empty()) {
|
|
OkDialog ok_dialog ("", string_compose (_("No audio/MIDI backends detected. %1 cannot run\n(This is a build/packaging/system error.\nIt should never happen.)"), PROGRAM_NAME));
|
|
ok_dialog.run ();
|
|
throw failed_constructor ();
|
|
}
|
|
for (std::vector<const AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
|
|
_engine_dropdown.add_menu_item ((*b)->name, 0);
|
|
}
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_engine_dropdown.set_sensitive (backends.size() > 1);
|
|
}
|
|
|
|
if (!backends.empty() )
|
|
{
|
|
_engine_dropdown.set_text (EngineStateController::instance()->get_current_backend_name() );
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_device_dropdown()
|
|
{
|
|
std::vector<AudioBackend::DeviceStatus> all_devices;
|
|
EngineStateController::instance()->enumerate_devices (all_devices);
|
|
|
|
_device_dropdown.clear_items ();
|
|
for (std::vector<AudioBackend::DeviceStatus>::const_iterator i = all_devices.begin(); i != all_devices.end(); ++i) {
|
|
_device_dropdown.add_menu_item (i->name, 0);
|
|
}
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_device_dropdown.set_sensitive (all_devices.size() > 1);
|
|
}
|
|
|
|
if(!all_devices.empty() ) {
|
|
_device_dropdown.set_text (EngineStateController::instance ()->get_current_device_name());
|
|
device_changed();
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_file_type_dropdown()
|
|
{
|
|
// Get FILE_TYPE from last used session
|
|
std::string header_format_string = read_property_from_last_session(Native_File_Header_Format);
|
|
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
HeaderFormat header_format = string_to_HeaderFormat(header_format_string);
|
|
ardour_ui->set_header_format( header_format );
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_file_type_dropdown.set_text( HeaderFormat_to_string(header_format) );
|
|
}
|
|
return;
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_sample_rate_dropdown()
|
|
{
|
|
std::vector<float> sample_rates;
|
|
EngineStateController::instance()->available_sample_rates_for_current_device(sample_rates);
|
|
|
|
_sample_rate_dropdown.clear_items ();
|
|
|
|
for (std::vector<float>::const_iterator x = sample_rates.begin(); x != sample_rates.end(); ++x) {
|
|
_sample_rate_dropdown.add_menu_item (ARDOUR_UI_UTILS::rate_as_string (*x), 0);
|
|
}
|
|
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_sample_rate_dropdown.set_sensitive (sample_rates.size() > 1);
|
|
|
|
if (!sample_rates.empty() ) {
|
|
std::string active_sr = ARDOUR_UI_UTILS::rate_as_string(EngineStateController::instance()->get_current_sample_rate() );
|
|
_sample_rate_dropdown.set_text(active_sr);
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_buffer_size_dropdown()
|
|
{
|
|
std::vector<pframes_t> buffer_sizes;
|
|
EngineStateController::instance()->available_buffer_sizes_for_current_device(buffer_sizes);
|
|
|
|
_buffer_size_dropdown.clear_items ();
|
|
for (std::vector<pframes_t>::const_iterator x = buffer_sizes.begin(); x != buffer_sizes.end(); ++x) {
|
|
_buffer_size_dropdown.add_menu_item (bufsize_as_string (*x), 0);
|
|
}
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
_buffer_size_dropdown.set_sensitive (buffer_sizes.size() > 1);
|
|
|
|
if (!buffer_sizes.empty() ) {
|
|
std::string active_bs = bufsize_as_string(EngineStateController::instance()->get_current_buffer_size());
|
|
_buffer_size_dropdown.set_text(active_bs);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_mtc_in_dropdown()
|
|
{
|
|
std::vector<EngineStateController::MidiPortState> midi_states;
|
|
static const char* midi_port_name_prefix = "system_midi:";
|
|
const char* midi_type_suffix;
|
|
bool have_first = false;
|
|
|
|
EngineStateController::instance()->get_physical_midi_input_states(midi_states);
|
|
midi_type_suffix = X_(" capture");
|
|
|
|
_mtc_in_dropdown.clear_items ();
|
|
|
|
Gtk::MenuItem& off_item = _mtc_in_dropdown.add_menu_item ("Off", 0);
|
|
|
|
std::vector<EngineStateController::MidiPortState>::const_iterator state_iter;
|
|
for (state_iter = midi_states.begin(); state_iter != midi_states.end(); ++state_iter) {
|
|
|
|
// strip the device name from input port name
|
|
std::string device_name;
|
|
ARDOUR::remove_pattern_from_string(state_iter->name, midi_port_name_prefix, device_name);
|
|
ARDOUR::remove_pattern_from_string(device_name, midi_type_suffix, device_name);
|
|
|
|
if (state_iter->active) {
|
|
Gtk::MenuItem& new_item = _mtc_in_dropdown.add_menu_item (device_name, strdup(state_iter->name.c_str()) );
|
|
|
|
if (!have_first && state_iter->mtc_in) {
|
|
_mtc_in_dropdown.set_text (new_item.get_label() );
|
|
have_first = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!have_first) {
|
|
_mtc_in_dropdown.set_text (off_item.get_label() );
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::populate_output_mode()
|
|
{
|
|
_multi_out_button.set_active(Config->get_output_auto_connect() & AutoConnectPhysical);
|
|
_stereo_out_button.set_active(Config->get_output_auto_connect() & AutoConnectMaster);
|
|
|
|
_all_outputs_on_button.set_sensitive(Config->get_output_auto_connect() & AutoConnectPhysical);
|
|
_all_outputs_off_button.set_sensitive(Config->get_output_auto_connect() & AutoConnectPhysical);
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::populate_input_channels()
|
|
{
|
|
cleanup_input_channels_list();
|
|
|
|
// process captures (inputs)
|
|
std::vector<EngineStateController::PortState> input_states;
|
|
EngineStateController::instance()->get_physical_audio_input_states(input_states);
|
|
|
|
std::vector<EngineStateController::PortState>::const_iterator input_iter;
|
|
|
|
uint16_t number_count = 1;
|
|
for (input_iter = input_states.begin(); input_iter != input_states.end(); ++input_iter ) {
|
|
|
|
uint16_t number = DeviceConnectionControl::NoNumber;
|
|
std::string track_name;
|
|
|
|
if (input_iter->active) {
|
|
|
|
std::string port_name("");
|
|
std::string pattern(audio_capture_name_prefix);
|
|
ARDOUR::remove_pattern_from_string(input_iter->name, pattern, port_name);
|
|
|
|
number = number_count++;
|
|
|
|
if (Config->get_tracks_auto_naming() & UseDefaultNames) {
|
|
track_name = string_compose ("%1 %2", Session::default_trx_track_name_pattern, number);
|
|
} else if (Config->get_tracks_auto_naming() & NameAfterDriver) {
|
|
track_name = port_name;
|
|
}
|
|
}
|
|
|
|
add_device_capture_control (input_iter->name, input_iter->active, number, track_name);
|
|
}
|
|
|
|
_all_inputs_on_button.set_sensitive(!input_states.empty() );
|
|
_all_inputs_off_button.set_sensitive(!input_states.empty() );
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::populate_output_channels()
|
|
{
|
|
cleanup_output_channels_list();
|
|
|
|
// process captures (outputs)
|
|
std::vector<EngineStateController::PortState> output_states;
|
|
EngineStateController::instance()->get_physical_audio_output_states(output_states);
|
|
|
|
std::vector<EngineStateController::PortState>::const_iterator output_iter;
|
|
|
|
uint16_t number_count = 1;
|
|
for (output_iter = output_states.begin(); output_iter != output_states.end(); ++output_iter ) {
|
|
|
|
uint16_t number = DeviceConnectionControl::NoNumber;
|
|
|
|
if (output_iter->active) {
|
|
number = number_count++;
|
|
}
|
|
|
|
add_device_playback_control (output_iter->name, output_iter->active, number);
|
|
}
|
|
|
|
bool stereo_out_disabled = (Config->get_output_auto_connect() & AutoConnectPhysical);
|
|
_all_outputs_on_button.set_sensitive(!output_states.empty() && stereo_out_disabled );
|
|
_all_outputs_off_button.set_sensitive(!output_states.empty() && stereo_out_disabled );
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::populate_midi_ports()
|
|
{
|
|
cleanup_midi_device_list();
|
|
|
|
std::vector<EngineStateController::MidiPortState> midi_input_states, midi_output_states;
|
|
EngineStateController::instance()->get_physical_midi_input_states(midi_input_states);
|
|
EngineStateController::instance()->get_physical_midi_output_states(midi_output_states);
|
|
|
|
// now group corresponding inputs and outputs into a std::vector of midi device descriptors
|
|
MidiDeviceDescriptorVec midi_device_descriptors;
|
|
std::vector<EngineStateController::MidiPortState>::const_iterator state_iter;
|
|
// process inputs
|
|
for (state_iter = midi_input_states.begin(); state_iter != midi_input_states.end(); ++state_iter) {
|
|
// strip the device name from input port name
|
|
std::string device_name("");
|
|
ARDOUR::remove_pattern_from_string(state_iter->name, midi_port_name_prefix, device_name);
|
|
ARDOUR::remove_pattern_from_string(device_name, midi_capture_suffix, device_name);
|
|
|
|
MidiDeviceDescriptor device_descriptor(device_name);
|
|
device_descriptor.capture_name = state_iter->name;
|
|
device_descriptor.capture_active = state_iter->active;
|
|
midi_device_descriptors.push_back(device_descriptor);
|
|
}
|
|
|
|
// process outputs
|
|
for (state_iter = midi_output_states.begin(); state_iter != midi_output_states.end(); ++state_iter){
|
|
// strip the device name from input port name
|
|
std::string device_name("");
|
|
ARDOUR::remove_pattern_from_string(state_iter->name, midi_port_name_prefix, device_name);
|
|
ARDOUR::remove_pattern_from_string(device_name, midi_playback_suffix, device_name);
|
|
|
|
// check if we already have descriptor for this device
|
|
MidiDeviceDescriptor device_descriptor(device_name);
|
|
MidiDeviceDescriptorVec::iterator found_iter;
|
|
found_iter = std::find(midi_device_descriptors.begin(), midi_device_descriptors.end(), device_descriptor );
|
|
|
|
if (found_iter != midi_device_descriptors.end() ) {
|
|
found_iter->playback_name = state_iter->name;
|
|
found_iter->playback_active = state_iter->active;
|
|
} else {
|
|
device_descriptor.capture_name.clear();
|
|
device_descriptor.playback_name = state_iter->name;
|
|
device_descriptor.playback_active = state_iter->active;
|
|
midi_device_descriptors.push_back(device_descriptor);
|
|
}
|
|
}
|
|
|
|
// now add midi device controls
|
|
MidiDeviceDescriptorVec::iterator iter;
|
|
for (iter = midi_device_descriptors.begin(); iter != midi_device_descriptors.end(); ++iter ) {
|
|
add_midi_device_control(iter->name, iter->capture_name, iter->capture_active,
|
|
iter->playback_name, iter->playback_active);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::cleanup_input_channels_list()
|
|
{
|
|
std::vector<Gtk::Widget*> capture_controls = _device_capture_list.get_children();
|
|
|
|
while (capture_controls.size() != 0) {
|
|
Gtk::Widget* item = capture_controls.back();
|
|
|
|
DeviceConnectionControl* control = dynamic_cast<DeviceConnectionControl*>(item);
|
|
|
|
if (control) {
|
|
control->remove_data(DeviceConnectionControl::id_name);
|
|
}
|
|
|
|
capture_controls.pop_back();
|
|
_device_capture_list.remove(*item);
|
|
delete item;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::cleanup_output_channels_list()
|
|
{
|
|
std::vector<Gtk::Widget*> playback_controls = _device_playback_list.get_children();
|
|
|
|
while (playback_controls.size() != 0) {
|
|
Gtk::Widget* item = playback_controls.back();
|
|
|
|
DeviceConnectionControl* control = dynamic_cast<DeviceConnectionControl*>(item);
|
|
|
|
if (control) {
|
|
control->remove_data(DeviceConnectionControl::id_name);
|
|
}
|
|
|
|
playback_controls.pop_back();
|
|
_device_playback_list.remove(*item);
|
|
delete item;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::cleanup_midi_device_list()
|
|
{
|
|
std::vector<Gtk::Widget*> midi_device_controls = _midi_device_list.get_children();
|
|
|
|
while (midi_device_controls.size() != 0) {
|
|
Gtk::Widget* item = midi_device_controls.back();
|
|
|
|
MidiDeviceConnectionControl* control = dynamic_cast<MidiDeviceConnectionControl*>(item);
|
|
|
|
if (control) {
|
|
control->remove_data(MidiDeviceConnectionControl::capture_id_name);
|
|
control->remove_data(MidiDeviceConnectionControl::playback_id_name);
|
|
}
|
|
|
|
midi_device_controls.pop_back();
|
|
_midi_device_list.remove(*item);
|
|
delete item;
|
|
}
|
|
}
|
|
|
|
|
|
void TracksControlPanel::display_general_preferences ()
|
|
{
|
|
ARDOUR::WaveformShape shape = Config->get_waveform_shape ();
|
|
switch (shape) {
|
|
case Traditional:
|
|
_waveform_shape_dropdown.set_current_item (0);
|
|
break;
|
|
case Rectified:
|
|
_waveform_shape_dropdown.set_current_item (1);
|
|
break;
|
|
default:
|
|
dbg_msg ("TracksControlPanel::display_general_preferences ():\nUnexpected WaveFormShape !");
|
|
break;
|
|
}
|
|
|
|
float peak_hold_time = Config->get_meter_hold ();
|
|
int selected_item = 0;
|
|
if (peak_hold_time <= (MeterHoldOff + 0.1)) {
|
|
selected_item = 0;
|
|
} else if (peak_hold_time <= (MeterHoldShort + 0.1)) {
|
|
selected_item = 1;
|
|
} else if (peak_hold_time <= (MeterHoldMedium + 0.1)) {
|
|
selected_item = 2;
|
|
} else if (peak_hold_time <= (MeterHoldLong + 0.1)) {
|
|
selected_item = 3;
|
|
}
|
|
_peak_hold_time_dropdown.set_current_item (selected_item);
|
|
|
|
float meter_falloff = Config->get_meter_falloff ();
|
|
selected_item = 0;
|
|
|
|
if (meter_falloff <= (METER_FALLOFF_OFF + 0.1)) {
|
|
selected_item = 0;
|
|
} else if (meter_falloff <= (METER_FALLOFF_SLOWEST + 0.1)) {
|
|
selected_item = 1;
|
|
} else if (meter_falloff <= (METER_FALLOFF_SLOW + 0.1)) {
|
|
selected_item = 2;
|
|
} else if (meter_falloff <= (METER_FALLOFF_SLOWISH + 0.1)) {
|
|
selected_item = 3;
|
|
} else if (meter_falloff <= (METER_FALLOFF_MODERATE + 0.1)) {
|
|
selected_item = 4;
|
|
} else if (meter_falloff <= (METER_FALLOFF_MEDIUM + 0.1)) {
|
|
selected_item = 5;
|
|
} else if (meter_falloff <= (METER_FALLOFF_FAST + 0.1)) {
|
|
selected_item = 6;
|
|
} else if (meter_falloff <= (METER_FALLOFF_FASTER + 0.1)) {
|
|
selected_item = 7;
|
|
} else if (meter_falloff <= (METER_FALLOFF_FASTEST + 0.1)) {
|
|
selected_item = 8;
|
|
}
|
|
_dpm_fall_off_dropdown.set_current_item (selected_item);
|
|
|
|
|
|
long period = Config->get_audio_capture_buffer_seconds ();
|
|
selected_item = 0;
|
|
|
|
if (period <= 0.1) {
|
|
selected_item = 0;
|
|
} else if ((period <= 5.1)) {
|
|
selected_item = 1;
|
|
} else if ((period <= 10.1)) {
|
|
selected_item = 2;
|
|
} else if ((period <= 15.1)) {
|
|
selected_item = 3;
|
|
} else if ((period <= 30.1)) {
|
|
selected_item = 4;
|
|
} else if ((period <= 45.1)) {
|
|
selected_item = 5;
|
|
} else if ((period <= 60.1)) {
|
|
selected_item = 6;
|
|
}
|
|
_recording_seconds_dropdown.set_current_item (selected_item);
|
|
|
|
period = Config->get_audio_playback_buffer_seconds ();
|
|
selected_item = 0;
|
|
|
|
if (period <= 0.1) {
|
|
selected_item = 0;
|
|
} else if ((period <= 5.1)) {
|
|
selected_item = 1;
|
|
} else if ((period <= 10.1)) {
|
|
selected_item = 2;
|
|
} else if ((period <= 15.1)) {
|
|
selected_item = 3;
|
|
} else if ((period <= 30.1)) {
|
|
selected_item = 4;
|
|
} else if ((period <= 45.1)) {
|
|
selected_item = 5;
|
|
} else if ((period <= 60.1)) {
|
|
selected_item = 6;
|
|
}
|
|
_playback_seconds_dropdown.set_current_item (selected_item);
|
|
|
|
_obey_mmc_commands_button.set_active_state (Config->get_mmc_control () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
|
_send_mmc_commands_button.set_active_state (Config->get_send_mmc () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
|
_send_mmc_feedback_button.set_active_state (Config->get_midi_feedback () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
|
_inbound_mmc_device_spinbutton.set_value (Config->get_mmc_receive_device_id ());
|
|
_outbound_mmc_device_spinbutton.set_value (Config->get_mmc_send_device_id ());
|
|
_limit_undo_history_spinbutton.set_value (Config->get_history_depth ());
|
|
_save_undo_history_spinbutton.set_value (Config->get_saved_history_depth ());
|
|
_copy_imported_files_button.set_active_state (Config->get_only_copy_imported_files () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
|
_dc_bias_against_denormals_button.set_active_state (Config->get_denormal_protection () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off);
|
|
}
|
|
|
|
|
|
void TracksControlPanel::save_general_preferences ()
|
|
{
|
|
int selected_item = _waveform_shape_dropdown.get_current_item ();
|
|
switch (selected_item) {
|
|
case 0:
|
|
Config->set_waveform_shape (Traditional);
|
|
break;
|
|
case 1:
|
|
Config->set_waveform_shape (Rectified);
|
|
break;
|
|
default:
|
|
dbg_msg ("TracksControlPanel::general_preferences ():\nUnexpected WaveFormShape !");
|
|
break;
|
|
}
|
|
|
|
selected_item = _peak_hold_time_dropdown.get_current_item ();
|
|
switch (selected_item) {
|
|
case 0:
|
|
Config->set_meter_hold (MeterHoldOff);
|
|
break;
|
|
case 1:
|
|
Config->set_meter_hold (MeterHoldShort);
|
|
break;
|
|
case 2:
|
|
Config->set_meter_hold (MeterHoldMedium);
|
|
break;
|
|
case 3:
|
|
Config->set_meter_hold (MeterHoldLong);
|
|
break;
|
|
default:
|
|
dbg_msg ("TracksControlPanel::general_preferences ():\nUnexpected peak hold time!");
|
|
break;
|
|
}
|
|
|
|
selected_item = _dpm_fall_off_dropdown.get_current_item ();
|
|
switch (selected_item) {
|
|
case 0:
|
|
Config->set_meter_falloff (METER_FALLOFF_OFF);
|
|
break;
|
|
case 1:
|
|
Config->set_meter_falloff (METER_FALLOFF_SLOWEST);
|
|
break;
|
|
case 2:
|
|
Config->set_meter_falloff (METER_FALLOFF_SLOW);
|
|
break;
|
|
case 3:
|
|
Config->set_meter_falloff (METER_FALLOFF_SLOWISH);
|
|
break;
|
|
case 4:
|
|
Config->set_meter_falloff (METER_FALLOFF_MODERATE);
|
|
break;
|
|
case 5:
|
|
Config->set_meter_falloff (METER_FALLOFF_MEDIUM);
|
|
break;
|
|
case 6:
|
|
Config->set_meter_falloff (METER_FALLOFF_FAST);
|
|
break;
|
|
case 7:
|
|
Config->set_meter_falloff (METER_FALLOFF_FASTER);
|
|
break;
|
|
case 8:
|
|
Config->set_meter_falloff (METER_FALLOFF_FASTEST);
|
|
break;
|
|
default:
|
|
dbg_msg ("TracksControlPanel::general_preferences ():\nUnexpected meter fall off time!");
|
|
break;
|
|
}
|
|
|
|
Config->set_mmc_control (_obey_mmc_commands_button.active_state () == Gtkmm2ext::ExplicitActive);
|
|
Config->set_send_mmc (_send_mmc_commands_button.active_state () == Gtkmm2ext::ExplicitActive);
|
|
Config->set_midi_feedback (_send_mmc_feedback_button.active_state () == Gtkmm2ext::ExplicitActive);
|
|
Config->set_only_copy_imported_files (_copy_imported_files_button.active_state () == Gtkmm2ext::ExplicitActive);
|
|
Config->set_denormal_protection (_dc_bias_against_denormals_button.active_state () == Gtkmm2ext::ExplicitActive);
|
|
|
|
Config->set_mmc_receive_device_id (_inbound_mmc_device_spinbutton.get_value ());
|
|
Config->set_mmc_send_device_id (_outbound_mmc_device_spinbutton.get_value ());
|
|
Config->set_history_depth (_limit_undo_history_spinbutton.get_value ());
|
|
Config->set_saved_history_depth (_save_undo_history_spinbutton.get_value ());
|
|
Config->set_save_history (_save_undo_history_spinbutton.get_value () > 0);
|
|
}
|
|
|
|
|
|
void TracksControlPanel::on_engine_dropdown_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::string backend_name = _engine_dropdown.get_text();
|
|
|
|
if ( EngineStateController::instance()->set_new_backend_as_current (backend_name) )
|
|
{
|
|
_have_control = EngineStateController::instance()->is_setup_required ();
|
|
populate_device_dropdown();
|
|
return;
|
|
}
|
|
|
|
std::cerr << "\tfailed to set backend [" << backend_name << "]\n";
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_device_dropdown_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::string device_name = _device_dropdown.get_text ();
|
|
|
|
std::string message = _("Would you like to switch to ") + device_name + "?";
|
|
|
|
this->set_keep_above (false);
|
|
YesNoDialog yes_no_dialog ("", message);
|
|
|
|
yes_no_dialog.set_position (Gtk::WIN_POS_MOUSE);
|
|
|
|
switch (yes_no_dialog.run()) {
|
|
case RESPONSE_NO:
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
|
|
_device_dropdown.set_text (EngineStateController::instance()->get_current_device_name());
|
|
this->set_keep_above (true);
|
|
return;
|
|
}
|
|
|
|
this->set_keep_above (true);
|
|
device_changed ();
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::device_changed ()
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::string device_name = _device_dropdown.get_text ();
|
|
if (EngineStateController::instance()->set_new_device_as_current(device_name) )
|
|
{
|
|
populate_buffer_size_dropdown();
|
|
populate_sample_rate_dropdown();
|
|
return;
|
|
}
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
// restore previous device name in combo box
|
|
_device_dropdown.set_text (EngineStateController::instance()->get_current_device_name() );
|
|
}
|
|
|
|
MessageDialog( _("Error activating selected device"), PROGRAM_NAME).run();
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_all_inputs_on_button(WavesButton*)
|
|
{
|
|
EngineStateController::instance()->set_state_to_all_inputs(true);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_name_tracks_after_driver(WavesButton*)
|
|
{
|
|
_yes_button.set_visible(true);
|
|
_no_button.set_visible(true);
|
|
|
|
_tracks_naming_rule = NameAfterDriver;
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_reset_tracks_name_to_default(WavesButton*)
|
|
{
|
|
_yes_button.set_visible(true);
|
|
_no_button.set_visible(true);
|
|
|
|
_tracks_naming_rule = UseDefaultNames;
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_yes_button(WavesButton*)
|
|
{
|
|
Config->set_tracks_auto_naming(_tracks_naming_rule);
|
|
|
|
_yes_button.set_visible(false);
|
|
_no_button.set_visible(false);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_no_button(WavesButton*)
|
|
{
|
|
_yes_button.set_visible(false);
|
|
_no_button.set_visible(false);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_control_panel_button(WavesButton*)
|
|
{
|
|
boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
|
|
assert(backend);
|
|
|
|
backend->launch_control_app ();
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_all_inputs_off_button(WavesButton*)
|
|
{
|
|
EngineStateController::instance()->set_state_to_all_inputs(false);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_all_outputs_on_button(WavesButton*)
|
|
{
|
|
EngineStateController::instance()->set_state_to_all_outputs(true);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_all_outputs_off_button(WavesButton*)
|
|
{
|
|
EngineStateController::instance()->set_state_to_all_outputs(false);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_file_type_dropdown_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::string s = _file_type_dropdown.get_text();
|
|
ARDOUR::HeaderFormat header_format = string_to_HeaderFormat(s);
|
|
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
ardour_ui->set_header_format( header_format );
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_bit_depth_dropdown_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::string s = _bit_depth_dropdown.get_text();
|
|
ARDOUR::SampleFormat sample_format = string_to_SampleFormat(s);
|
|
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
ardour_ui->set_sample_format( sample_format );
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_frame_rate_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
std::string s = _frame_rate_dropdown.get_text();
|
|
Timecode::TimecodeFormat timecode_format = string_to_TimecodeFormat(s);
|
|
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
ardour_ui->set_timecode_format(timecode_format);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_buffer_size_dropdown_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
pframes_t new_buffer_size = get_buffer_size();
|
|
if (EngineStateController::instance()->set_new_buffer_size_in_controller(new_buffer_size) )
|
|
{
|
|
show_buffer_duration();
|
|
return;
|
|
}
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
// restore previous buffer size value in combo box
|
|
std::string buffer_size_str = bufsize_as_string (EngineStateController::instance()->get_current_buffer_size() );
|
|
_buffer_size_dropdown.set_text(buffer_size_str);
|
|
}
|
|
|
|
MessageDialog( _("Buffer size set to the value which is not supported"), PROGRAM_NAME).run();
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_sample_rate_dropdown_item_clicked (WavesDropdown*, int)
|
|
{
|
|
if (_ignore_changes) {
|
|
return;
|
|
}
|
|
|
|
framecnt_t new_sample_rate = get_sample_rate ();
|
|
if (EngineStateController::instance()->set_new_sample_rate_in_controller(new_sample_rate) )
|
|
{
|
|
show_buffer_duration();
|
|
return;
|
|
}
|
|
|
|
{
|
|
// set _ignore_changes flag to ignore changes in combo-box callbacks
|
|
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
|
|
// restore previous buffer size value in combo box
|
|
std::string sample_rate_str = ARDOUR_UI_UTILS::rate_as_string (EngineStateController::instance()->get_current_sample_rate() );
|
|
_sample_rate_dropdown.set_text(sample_rate_str);
|
|
}
|
|
|
|
MessageDialog( _("Sample rate set to the value which is not supported"), PROGRAM_NAME).run();
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_mtc_input_chosen (WavesDropdown* dropdown, int el_number)
|
|
{
|
|
char* full_name_of_chosen_port = (char*)dropdown->get_item_associated_data(el_number);
|
|
|
|
if (full_name_of_chosen_port) {
|
|
EngineStateController::instance()->set_mtc_input((char*) full_name_of_chosen_port);
|
|
} else {
|
|
EngineStateController::instance()->set_mtc_input("");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::engine_running ()
|
|
{
|
|
populate_buffer_size_dropdown();
|
|
populate_sample_rate_dropdown();
|
|
show_buffer_duration ();
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::engine_stopped ()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_a_settings_tab_button_clicked (WavesButton* clicked_button)
|
|
{
|
|
bool visible = (&_midi_settings_tab_button == clicked_button);
|
|
_midi_settings_tab.set_visible (visible);
|
|
_midi_settings_tab_button.set_active(visible);
|
|
|
|
visible = (&_session_settings_tab_button == clicked_button);
|
|
_session_settings_tab.set_visible (visible);;
|
|
_session_settings_tab_button.set_active(visible);
|
|
|
|
visible = (&_audio_settings_tab_button == clicked_button);
|
|
_audio_settings_tab.set_visible (visible);
|
|
_audio_settings_tab_button.set_active(visible);
|
|
|
|
visible = (&_general_settings_tab_button == clicked_button);
|
|
_general_settings_tab.set_visible (visible);
|
|
_general_settings_tab_button.set_active(visible);
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_device_error ()
|
|
{
|
|
std::string message = _("Device cannot operate properly. Switched to None device.");
|
|
|
|
OkDialog ok_dialog ("", message);
|
|
|
|
ok_dialog.set_position (Gtk::WIN_POS_MOUSE);
|
|
ok_dialog.set_keep_above (true);
|
|
ok_dialog.run ();
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_multi_out (WavesButton*)
|
|
{
|
|
if (Config->get_output_auto_connect() & AutoConnectPhysical) {
|
|
return;
|
|
}
|
|
|
|
Config->set_output_auto_connect(AutoConnectPhysical);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_stereo_out (WavesButton*)
|
|
{
|
|
if (Config->get_output_auto_connect() & AutoConnectMaster) {
|
|
return;
|
|
}
|
|
|
|
Config->set_output_auto_connect(AutoConnectMaster);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_browse_button (WavesButton*)
|
|
{
|
|
set_keep_above (false);
|
|
_default_path_name = ARDOUR::choose_folder_dialog(Config->get_default_session_parent_dir(), _("Choose Default Path"));
|
|
set_keep_above (true);
|
|
|
|
if (!_default_path_name.empty()) {
|
|
_default_open_path.set_text(_default_path_name);
|
|
} else {
|
|
_default_open_path.set_text(Config->get_default_session_parent_dir());
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::save_default_session_path()
|
|
{
|
|
if(!_default_path_name.empty())
|
|
{
|
|
Config->set_default_session_parent_dir(_default_path_name);
|
|
Config->save_state();
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::save_auto_lock_time()
|
|
{
|
|
std::string s = _auto_lock_timer_dropdown.get_text();
|
|
char * pEnd;
|
|
int time = strtol( s.c_str(), &pEnd, 10 );
|
|
ARDOUR_UI::config()->set_auto_lock_timer(time);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::save_auto_save_time()
|
|
{
|
|
std::string s = _auto_save_timer_dropdown.get_text();
|
|
char * pEnd;
|
|
int time = strtol( s.c_str(), &pEnd, 10 );
|
|
ARDOUR_UI::config()->set_auto_save_timer(time);
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::save_pre_record_buffer()
|
|
{
|
|
std::string s = _pre_record_buffer_dropdown.get_text();
|
|
char * pEnd;
|
|
int time = strtol( s.c_str(), &pEnd, 10 );
|
|
ARDOUR_UI::config()->set_pre_record_buffer(time);
|
|
}
|
|
|
|
void TracksControlPanel::update_session_config ()
|
|
{
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
|
|
if( ardour_ui )
|
|
{
|
|
ARDOUR::Session* session = ardour_ui->the_session();
|
|
|
|
if( session )
|
|
{
|
|
session->config.set_native_file_header_format( string_to_HeaderFormat(_file_type_dropdown.get_text()));
|
|
session->config.set_native_file_data_format ( string_to_SampleFormat(_bit_depth_dropdown.get_text()));
|
|
session->config.set_timecode_format ( string_to_TimecodeFormat(_frame_rate_dropdown.get_text()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::update_configs()
|
|
{
|
|
// update session config
|
|
update_session_config ();
|
|
|
|
// update global config
|
|
save_default_session_path ();
|
|
save_auto_lock_time ();
|
|
save_auto_save_time ();
|
|
save_pre_record_buffer ();
|
|
save_general_preferences ();
|
|
|
|
// save ARDOUR_UI::config to disk persistently
|
|
ARDOUR_UI::config()->save_state();
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::on_ok (WavesButton*)
|
|
{
|
|
hide();
|
|
EngineStateController::instance()->push_current_state_to_backend(true);
|
|
response(Gtk::RESPONSE_OK);
|
|
|
|
update_configs();
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_cancel (WavesButton*)
|
|
{
|
|
hide();
|
|
response(Gtk::RESPONSE_CANCEL);
|
|
|
|
// restore previous value in combo-boxes
|
|
std::stringstream ss;
|
|
int temp;
|
|
std::string str;
|
|
temp = ARDOUR_UI::config()->get_auto_lock_timer();
|
|
ss.str(std::string(""));
|
|
ss.clear();
|
|
ss << temp;
|
|
str = ss.str() + " Min";
|
|
_auto_lock_timer_dropdown.set_text(str);
|
|
|
|
temp = ARDOUR_UI::config()->get_auto_save_timer();
|
|
ss.str(std::string(""));
|
|
ss.clear();
|
|
ss << temp;
|
|
str = ss.str() + " Min";
|
|
_auto_save_timer_dropdown.set_text(str);
|
|
|
|
temp = ARDOUR_UI::config()->get_pre_record_buffer();
|
|
ss.str(std::string(""));
|
|
ss.clear();
|
|
ss << temp;
|
|
str = ss.str() + " Min";
|
|
_pre_record_buffer_dropdown.set_text(str);
|
|
|
|
_default_open_path.set_text(Config->get_default_session_parent_dir());
|
|
display_general_preferences ();
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_apply (WavesButton*)
|
|
{
|
|
EngineStateController::instance()->push_current_state_to_backend(true);
|
|
//response(Gtk::RESPONSE_APPLY);
|
|
|
|
update_configs();
|
|
}
|
|
|
|
|
|
void TracksControlPanel::on_capture_active_changed(DeviceConnectionControl* capture_control, bool active)
|
|
{
|
|
const char * id_name = (char*)capture_control->get_data(DeviceConnectionControl::id_name);
|
|
EngineStateController::instance()->set_physical_audio_input_state(id_name, active);
|
|
}
|
|
|
|
|
|
void TracksControlPanel::on_playback_active_changed(DeviceConnectionControl* playback_control, bool active)
|
|
{
|
|
const char * id_name = (char*)playback_control->get_data(DeviceConnectionControl::id_name);
|
|
EngineStateController::instance()->set_physical_audio_output_state(id_name, active);
|
|
}
|
|
|
|
|
|
void TracksControlPanel::on_midi_capture_active_changed(MidiDeviceConnectionControl* control, bool active)
|
|
{
|
|
const char * id_name = (char*)control->get_data(MidiDeviceConnectionControl::capture_id_name);
|
|
EngineStateController::instance()->set_physical_midi_input_state(id_name, active);
|
|
}
|
|
|
|
|
|
void TracksControlPanel::on_midi_playback_active_changed(MidiDeviceConnectionControl* control, bool active)
|
|
{
|
|
const char * id_name = (char*)control->get_data(MidiDeviceConnectionControl::playback_id_name);
|
|
EngineStateController::instance()->set_physical_midi_output_state(id_name, active);
|
|
}
|
|
|
|
|
|
void TracksControlPanel::on_port_registration_update()
|
|
{
|
|
populate_input_channels();
|
|
populate_output_channels();
|
|
populate_midi_ports();
|
|
populate_mtc_in_dropdown();
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_buffer_size_update ()
|
|
{
|
|
populate_buffer_size_dropdown();
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_device_list_update (bool current_device_disconnected)
|
|
{
|
|
populate_device_dropdown();
|
|
|
|
if (current_device_disconnected) {
|
|
std::string message = _("Audio device has been removed");
|
|
|
|
this->set_keep_above (false);
|
|
OkDialog ok_dialog ("", message);
|
|
|
|
ok_dialog.set_position (Gtk::WIN_POS_MOUSE);
|
|
ok_dialog.run();
|
|
this->set_keep_above (true);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_parameter_changed (const std::string& parameter_name)
|
|
{
|
|
if (parameter_name == "output-auto-connect") {
|
|
populate_output_mode();
|
|
} else if (parameter_name == "tracks-auto-naming") {
|
|
on_audio_input_configuration_changed ();
|
|
} else if (parameter_name == "default-session-parent-dir") {
|
|
_default_open_path.set_text(Config->get_default_session_parent_dir());
|
|
} else if ((parameter_name == "meter-hold") ||
|
|
(parameter_name == "meter-falloff") ||
|
|
(parameter_name == "waveform-shape") ||
|
|
(parameter_name == "mmc-control") ||
|
|
(parameter_name == "send-mmc") ||
|
|
(parameter_name == "midi-feedback") ||
|
|
(parameter_name == "mmc-receive-device-id") ||
|
|
(parameter_name == "mmc-send-device-id") ||
|
|
(parameter_name == "playback-buffer-seconds") ||
|
|
(parameter_name == "capture-buffer-seconds") ||
|
|
(parameter_name == "only-copy-imported-files") ||
|
|
(parameter_name == "denormal-protection") ||
|
|
(parameter_name == "history-depth") ||
|
|
(parameter_name == "save-history") ||
|
|
(parameter_name == "save-history-depth")){
|
|
// This is not that correct.
|
|
// We should update UI when the panel is being shown.
|
|
// We should not react immediately.
|
|
// The use case is: load the values, edit them and then
|
|
// save or cancel.
|
|
display_general_preferences ();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_audio_input_configuration_changed ()
|
|
{
|
|
std::vector<Gtk::Widget*> capture_controls = _device_capture_list.get_children();
|
|
|
|
std::vector<Gtk::Widget*>::iterator control_iter = capture_controls.begin();
|
|
|
|
uint16_t number_count = 1;
|
|
for (; control_iter != capture_controls.end(); ++control_iter) {
|
|
DeviceConnectionControl* control = dynamic_cast<DeviceConnectionControl*> (*control_iter);
|
|
|
|
if (control) {
|
|
|
|
const char* id_name = (char*)control->get_data(DeviceConnectionControl::id_name);
|
|
|
|
if (id_name) {
|
|
bool new_state = EngineStateController::instance()->get_physical_audio_input_state(id_name );
|
|
|
|
uint16_t number = DeviceConnectionControl::NoNumber;
|
|
std::string track_name ("");
|
|
|
|
if (new_state) {
|
|
|
|
number = number_count++;
|
|
|
|
if (Config->get_tracks_auto_naming() & UseDefaultNames) {
|
|
track_name = string_compose ("%1 %2", Session::default_trx_track_name_pattern, number);
|
|
} else if (Config->get_tracks_auto_naming() & NameAfterDriver) {
|
|
track_name = control->get_port_name();
|
|
}
|
|
}
|
|
|
|
control->set_track_name(track_name);
|
|
control->set_number(number);
|
|
control->set_active(new_state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_audio_output_configuration_changed()
|
|
{
|
|
std::vector<Gtk::Widget*> playback_controls = _device_playback_list.get_children();
|
|
|
|
std::vector<Gtk::Widget*>::iterator control_iter = playback_controls.begin();
|
|
|
|
uint16_t number_count = 1;
|
|
for (; control_iter != playback_controls.end(); ++control_iter) {
|
|
DeviceConnectionControl* control = dynamic_cast<DeviceConnectionControl*> (*control_iter);
|
|
|
|
if (control) {
|
|
|
|
const char * id_name = (char*)control->get_data(DeviceConnectionControl::id_name);
|
|
|
|
if (id_name != NULL) {
|
|
bool new_state = EngineStateController::instance()->get_physical_audio_output_state(id_name );
|
|
|
|
uint16_t number = DeviceConnectionControl::NoNumber;
|
|
|
|
if (new_state) {
|
|
number = number_count++;
|
|
}
|
|
|
|
control->set_number(number);
|
|
control->set_active(new_state);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_midi_input_configuration_changed ()
|
|
{
|
|
std::vector<Gtk::Widget*> midi_controls = _midi_device_list.get_children();
|
|
|
|
std::vector<Gtk::Widget*>::iterator control_iter = midi_controls.begin();
|
|
|
|
for (; control_iter != midi_controls.end(); ++control_iter) {
|
|
MidiDeviceConnectionControl* control = dynamic_cast<MidiDeviceConnectionControl*> (*control_iter);
|
|
|
|
if (control && control->has_capture() ) {
|
|
|
|
const char* capture_id_name = (char*)control->get_data(MidiDeviceConnectionControl::capture_id_name);
|
|
|
|
if (capture_id_name != NULL) {
|
|
bool connected;
|
|
bool new_state = EngineStateController::instance()->get_physical_midi_input_state(capture_id_name, connected );
|
|
control->set_capture_active(new_state);
|
|
}
|
|
}
|
|
}
|
|
|
|
populate_mtc_in_dropdown();
|
|
|
|
ARDOUR::Session* session = ARDOUR_UI::instance()->the_session();
|
|
if (session) {
|
|
session->reconnect_mtc_ports ();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_midi_output_configuration_changed ()
|
|
{
|
|
std::vector<Gtk::Widget*> midi_controls = _midi_device_list.get_children();
|
|
|
|
std::vector<Gtk::Widget*>::iterator control_iter = midi_controls.begin();
|
|
|
|
for (; control_iter != midi_controls.end(); ++control_iter) {
|
|
MidiDeviceConnectionControl* control = dynamic_cast<MidiDeviceConnectionControl*> (*control_iter);
|
|
|
|
if (control && control->has_playback() ) {
|
|
|
|
const char* playback_id_name = (char*)control->get_data(MidiDeviceConnectionControl::playback_id_name);
|
|
|
|
if (playback_id_name != NULL) {
|
|
bool connected;
|
|
bool new_state = EngineStateController::instance()->get_physical_midi_output_state(playback_id_name, connected );
|
|
control->set_playback_active(new_state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TracksControlPanel::on_mtc_input_changed (const std::string&)
|
|
{
|
|
ARDOUR_UI* ardour_ui = ARDOUR_UI::instance();
|
|
|
|
if(!ardour_ui)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ARDOUR::Session* session = ardour_ui->the_session();
|
|
if (!session) {
|
|
return;
|
|
}
|
|
|
|
session->reconnect_mtc_ports ();
|
|
}
|
|
|
|
|
|
std::string
|
|
TracksControlPanel::bufsize_as_string (uint32_t sz)
|
|
{
|
|
/* Translators: "samples" is always plural here, so no
|
|
need for plural+singular forms.
|
|
*/
|
|
char buf[32];
|
|
snprintf (buf, sizeof (buf), _("%u samples"), sz);
|
|
return buf;
|
|
}
|
|
|
|
|
|
framecnt_t
|
|
TracksControlPanel::get_sample_rate () const
|
|
{
|
|
const std::string sample_rate = _sample_rate_dropdown.get_text ();
|
|
|
|
return ARDOUR_UI_UTILS::string_as_rate (sample_rate);
|
|
}
|
|
|
|
pframes_t
|
|
TracksControlPanel::get_buffer_size() const
|
|
{
|
|
std::string bs_text = _buffer_size_dropdown.get_text ();
|
|
pframes_t samples = atoi (bs_text); /* will ignore trailing text */
|
|
return samples;
|
|
}
|
|
|
|
void
|
|
TracksControlPanel::show_buffer_duration ()
|
|
{
|
|
float latency = (get_buffer_size() * 1000.0) / get_sample_rate();
|
|
|
|
char buf[256];
|
|
snprintf (buf, sizeof (buf), _("INPUT LATENCY: %.1f MS OUTPUT LATENCY: %.1f MS TOTAL LATENCY: %.1f MS"),
|
|
latency, latency, 2*latency);
|
|
_latency_label.set_text (buf);
|
|
}
|