Merge branch 'master' into ardour-merge
Conflicts: gtk2_ardour/time_axis_view_item.cc libs/backends/wavesaudio/waves_audiobackend.h libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp
|
|
@ -211,14 +211,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
||||||
, _feedback_exists (false)
|
, _feedback_exists (false)
|
||||||
, _dsp_load_adjustment (0)
|
, _dsp_load_adjustment (0)
|
||||||
, _hd_load_adjustment (0)
|
, _hd_load_adjustment (0)
|
||||||
, _dsp_load_label(0)
|
, _dsp_load_label (0)
|
||||||
, _hd_load_label(0)
|
, _hd_load_label (0)
|
||||||
, _hd_remained_time_label(0)
|
, _hd_remained_time_label (0)
|
||||||
, editor (0)
|
, editor (0)
|
||||||
, mixer (0)
|
, mixer (0)
|
||||||
, _bit_depth_button(0)
|
, _tracks_button (0)
|
||||||
, _sample_rate_button(0)
|
, _bit_depth_button (0)
|
||||||
, _frame_rate_button(0)
|
, _sample_rate_button (0)
|
||||||
|
, _frame_rate_button (0)
|
||||||
, splash (0)
|
, splash (0)
|
||||||
{
|
{
|
||||||
Gtkmm2ext::init(localedir);
|
Gtkmm2ext::init(localedir);
|
||||||
|
|
@ -4026,15 +4027,17 @@ ARDOUR_UI::sr_mismatch_dialog (framecnt_t desired, framecnt_t actual)
|
||||||
ArdourDialog dialog (_("Sample Rate Mismatch"), true);
|
ArdourDialog dialog (_("Sample Rate Mismatch"), true);
|
||||||
Label message (string_compose (_("\
|
Label message (string_compose (_("\
|
||||||
This session was created with a sample rate of %1 Hz, but\n\
|
This session was created with a sample rate of %1 Hz, but\n\
|
||||||
%2 is currently running at %3 Hz. If you load this session,\n\
|
%2 is currently running at %3 Hz. If you load this session,\n\
|
||||||
|
device will be switched to the session sample rate value. \n\
|
||||||
|
If an attemp to switch the device is unsuccessful\n\
|
||||||
audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual));
|
audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual));
|
||||||
|
|
||||||
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
|
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
|
||||||
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
|
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
|
||||||
hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
|
hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
|
||||||
dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
|
dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
|
||||||
dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
|
dialog.add_button (_("Cancel"), RESPONSE_REJECT);
|
||||||
dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
|
dialog.add_button (_("Accept"), RESPONSE_ACCEPT);
|
||||||
dialog.set_default_response (RESPONSE_ACCEPT);
|
dialog.set_default_response (RESPONSE_ACCEPT);
|
||||||
dialog.set_position (WIN_POS_CENTER);
|
dialog.set_position (WIN_POS_CENTER);
|
||||||
message.show();
|
message.show();
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
||||||
void focus_on_clock ();
|
void focus_on_clock ();
|
||||||
AudioClock* big_clock;
|
AudioClock* big_clock;
|
||||||
|
|
||||||
|
WavesButton* _tracks_button;
|
||||||
|
void on_tracks_button (WavesButton*);
|
||||||
WavesButton* _bit_depth_button;
|
WavesButton* _bit_depth_button;
|
||||||
WavesButton* _sample_rate_button;
|
WavesButton* _sample_rate_button;
|
||||||
WavesButton* _frame_rate_button;
|
WavesButton* _frame_rate_button;
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,8 @@ ARDOUR_UI::create_editor ()
|
||||||
_bit_depth_button = &editor->get_waves_button("bit_depth_button");
|
_bit_depth_button = &editor->get_waves_button("bit_depth_button");
|
||||||
_sample_rate_button = &editor->get_waves_button("sample_rate_button");
|
_sample_rate_button = &editor->get_waves_button("sample_rate_button");
|
||||||
_frame_rate_button = &editor->get_waves_button("frame_rate_button");
|
_frame_rate_button = &editor->get_waves_button("frame_rate_button");
|
||||||
|
|
||||||
|
_tracks_button = &editor->get_waves_button("tracks_button");
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
|
|
@ -99,6 +101,7 @@ ARDOUR_UI::create_editor ()
|
||||||
_bit_depth_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_bit_depth_button));
|
_bit_depth_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_bit_depth_button));
|
||||||
_sample_rate_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_sample_rate_button));
|
_sample_rate_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_sample_rate_button));
|
||||||
_frame_rate_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_frame_rate_button));
|
_frame_rate_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_frame_rate_button));
|
||||||
|
_tracks_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_tracks_button));
|
||||||
|
|
||||||
editor->Realized.connect (sigc::mem_fun (*this, &ARDOUR_UI::editor_realized));
|
editor->Realized.connect (sigc::mem_fun (*this, &ARDOUR_UI::editor_realized));
|
||||||
editor->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), true));
|
editor->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), true));
|
||||||
|
|
@ -106,6 +109,12 @@ ARDOUR_UI::create_editor ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ARDOUR_UI::on_tracks_button (WavesButton*)
|
||||||
|
{
|
||||||
|
about->show ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ARDOUR_UI::on_bit_depth_button (WavesButton*)
|
ARDOUR_UI::on_bit_depth_button (WavesButton*)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 2.4 KiB |
BIN
gtk2_ardour/icons/infobar_center.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
gtk2_ardour/icons/infobar_left.png
Normal file
|
After Width: | Height: | Size: 207 B |
BIN
gtk2_ardour/icons/infobar_right.png
Normal file
|
After Width: | Height: | Size: 212 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 644 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 301 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 1.4 KiB |
|
|
@ -59,8 +59,14 @@ using namespace ARDOUR;
|
||||||
using namespace ARDOUR_UI_UTILS;
|
using namespace ARDOUR_UI_UTILS;
|
||||||
using namespace Gtkmm2ext;
|
using namespace Gtkmm2ext;
|
||||||
|
|
||||||
Pango::FontDescription TimeAxisViewItem::NAME_FONT;
|
// GZ: Should be moved to config
|
||||||
const double TimeAxisViewItem::NAME_HIGHLIGHT_Y_IDENT = 3.0;
|
#ifdef _WIN32
|
||||||
|
Pango::FontDescription TimeAxisViewItem::NAME_FONT("Helvetica 8");
|
||||||
|
#else
|
||||||
|
Pango::FontDescription TimeAxisViewItem::NAME_FONT("Arial 8");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const double TimeAxisViewItem::NAME_HIGHLIGHT_Y_INDENT = 1.0;
|
||||||
const double TimeAxisViewItem::NAME_HIGHLIGHT_X_OFFSET = 10.0;
|
const double TimeAxisViewItem::NAME_HIGHLIGHT_X_OFFSET = 10.0;
|
||||||
const double TimeAxisViewItem::NAME_HIGHLIGHT_Y_OFFSET = 5.0;
|
const double TimeAxisViewItem::NAME_HIGHLIGHT_Y_OFFSET = 5.0;
|
||||||
const double TimeAxisViewItem::GRAB_HANDLE_TOP = 2.0;
|
const double TimeAxisViewItem::GRAB_HANDLE_TOP = 2.0;
|
||||||
|
|
@ -71,20 +77,19 @@ const double TimeAxisViewItem::REGION_TOP_OFFSET = 2.0;
|
||||||
const double TimeAxisViewItem::REGION_BOTTOM_OFFSET = 3.0;
|
const double TimeAxisViewItem::REGION_BOTTOM_OFFSET = 3.0;
|
||||||
|
|
||||||
int TimeAxisViewItem::NAME_HEIGHT;
|
int TimeAxisViewItem::NAME_HEIGHT;
|
||||||
double TimeAxisViewItem::NAME_HIGHLIGHT_X_IDENT;
|
double TimeAxisViewItem::NAME_HIGHLIGHT_X_INDENT;
|
||||||
double TimeAxisViewItem::NAME_Y_OFFSET;
|
|
||||||
double TimeAxisViewItem::NAME_HIGHLIGHT_HEIGHT;
|
double TimeAxisViewItem::NAME_HIGHLIGHT_HEIGHT;
|
||||||
double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
|
double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
|
||||||
|
|
||||||
void
|
void
|
||||||
TimeAxisViewItem::set_constant_heights ()
|
TimeAxisViewItem::set_constant_heights ()
|
||||||
{
|
{
|
||||||
NAME_FONT = Pango::FontDescription (ARDOUR_UI::config()->get_canvasvar_SmallFont());
|
// GZ: FONT IS DEFINED AT THE BEGINNING OF THE FILE
|
||||||
|
//NAME_FONT = get_font_for_style (X_("TimeAxisViewItemName"));
|
||||||
Gtk::Window win;
|
Gtk::Window win;
|
||||||
Gtk::Label foo;
|
Gtk::Label foo;
|
||||||
win.add (foo);
|
win.add (foo);
|
||||||
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
|
|
@ -92,17 +97,17 @@ TimeAxisViewItem::set_constant_heights ()
|
||||||
layout->set_font_description (NAME_FONT);
|
layout->set_font_description (NAME_FONT);
|
||||||
get_pixel_size (layout, width, height);
|
get_pixel_size (layout, width, height);
|
||||||
|
|
||||||
NAME_HEIGHT = height + 2;
|
NAME_HEIGHT = height;
|
||||||
NAME_HIGHLIGHT_X_IDENT = width + 2;
|
NAME_HIGHLIGHT_X_INDENT = width;
|
||||||
|
|
||||||
/* Config->get_show_name_highlight) == true:
|
/* Config->get_show_name_highlight) == true:
|
||||||
Y_OFFSET is measured from bottom of the time axis view item.
|
Y_OFFSET is measured from bottom of the time axis view item.
|
||||||
Config->get_show_name_highlight) == false:
|
Config->get_show_name_highlight) == false:
|
||||||
Y_OFFSET is measured from the top of the time axis view item.
|
Y_OFFSET is measured from the top of the time axis view item.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NAME_HIGHLIGHT_HEIGHT = NAME_HEIGHT + NAME_HIGHLIGHT_Y_IDENT*2;
|
NAME_HIGHLIGHT_HEIGHT = NAME_HEIGHT + NAME_HIGHLIGHT_Y_INDENT*2;
|
||||||
NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_HEIGHT * 1.5;
|
NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_HEIGHT + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -226,27 +231,28 @@ TimeAxisViewItem::init (ArdourCanvas::Item* parent, double fpp, uint32_t base_co
|
||||||
{ // always show name highlight
|
{ // always show name highlight
|
||||||
double width;
|
double width;
|
||||||
|
|
||||||
width = trackview.editor().sample_to_pixel(item_duration) - 2.0 + RIGHT_EDGE_SHIFT;
|
width = trackview.editor().sample_to_pixel(item_duration) - 2.0 + RIGHT_EDGE_SHIFT;
|
||||||
|
|
||||||
name_highlight = new ArdourCanvas::Rectangle (group,
|
name_highlight = new ArdourCanvas::Rectangle (group,
|
||||||
ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
|
ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
|
||||||
NAME_HIGHLIGHT_Y_OFFSET,
|
NAME_HIGHLIGHT_Y_OFFSET,
|
||||||
NAME_HIGHLIGHT_X_OFFSET + 2*NAME_HIGHLIGHT_X_IDENT,
|
NAME_HIGHLIGHT_X_OFFSET + 2*NAME_HIGHLIGHT_X_INDENT,
|
||||||
NAME_HIGHLIGHT_HEIGHT) );
|
NAME_HIGHLIGHT_HEIGHT + NAME_HIGHLIGHT_Y_OFFSET) );
|
||||||
CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
|
CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
|
||||||
name_highlight->set_data ("timeaxisviewitem", this);
|
name_highlight->set_data ("timeaxisviewitem", this);
|
||||||
name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0) );
|
name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0) );
|
||||||
name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
|
name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
name_text = new ArdourCanvas::Text (group);
|
name_text = new ArdourCanvas::Text (group);
|
||||||
CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
|
CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
|
||||||
|
|
||||||
name_text->set_position (ArdourCanvas::Duple (NAME_HIGHLIGHT_X_OFFSET + NAME_HIGHLIGHT_X_IDENT, NAME_HIGHLIGHT_Y_OFFSET + NAME_HIGHLIGHT_Y_IDENT) );
|
name_text->set_position (ArdourCanvas::Duple (NAME_HIGHLIGHT_X_OFFSET + NAME_HIGHLIGHT_X_IDENT, NAME_HIGHLIGHT_Y_OFFSET + NAME_HIGHLIGHT_Y_IDENT) );
|
||||||
name_text->set("");
|
name_text->set("");
|
||||||
name_text->set_font_description (NAME_FONT);
|
name_text->set_font_description (NAME_FONT);
|
||||||
|
|
||||||
if (name_text->text().empty() ) {
|
if (name_text->text().empty()) {
|
||||||
name_highlight->hide();
|
name_highlight->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -558,8 +564,9 @@ TimeAxisViewItem::set_name_text(const string& new_name)
|
||||||
if (!name_text) {
|
if (!name_text) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// This is a workaround.
|
||||||
name_text_width = pixel_width (new_name, NAME_FONT);
|
// Pango returns incorrect width values 1.5*NAME_HIGHLIGHT_X_INDENT
|
||||||
|
name_text_width = pixel_width (new_name, NAME_FONT) + 1.5*NAME_HIGHLIGHT_X_INDENT;
|
||||||
name_text->set (new_name);
|
name_text->set (new_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -601,12 +608,12 @@ TimeAxisViewItem::manage_name_highlight ()
|
||||||
high_enough_for_name = true;
|
high_enough_for_name = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double highlite_y1 = name_text_width + 2*NAME_HIGHLIGHT_X_IDENT + NAME_HIGHLIGHT_X_OFFSET;
|
double highlite_x1 = name_text_width + 2*NAME_HIGHLIGHT_X_INDENT + NAME_HIGHLIGHT_X_OFFSET;
|
||||||
if (_width < highlite_y1) {
|
if (_width < highlite_x1) {
|
||||||
highlite_y1 = _width;
|
highlite_x1 = _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highlite_y1 < NAME_HIGHLIGHT_X_OFFSET) {
|
if (highlite_x1 < NAME_HIGHLIGHT_X_OFFSET) {
|
||||||
wide_enough_for_name = false;
|
wide_enough_for_name = false;
|
||||||
} else {
|
} else {
|
||||||
wide_enough_for_name = true;
|
wide_enough_for_name = true;
|
||||||
|
|
@ -615,10 +622,10 @@ TimeAxisViewItem::manage_name_highlight ()
|
||||||
if (wide_enough_for_name && high_enough_for_name && !name_text->text().empty() ) {
|
if (wide_enough_for_name && high_enough_for_name && !name_text->text().empty() ) {
|
||||||
name_highlight->set (ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
|
name_highlight->set (ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
|
||||||
NAME_HIGHLIGHT_Y_OFFSET,
|
NAME_HIGHLIGHT_Y_OFFSET,
|
||||||
highlite_y1,
|
highlite_x1,
|
||||||
NAME_HIGHLIGHT_HEIGHT) );
|
NAME_HIGHLIGHT_HEIGHT + NAME_HIGHLIGHT_Y_OFFSET) );
|
||||||
name_highlight->show();
|
name_highlight->show();
|
||||||
|
name_highlight->raise_to_top();
|
||||||
} else {
|
} else {
|
||||||
name_highlight->hide();
|
name_highlight->hide();
|
||||||
}
|
}
|
||||||
|
|
@ -948,8 +955,8 @@ TimeAxisViewItem::manage_name_text ()
|
||||||
|
|
||||||
visible_name_width = name_text_width;
|
visible_name_width = name_text_width;
|
||||||
|
|
||||||
if (visible_name_width > _width - NAME_HIGHLIGHT_X_OFFSET - NAME_HIGHLIGHT_X_IDENT) {
|
if (visible_name_width > _width - NAME_HIGHLIGHT_X_OFFSET - NAME_HIGHLIGHT_X_INDENT) {
|
||||||
visible_name_width = _width - NAME_HIGHLIGHT_X_OFFSET - NAME_HIGHLIGHT_X_IDENT;
|
visible_name_width = _width - NAME_HIGHLIGHT_X_OFFSET - NAME_HIGHLIGHT_X_INDENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visible_name_width < 1) {
|
if (visible_name_width < 1) {
|
||||||
|
|
@ -957,6 +964,7 @@ TimeAxisViewItem::manage_name_text ()
|
||||||
} else {
|
} else {
|
||||||
name_text->clamp_width (visible_name_width);
|
name_text->clamp_width (visible_name_width);
|
||||||
name_text->show ();
|
name_text->show ();
|
||||||
|
name_text->raise_to_top ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
|
||||||
// Default sizes, font and spacing
|
// Default sizes, font and spacing
|
||||||
static Pango::FontDescription NAME_FONT;
|
static Pango::FontDescription NAME_FONT;
|
||||||
static void set_constant_heights ();
|
static void set_constant_heights ();
|
||||||
static const double NAME_HIGHLIGHT_Y_IDENT;
|
static const double NAME_HIGHLIGHT_Y_INDENT;
|
||||||
static const double NAME_HIGHLIGHT_X_OFFSET;
|
static const double NAME_HIGHLIGHT_X_OFFSET;
|
||||||
static const double NAME_HIGHLIGHT_Y_OFFSET;
|
static const double NAME_HIGHLIGHT_Y_OFFSET;
|
||||||
static const double GRAB_HANDLE_TOP;
|
static const double GRAB_HANDLE_TOP;
|
||||||
|
|
@ -117,9 +117,8 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
|
||||||
of the font used to display the item name.
|
of the font used to display the item name.
|
||||||
*/
|
*/
|
||||||
static int NAME_HEIGHT;
|
static int NAME_HEIGHT;
|
||||||
static double NAME_HIGHLIGHT_X_IDENT;
|
static double NAME_HIGHLIGHT_X_INDENT;
|
||||||
static double NAME_X_OFFSET;
|
static double NAME_X_OFFSET;
|
||||||
static double NAME_Y_OFFSET;
|
|
||||||
static double NAME_HIGHLIGHT_HEIGHT;
|
static double NAME_HIGHLIGHT_HEIGHT;
|
||||||
static double NAME_HIGHLIGHT_THRESH;
|
static double NAME_HIGHLIGHT_THRESH;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@ TracksControlPanel::init ()
|
||||||
EngineStateController::instance()->OutputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_audio_output_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()->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()->MIDIOutputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_midi_output_configuration_changed, this), gui_context());
|
||||||
|
EngineStateController::instance()->DeviceError.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_device_error, this), gui_context());
|
||||||
|
|
||||||
/* Global configuration parameters update */
|
/* Global configuration parameters update */
|
||||||
Config->ParameterChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_parameter_changed, this, _1), gui_context());
|
Config->ParameterChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_parameter_changed, this, _1), gui_context());
|
||||||
|
|
||||||
|
|
@ -1243,6 +1244,21 @@ TracksControlPanel::on_session_settings (WavesButton*)
|
||||||
_session_settings_tab_button.set_active(true);
|
_session_settings_tab_button.set_active(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TracksControlPanel::on_device_error ()
|
||||||
|
{
|
||||||
|
std::string message = _("Device cannot operate properly. Switched to None device.");
|
||||||
|
|
||||||
|
MessageDialog msg (message,
|
||||||
|
false,
|
||||||
|
Gtk::MESSAGE_WARNING,
|
||||||
|
Gtk::BUTTONS_OK,
|
||||||
|
true);
|
||||||
|
|
||||||
|
msg.set_position (Gtk::WIN_POS_MOUSE);
|
||||||
|
msg.set_keep_above (true);
|
||||||
|
msg.run ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TracksControlPanel::on_multi_out (WavesButton*)
|
TracksControlPanel::on_multi_out (WavesButton*)
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@
|
||||||
void on_audio_output_configuration_changed ();
|
void on_audio_output_configuration_changed ();
|
||||||
void on_midi_input_configuration_changed ();
|
void on_midi_input_configuration_changed ();
|
||||||
void on_midi_output_configuration_changed ();
|
void on_midi_output_configuration_changed ();
|
||||||
|
void on_device_error ();
|
||||||
|
|
||||||
void cleanup_input_channels_list();
|
void cleanup_input_channels_list();
|
||||||
void cleanup_output_channels_list();
|
void cleanup_output_channels_list();
|
||||||
|
|
|
||||||
|
|
@ -1,145 +1,138 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<RouteUI bgnormal="#383838" bgactive="#545454">
|
<RouteUI bgnormal="#383838" bgactive="#545454">
|
||||||
<Vbox>
|
<Vbox>
|
||||||
<EventBox id="upper_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3"/>
|
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
|
||||||
<HBox>
|
<EventBox id="upper_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3"/>
|
||||||
<VBox>
|
<HBox box.fill="true" box.expand="true">
|
||||||
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
|
<VBox>
|
||||||
<HBox box.expand="true" box.fill="true">
|
<HBox box.expand="true" box.fill="true">
|
||||||
<EventBox id="selected_track_color_box" width="29" bgactive="#5BA55C">
|
<EventBox id="selected_track_color_box" width="29" bgactive="#5BA55C">
|
||||||
<HBox>
|
<HBox>
|
||||||
<!--<Igor! width="2" below is the shift from RIGHT side of the space>-->
|
<!--<Igor! width="2" below is the shift from RIGHT side of the space>-->
|
||||||
<VBox width="2" box.pack="end"/>
|
<VBox width="2" box.pack="end"/>
|
||||||
<VBox box.pack="end">
|
<VBox box.pack="end">
|
||||||
<!--<Igor! height="4" below is the shift from TOP side of the space>-->
|
<!--<Igor! height="4" below is the shift from TOP side of the space>-->
|
||||||
<HBox height="4"/>
|
<HBox height="4"/>
|
||||||
<Label id="number_label"
|
<Label id="number_label"
|
||||||
text="32"
|
text="32"
|
||||||
fgnormal="#ffffff"
|
fgnormal="#ffffff"
|
||||||
fgactive="#ffffff"
|
fgactive="#ffffff"
|
||||||
winfont ="Arial Bold 13"
|
winfont ="Arial Bold 13"
|
||||||
macfont ="Helvetica Bold 13"/>
|
macfont ="Helvetica Bold 13"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
</HBox>
|
</HBox>
|
||||||
</EventBox>
|
</EventBox>
|
||||||
<EventBox id="track_color_box" width="6" bgnormal="#5BA55C" bgactive="#5BA55C"/>
|
<EventBox id="track_color_box" width="6" bgnormal="#5BA55C" bgactive="#5BA55C"/>
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000" box.pack="end"/>
|
</VBox>
|
||||||
</VBox>
|
<VBox>
|
||||||
<VBox>
|
<!--<Igor! About the track name: height="5" below is the shift from TOP side of the space>-->
|
||||||
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
|
<HBox height="5"/>
|
||||||
<!--<Igor! About the track name: height="5" below is the shift from TOP side of the space>-->
|
<HBox width="80"
|
||||||
<HBox height="5"/>
|
id="name_label_home">
|
||||||
<HBox width="80"
|
<HBox width="5"/>
|
||||||
id="name_label_home">
|
<Label id="name_label"
|
||||||
<HBox width="5"/>
|
winfont ="Arial 10"
|
||||||
<Label id="name_label"
|
macfont ="Helvetica 10"
|
||||||
winfont ="Arial 10"
|
fgnormal="#ffffff"
|
||||||
macfont ="Helvetica 10"
|
fgactive="#ffffff"/>
|
||||||
fgnormal="#ffffff"
|
<FocusEntry id="name_entry"
|
||||||
fgactive="#ffffff"/>
|
width="80"
|
||||||
<FocusEntry id="name_entry"
|
height="20"
|
||||||
width="80"
|
fgnormal="#ffffff"
|
||||||
height="20"
|
winfont ="Arial 10"
|
||||||
fgnormal="#ffffff"
|
macfont ="Helvetica 10"
|
||||||
winfont ="Arial 10"
|
cssname="EditorTrackNameDisplay"
|
||||||
macfont ="Helvetica 10"
|
textcolornormal="#ffffff"
|
||||||
cssname="EditorTrackNameDisplay"
|
textcoloractive="#ffffff"
|
||||||
textcolornormal="#ffffff"
|
textcolorselected="#ffffff"
|
||||||
textcoloractive="#ffffff"
|
noshowall="true"
|
||||||
textcolorselected="#ffffff"
|
visible="false"/>
|
||||||
noshowall="true"
|
</HBox>
|
||||||
visible="false"/>
|
</VBox>
|
||||||
</HBox>
|
<VBox>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000" box.pack="end"/>
|
|
||||||
</VBox>
|
|
||||||
<VBox>
|
|
||||||
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
|
|
||||||
<HBox>
|
|
||||||
<iconbutton id="playlist_button"
|
|
||||||
width="21"
|
|
||||||
height="20"
|
|
||||||
normalicon="time_axis_playlist"
|
|
||||||
activeicon="time_axis_playlist"
|
|
||||||
prelighticon="time_axis_playlist"/>
|
|
||||||
<HBox width="3"/>
|
|
||||||
<HBox>
|
<HBox>
|
||||||
|
<iconbutton id="playlist_button"
|
||||||
|
width="21"
|
||||||
|
height="20"
|
||||||
|
normalicon="time_axis_playlist"
|
||||||
|
activeicon="time_axis_playlist"
|
||||||
|
prelighticon="time_axis_playlist"/>
|
||||||
|
<HBox width="3"/>
|
||||||
|
<HBox>
|
||||||
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
<VBox>
|
||||||
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
<iconbutton id="rec_enable_button"
|
||||||
|
width="41"
|
||||||
|
height="20"
|
||||||
|
normalicon="time_axis_record"
|
||||||
|
activeicon="time_axis_record_active"
|
||||||
|
prelighticon="time_axis_record_prelight"
|
||||||
|
tooltip="Record Enable"/>
|
||||||
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
</VBox>
|
||||||
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
<VBox>
|
||||||
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
<iconbutton id="solo_button"
|
||||||
|
width="41"
|
||||||
|
height="20"
|
||||||
|
normalicon="time_axis_solo"
|
||||||
|
activeicon="time_axis_solo_active"
|
||||||
|
implicitactiveicon="time_axis_solo_safe"
|
||||||
|
prelighticon="time_axis_solo_prelight"
|
||||||
|
tooltip="Solo"/>
|
||||||
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
</VBox>
|
||||||
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
|
</HBox>
|
||||||
|
</HBox>
|
||||||
|
<HBox>
|
||||||
|
<VBox width="24"/>
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
<VBox>
|
<VBox>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
<iconbutton id="monitor_input_button"
|
||||||
<iconbutton id="rec_enable_button"
|
|
||||||
width="41"
|
width="41"
|
||||||
height="20"
|
height="20"
|
||||||
normalicon="time_axis_record"
|
normalicon="time_axis_monitor_input"
|
||||||
activeicon="time_axis_record_active"
|
activeicon="time_axis_monitor_input_active"
|
||||||
prelighticon="time_axis_record_prelight"
|
prelighticon="time_axis_monitor_input_prelight"
|
||||||
tooltip="Record Enable"/>
|
tooltip="Input Monitoring"/>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
<VBox>
|
<VBox>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
<iconbutton id="mute_button"
|
||||||
<iconbutton id="solo_button"
|
|
||||||
width="41"
|
width="41"
|
||||||
height="20"
|
height="20"
|
||||||
normalicon="time_axis_solo"
|
normalicon="time_axis_mute"
|
||||||
activeicon="time_axis_solo_active"
|
activeicon="time_axis_mute_active"
|
||||||
implicitactiveicon="time_axis_solo_safe"
|
implicitactiveicon="time_axis_mute_implicit"
|
||||||
prelighticon="time_axis_solo_prelight"
|
prelighticon="time_axis_mute_prelight"
|
||||||
tooltip="Solo"/>
|
tooltip="Mute"/>
|
||||||
|
<Button id="master_mute_button" ui.orphan="true"/>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
</VBox>
|
||||||
|
<HBox visible="false" noshowall="true">
|
||||||
|
<Button id="show_sends_button"/>
|
||||||
|
<Button id="monitor_disk_button"/>
|
||||||
|
<Button id="comment_button"/>
|
||||||
|
<Button id="midi_input_enable_button"/>
|
||||||
|
<Button id="group_button" text="Grp"/>
|
||||||
|
<Button id="route_group_button"/>
|
||||||
|
<Button id="automation_button"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox>
|
<VBox width="1"/>
|
||||||
<VBox width="24"/>
|
<VBox id="gain_meter_home" width="7" />
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
<VBox>
|
|
||||||
<iconbutton id="monitor_input_button"
|
|
||||||
width="41"
|
|
||||||
height="20"
|
|
||||||
normalicon="time_axis_monitor_input"
|
|
||||||
activeicon="time_axis_monitor_input_active"
|
|
||||||
prelighticon="time_axis_monitor_input_prelight"
|
|
||||||
tooltip="Input Monitoring"/>
|
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
|
||||||
</VBox>
|
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
|
||||||
<VBox>
|
|
||||||
<iconbutton id="mute_button"
|
|
||||||
width="41"
|
|
||||||
height="20"
|
|
||||||
normalicon="time_axis_mute"
|
|
||||||
activeicon="time_axis_mute_active"
|
|
||||||
implicitactiveicon="time_axis_mute_implicit"
|
|
||||||
prelighticon="time_axis_mute_prelight"
|
|
||||||
tooltip="Mute"/>
|
|
||||||
<Button id="master_mute_button" ui.orphan="true"/>
|
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
|
||||||
</VBox>
|
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
|
||||||
</HBox>
|
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000" box.pack="end"/>
|
|
||||||
</VBox>
|
|
||||||
<HBox visible="false" noshowall="true">
|
|
||||||
<Button id="show_sends_button"/>
|
|
||||||
<Button id="monitor_disk_button"/>
|
|
||||||
<Button id="comment_button"/>
|
|
||||||
<Button id="midi_input_enable_button"/>
|
|
||||||
<Button id="group_button" text="Grp"/>
|
|
||||||
<Button id="route_group_button"/>
|
|
||||||
<Button id="automation_button"/>
|
|
||||||
</HBox>
|
</HBox>
|
||||||
<!--<HBox id="gain_meter_home" box.pack="end"/>-->
|
<EventBox id="lower_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3"/>
|
||||||
<VBox id="gain_meter_home" width="7">
|
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
|
||||||
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
|
</Vbox>
|
||||||
<EventBox height="1" bgnormal="#000000" bgactive="#000000" box.pack="end"/>
|
|
||||||
</VBox>
|
|
||||||
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
|
|
||||||
</HBox>
|
|
||||||
<EventBox id="lower_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3" box.pack="end"/>
|
|
||||||
</Vbox>
|
|
||||||
</RouteUI>
|
</RouteUI>
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,7 @@
|
||||||
y="4"/>
|
y="4"/>
|
||||||
<HBox id="primary_clock_home"
|
<HBox id="primary_clock_home"
|
||||||
x="132"
|
x="132"
|
||||||
y="6"/>
|
y="6"/>
|
||||||
|
|
||||||
<Button id="bit_depth_button"
|
<Button id="bit_depth_button"
|
||||||
text="bit depth"
|
text="bit depth"
|
||||||
fgnormal="#ffffff"
|
fgnormal="#ffffff"
|
||||||
|
|
@ -78,8 +77,26 @@
|
||||||
activeicon="top_bar_button"
|
activeicon="top_bar_button"
|
||||||
prelighticon="top_bar_button"/>
|
prelighticon="top_bar_button"/>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Layout box.pack="end" width="114" height="51">
|
<EventBox bgnormal="#383838"
|
||||||
<icon source="metrics_display.png"/>
|
width="17"
|
||||||
|
box.padding="1"
|
||||||
|
box.fill="true"
|
||||||
|
box.expand="true">
|
||||||
|
<HBox>
|
||||||
|
<icon source="infobar_left.png"/>
|
||||||
|
<icon source="infobar_center.png"
|
||||||
|
box.fill="true"
|
||||||
|
box.expand="true"/>
|
||||||
|
<icon source="infobar_right.png"
|
||||||
|
box.pack="end"/>
|
||||||
|
</HBox>
|
||||||
|
</EventBox>
|
||||||
|
<Layout bgnormal="#282828"
|
||||||
|
width="115"
|
||||||
|
height="51"
|
||||||
|
box.pack="end">
|
||||||
|
<icon source="metrics_display.png"
|
||||||
|
x="1"/>
|
||||||
<Adjustment id="dsp_load_adjustment"
|
<Adjustment id="dsp_load_adjustment"
|
||||||
minvalue="1"
|
minvalue="1"
|
||||||
maxvalue="100"
|
maxvalue="100"
|
||||||
|
|
@ -93,7 +110,7 @@
|
||||||
maxposx="56"
|
maxposx="56"
|
||||||
maxposy="3"
|
maxposy="3"
|
||||||
readonly="true"
|
readonly="true"
|
||||||
x="28"
|
x="29"
|
||||||
y="8"
|
y="8"
|
||||||
width="56"
|
width="56"
|
||||||
height="5"/>
|
height="5"/>
|
||||||
|
|
@ -103,7 +120,7 @@
|
||||||
fgnormal="#ffffff"
|
fgnormal="#ffffff"
|
||||||
winfont ="Arial 8"
|
winfont ="Arial 8"
|
||||||
macfont ="Helvetica 8"
|
macfont ="Helvetica 8"
|
||||||
x="87"
|
x="88"
|
||||||
y="8"/>
|
y="8"/>
|
||||||
<Adjustment id="hd_load_adjustment"
|
<Adjustment id="hd_load_adjustment"
|
||||||
minvalue="1"
|
minvalue="1"
|
||||||
|
|
@ -118,7 +135,7 @@
|
||||||
maxposx="56"
|
maxposx="56"
|
||||||
maxposy="3"
|
maxposy="3"
|
||||||
readonly="true"
|
readonly="true"
|
||||||
x="28"
|
x="29"
|
||||||
y="18"
|
y="18"
|
||||||
width="56"
|
width="56"
|
||||||
height="5"/>
|
height="5"/>
|
||||||
|
|
@ -128,7 +145,7 @@
|
||||||
fgnormal="#ffffff"
|
fgnormal="#ffffff"
|
||||||
winfont ="Arial 8"
|
winfont ="Arial 8"
|
||||||
macfont ="Helvetica 8"
|
macfont ="Helvetica 8"
|
||||||
x="87"
|
x="88"
|
||||||
y="18"/>
|
y="18"/>
|
||||||
|
|
||||||
<Label id="hd_remained_time"
|
<Label id="hd_remained_time"
|
||||||
|
|
@ -136,16 +153,11 @@
|
||||||
fgnormal="#ffffff"
|
fgnormal="#ffffff"
|
||||||
winfont ="Arial 9"
|
winfont ="Arial 9"
|
||||||
macfont ="Helvetica 9"
|
macfont ="Helvetica 9"
|
||||||
x="58"
|
x="59"
|
||||||
y="33"/>
|
y="33"/>
|
||||||
</Layout>
|
</Layout>
|
||||||
<EventBox bgnormal="#383838"
|
<VBox spacing ="1"
|
||||||
width="420"
|
box.pack="end">
|
||||||
box.padding="4">
|
|
||||||
<EventBox bgnormal="#474747"
|
|
||||||
borderwidth="1"/>
|
|
||||||
</EventBox>
|
|
||||||
<VBox spacing ="1" box.pack="end">
|
|
||||||
<iconbutton id="mode_stereo_out_button"
|
<iconbutton id="mode_stereo_out_button"
|
||||||
tooltip="Stereo Out Mode"
|
tooltip="Stereo Out Mode"
|
||||||
width="79" height="25"
|
width="79" height="25"
|
||||||
|
|
@ -183,7 +195,9 @@
|
||||||
normalicon="meter_bridge_on"
|
normalicon="meter_bridge_on"
|
||||||
activeicon="meter_bridge_on_active"
|
activeicon="meter_bridge_on_active"
|
||||||
prelighticon="meter_bridge_on_prelight"/>
|
prelighticon="meter_bridge_on_prelight"/>
|
||||||
<layout width="54" height="26" bgnormal="#3E3E3E"/>
|
<Layout width="54"
|
||||||
|
height="26"
|
||||||
|
bgnormal="#3E3E3E"/>
|
||||||
<iconbutton id="transport_start_button"
|
<iconbutton id="transport_start_button"
|
||||||
tooltip="Rewind"
|
tooltip="Rewind"
|
||||||
width="34" height="26"
|
width="34" height="26"
|
||||||
|
|
@ -226,7 +240,9 @@
|
||||||
normalicon="lock_session"
|
normalicon="lock_session"
|
||||||
activeicon="lock_session_active"
|
activeicon="lock_session_active"
|
||||||
prelighticon="lock_session_prelight"/>
|
prelighticon="lock_session_prelight"/>
|
||||||
<layout width="60" height="26" bgnormal="#3E3E3E"/>
|
<Layout width="60"
|
||||||
|
height="26"
|
||||||
|
bgnormal="#3E3E3E"/>
|
||||||
<iconbutton id="tool_marker_button"
|
<iconbutton id="tool_marker_button"
|
||||||
tooltip="Range Select Tool"
|
tooltip="Range Select Tool"
|
||||||
width="34" height="26"
|
width="34" height="26"
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,8 @@ WavesUI::create_widget (const XMLNode& definition, const XMLNodeMap& styles)
|
||||||
child = manage (new WavesButton(text));
|
child = manage (new WavesButton(text));
|
||||||
} else if (widget_type == "ICONBUTTON") {
|
} else if (widget_type == "ICONBUTTON") {
|
||||||
child = manage (new WavesIconButton);
|
child = manage (new WavesIconButton);
|
||||||
|
} else if (widget_type == "DROPDOWN") {
|
||||||
|
child = manage (new WavesDropdown);
|
||||||
} else if (widget_type == "ICON") {
|
} else if (widget_type == "ICON") {
|
||||||
std::string image_path;
|
std::string image_path;
|
||||||
Searchpath spath(ARDOUR::ardour_data_search_path());
|
Searchpath spath(ARDOUR::ardour_data_search_path());
|
||||||
|
|
@ -679,6 +681,11 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WavesDropdown* dropdown = dynamic_cast<WavesDropdown*> (&widget);
|
||||||
|
if (dropdown) {
|
||||||
|
set_attributes (dropdown->get_menu (), definition, styles);
|
||||||
|
}
|
||||||
|
|
||||||
Gtk::Table* table = dynamic_cast<Gtk::Table*> (&widget);
|
Gtk::Table* table = dynamic_cast<Gtk::Table*> (&widget);
|
||||||
if (table) {
|
if (table) {
|
||||||
table->set_col_spacings (xml_property (definition, "columnspacing", styles, 0));
|
table->set_col_spacings (xml_property (definition, "columnspacing", styles, 0));
|
||||||
|
|
@ -813,6 +820,16 @@ WavesUI::get_waves_grid (const char* id)
|
||||||
return *child;
|
return *child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WavesDropdown&
|
||||||
|
WavesUI::get_waves_dropdown (const char* id)
|
||||||
|
{
|
||||||
|
WavesDropdown* child = dynamic_cast<WavesDropdown*> (get_object(id));
|
||||||
|
if (child == NULL ) {
|
||||||
|
dbg_msg (std::string("WavesDropdown ") + id + " not found in " + _scrip_file_name + "!");
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
return *child;
|
||||||
|
}
|
||||||
Gtk::Paned&
|
Gtk::Paned&
|
||||||
WavesUI::get_paned (const char* id)
|
WavesUI::get_paned (const char* id)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "waves_grid.h"
|
#include "waves_grid.h"
|
||||||
#include "waves_button.h"
|
#include "waves_button.h"
|
||||||
#include "waves_icon_button.h"
|
#include "waves_icon_button.h"
|
||||||
|
#include "waves_dropdown.h"
|
||||||
|
|
||||||
using namespace ArdourCanvas::XMLUI;
|
using namespace ArdourCanvas::XMLUI;
|
||||||
|
|
||||||
|
|
@ -54,6 +55,7 @@ class WavesUI : public std::map<std::string, Gtk::Object*> {
|
||||||
Gtk::HBox& get_h_box (const char* id);
|
Gtk::HBox& get_h_box (const char* id);
|
||||||
Gtk::Fixed& get_fixed (const char* id);
|
Gtk::Fixed& get_fixed (const char* id);
|
||||||
WavesGrid& get_waves_grid (const char* id);
|
WavesGrid& get_waves_grid (const char* id);
|
||||||
|
WavesDropdown& get_waves_dropdown (const char* id);
|
||||||
Gtk::Paned& get_paned (const char* id);
|
Gtk::Paned& get_paned (const char* id);
|
||||||
Gtk::HPaned& get_h_paned (const char* id);
|
Gtk::HPaned& get_h_paned (const char* id);
|
||||||
Gtk::VPaned& get_v_paned (const char* id);
|
Gtk::VPaned& get_v_paned (const char* id);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ path_prefix = 'gtk2_ardour/'
|
||||||
|
|
||||||
gtk2_ardour_sources = [
|
gtk2_ardour_sources = [
|
||||||
'mixer_bridge_view.cc',
|
'mixer_bridge_view.cc',
|
||||||
|
'waves_dropdown.cc',
|
||||||
'waves_zoom_control.cc',
|
'waves_zoom_control.cc',
|
||||||
'waves_ui.cc',
|
'waves_ui.cc',
|
||||||
'waves_grid.cc',
|
'waves_grid.cc',
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,12 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
|
||||||
*/
|
*/
|
||||||
virtual int stop () = 0;
|
virtual int stop () = 0;
|
||||||
|
|
||||||
|
/** Reset device.
|
||||||
|
*
|
||||||
|
* Return zero if successful, negative values on error
|
||||||
|
*/
|
||||||
|
virtual int reset_device() = 0;
|
||||||
|
|
||||||
/** While remaining connected to the device, and without changing its
|
/** While remaining connected to the device, and without changing its
|
||||||
* configuration, start (or stop) calling the process_callback() of @param engine
|
* configuration, start (or stop) calling the process_callback() of @param engine
|
||||||
* without waiting for the device. Once process_callback() has returned, it
|
* without waiting for the device. Once process_callback() has returned, it
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,9 @@ public:
|
||||||
bool is_realtime() const;
|
bool is_realtime() const;
|
||||||
bool connected() const;
|
bool connected() const;
|
||||||
|
|
||||||
|
// for the user which hold state_lock to check if reset operation is pending
|
||||||
|
bool is_reset_requested() const { return g_atomic_int_get(&_hw_reset_request_count); }
|
||||||
|
|
||||||
int set_device_name (const std::string&);
|
int set_device_name (const std::string&);
|
||||||
int set_sample_rate (float);
|
int set_sample_rate (float);
|
||||||
int set_buffer_size (uint32_t);
|
int set_buffer_size (uint32_t);
|
||||||
|
|
@ -129,6 +132,7 @@ public:
|
||||||
bool running() const { return _running; }
|
bool running() const { return _running; }
|
||||||
|
|
||||||
Glib::Threads::Mutex& process_lock() { return _process_lock; }
|
Glib::Threads::Mutex& process_lock() { return _process_lock; }
|
||||||
|
Glib::Threads::RecMutex& state_lock() { return _state_lock; }
|
||||||
|
|
||||||
int request_buffer_size (pframes_t samples) {
|
int request_buffer_size (pframes_t samples) {
|
||||||
return set_buffer_size (samples);
|
return set_buffer_size (samples);
|
||||||
|
|
@ -169,6 +173,10 @@ public:
|
||||||
|
|
||||||
PBD::Signal1<void, pframes_t> BufferSizeChanged;
|
PBD::Signal1<void, pframes_t> BufferSizeChanged;
|
||||||
|
|
||||||
|
/* this signal is emitted if the device cannot operate properly */
|
||||||
|
|
||||||
|
PBD::Signal0<void> DeviceError;
|
||||||
|
|
||||||
/* this signal is emitted if the device list changed */
|
/* this signal is emitted if the device list changed */
|
||||||
|
|
||||||
PBD::Signal0<void> DeviceListChanged;
|
PBD::Signal0<void> DeviceListChanged;
|
||||||
|
|
@ -228,7 +236,8 @@ public:
|
||||||
|
|
||||||
static AudioEngine* _instance;
|
static AudioEngine* _instance;
|
||||||
|
|
||||||
Glib::Threads::Mutex _process_lock;
|
Glib::Threads::Mutex _process_lock;
|
||||||
|
Glib::Threads::RecMutex _state_lock;
|
||||||
Glib::Threads::Cond session_removed;
|
Glib::Threads::Cond session_removed;
|
||||||
bool session_remove_pending;
|
bool session_remove_pending;
|
||||||
frameoffset_t session_removal_countdown;
|
frameoffset_t session_removal_countdown;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@ public:
|
||||||
|
|
||||||
static EngineStateController* instance();
|
static EngineStateController* instance();
|
||||||
|
|
||||||
|
void set_session(Session* session);
|
||||||
|
void remove_session ();
|
||||||
|
|
||||||
//Interfaces
|
//Interfaces
|
||||||
void available_backends(std::vector<const AudioBackendInfo*>&);
|
void available_backends(std::vector<const AudioBackendInfo*>&);
|
||||||
|
|
||||||
|
|
@ -128,7 +131,9 @@ public:
|
||||||
PBD::Signal0<void> BufferSizeChanged;
|
PBD::Signal0<void> BufferSizeChanged;
|
||||||
/* this signal is emitted if the device list changes */
|
/* this signal is emitted if the device list changes */
|
||||||
PBD::Signal1<void, bool> DeviceListChanged;
|
PBD::Signal1<void, bool> DeviceListChanged;
|
||||||
|
/* this signal is emitted if the device cannot operate properly */
|
||||||
|
PBD::Signal0<void> DeviceError;
|
||||||
|
|
||||||
//ENGINE STATE SIGNALS
|
//ENGINE STATE SIGNALS
|
||||||
/* this signal is emitted when the engine is started */
|
/* this signal is emitted when the engine is started */
|
||||||
PBD::Signal0<void> EngineRunning;
|
PBD::Signal0<void> EngineRunning;
|
||||||
|
|
@ -260,11 +265,13 @@ private:
|
||||||
void _on_engine_running();
|
void _on_engine_running();
|
||||||
void _on_engine_halted();
|
void _on_engine_halted();
|
||||||
void _on_engine_stopped();
|
void _on_engine_stopped();
|
||||||
|
void _on_device_error();
|
||||||
void _on_sample_rate_change(ARDOUR::framecnt_t);
|
void _on_sample_rate_change(ARDOUR::framecnt_t);
|
||||||
void _on_buffer_size_change(ARDOUR::pframes_t);
|
void _on_buffer_size_change(ARDOUR::pframes_t);
|
||||||
void _on_device_list_change();
|
void _on_device_list_change();
|
||||||
void _on_parameter_changed (const std::string&);
|
void _on_parameter_changed (const std::string&);
|
||||||
void _on_ports_registration_update ();
|
void _on_ports_registration_update ();
|
||||||
|
void _on_session_loaded();
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
@ -282,12 +289,14 @@ private:
|
||||||
ARDOUR::framecnt_t _desired_sample_rate;
|
ARDOUR::framecnt_t _desired_sample_rate;
|
||||||
bool _have_control;
|
bool _have_control;
|
||||||
|
|
||||||
|
Session* _session;
|
||||||
|
|
||||||
// Engine connections stuff
|
// Engine connections stuff
|
||||||
PBD::ScopedConnectionList update_connections;
|
PBD::ScopedConnectionList update_connections;
|
||||||
|
PBD::ScopedConnectionList session_connections;
|
||||||
PBD::ScopedConnection running_connection;
|
PBD::ScopedConnection running_connection;
|
||||||
PBD::ScopedConnection halt_connection;
|
PBD::ScopedConnection halt_connection;
|
||||||
PBD::ScopedConnection stopped_connection;
|
PBD::ScopedConnection stopped_connection;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
|
||||||
|
|
||||||
PBD::Signal0<void> RecordStateChanged;
|
PBD::Signal0<void> RecordStateChanged;
|
||||||
|
|
||||||
|
/* Emited when session is loaded */
|
||||||
|
PBD::Signal0<void> SessionLoaded;
|
||||||
|
|
||||||
/* Transport mechanism signals */
|
/* Transport mechanism signals */
|
||||||
|
|
||||||
/** Emitted on the following changes in transport state:
|
/** Emitted on the following changes in transport state:
|
||||||
|
|
|
||||||
|
|
@ -405,31 +405,42 @@ AudioEngine::do_reset_backend()
|
||||||
while (!_stop_hw_reset_processing) {
|
while (!_stop_hw_reset_processing) {
|
||||||
|
|
||||||
if (_hw_reset_request_count && _backend) {
|
if (_hw_reset_request_count && _backend) {
|
||||||
|
|
||||||
|
_reset_request_lock.unlock();
|
||||||
|
|
||||||
_reset_request_lock.unlock();
|
Glib::Threads::RecMutex::Lock pl (_state_lock);
|
||||||
|
|
||||||
g_atomic_int_dec_and_test (&_hw_reset_request_count);
|
g_atomic_int_dec_and_test (&_hw_reset_request_count);
|
||||||
|
|
||||||
|
std::cout << "AudioEngine::RESET::Reset request processing" << std::endl;
|
||||||
|
|
||||||
// backup the device name
|
// backup the device name
|
||||||
std::string name = _backend->device_name ();
|
std::string name = _backend->device_name ();
|
||||||
|
|
||||||
|
std::cout << "AudioEngine::RESET::Halting session processing..." << std::endl;
|
||||||
|
if (_session && _running) {
|
||||||
|
// it's not a halt, but should be handled the same way:
|
||||||
|
// disable record, stop transport and I/O processign but save the data.
|
||||||
|
_session->engine_halted ();
|
||||||
|
}
|
||||||
|
|
||||||
stop();
|
std::cout << "AudioEngine::RESET::Stoping engine..." << std::endl;
|
||||||
if (_session) {
|
stop();
|
||||||
// it's not a halt, but should be handled the same way:
|
|
||||||
// disable record, stop transport and I/O processign but save the data.
|
std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
|
||||||
_session->engine_halted ();
|
if ( 0 == _backend->reset_device () ) {
|
||||||
}
|
|
||||||
|
std::cout << "AudioEngine::RESET::Starting engine..." << std::endl;
|
||||||
// "hard reset" the device
|
start ();
|
||||||
_backend->drop_device ();
|
|
||||||
_backend->set_device_name (name);
|
// inform about possible changes
|
||||||
|
BufferSizeChanged (_backend->buffer_size() );
|
||||||
start ();
|
} else {
|
||||||
|
DeviceError();
|
||||||
// inform about possible changes
|
}
|
||||||
SampleRateChanged (_backend->sample_rate() );
|
|
||||||
BufferSizeChanged (_backend->buffer_size() );
|
|
||||||
|
|
||||||
|
std::cout << "AudioEngine::RESET::Done." << std::endl;
|
||||||
|
|
||||||
_reset_request_lock.lock();
|
_reset_request_lock.lock();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -460,7 +471,7 @@ AudioEngine::do_devicelist_update()
|
||||||
while (!_stop_hw_devicelist_processing) {
|
while (!_stop_hw_devicelist_processing) {
|
||||||
|
|
||||||
if (_hw_devicelist_update_count) {
|
if (_hw_devicelist_update_count) {
|
||||||
|
|
||||||
_devicelist_update_lock.unlock();
|
_devicelist_update_lock.unlock();
|
||||||
|
|
||||||
g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
|
g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
|
||||||
|
|
@ -611,7 +622,7 @@ AudioEngine::died ()
|
||||||
|
|
||||||
stop_metering_thread ();
|
stop_metering_thread ();
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -1177,7 +1188,7 @@ AudioEngine::halted_callback (const char* why)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_metering_thread ();
|
stop_metering_thread ();
|
||||||
_running = false;
|
_running = false;
|
||||||
|
|
||||||
Port::PortDrop (); /* EMIT SIGNAL */
|
Port::PortDrop (); /* EMIT SIGNAL */
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,11 @@
|
||||||
#include "ardour/engine_state_controller.h"
|
#include "ardour/engine_state_controller.h"
|
||||||
|
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
#include "ardour/rc_configuration.h"
|
#include "ardour/rc_configuration.h"
|
||||||
#include "ardour/data_type.h"
|
#include "ardour/data_type.h"
|
||||||
|
|
||||||
|
#include "pbd/pthread_utils.h"
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -61,6 +63,7 @@ EngineStateController::EngineStateController()
|
||||||
AudioEngine::instance()->SampleRateChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_sample_rate_change, this, _1) );
|
AudioEngine::instance()->SampleRateChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_sample_rate_change, this, _1) );
|
||||||
AudioEngine::instance()->BufferSizeChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_buffer_size_change, this, _1) );
|
AudioEngine::instance()->BufferSizeChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_buffer_size_change, this, _1) );
|
||||||
AudioEngine::instance()->DeviceListChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_list_change, this) );
|
AudioEngine::instance()->DeviceListChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_list_change, this) );
|
||||||
|
AudioEngine::instance()->DeviceError.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_error, this) );
|
||||||
|
|
||||||
/* Global configuration parameters update */
|
/* Global configuration parameters update */
|
||||||
Config->ParameterChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_parameter_changed, this, _1) );
|
Config->ParameterChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_parameter_changed, this, _1) );
|
||||||
|
|
@ -79,8 +82,25 @@ EngineStateController::~EngineStateController()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EngineStateController::set_session(Session* session)
|
||||||
|
{
|
||||||
|
_session = session;
|
||||||
|
_session->SessionLoaded.connect_same_thread (session_connections, boost::bind (&EngineStateController::_on_session_loaded, this) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EngineStateController::remove_session ()
|
||||||
|
{
|
||||||
|
session_connections.drop_connections ();
|
||||||
|
_session = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLNode&
|
XMLNode&
|
||||||
EngineStateController::serialize_audio_midi_settings() {
|
EngineStateController::serialize_audio_midi_settings()
|
||||||
|
{
|
||||||
|
|
||||||
XMLNode* root = new XMLNode ("AudioMidiSettings");
|
XMLNode* root = new XMLNode ("AudioMidiSettings");
|
||||||
|
|
||||||
|
|
@ -92,7 +112,8 @@ EngineStateController::serialize_audio_midi_settings() {
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EngineStateController::save_audio_midi_settings() {
|
EngineStateController::save_audio_midi_settings()
|
||||||
|
{
|
||||||
Config->add_extra_xml (serialize_audio_midi_settings() );
|
Config->add_extra_xml (serialize_audio_midi_settings() );
|
||||||
Config->save_state ();
|
Config->save_state ();
|
||||||
}
|
}
|
||||||
|
|
@ -1172,6 +1193,17 @@ EngineStateController::get_physical_midi_output_states (std::vector<PortState>&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EngineStateController::_on_session_loaded ()
|
||||||
|
{
|
||||||
|
if (_session && _desired_sample_rate && set_new_sample_rate_in_controller(_desired_sample_rate) )
|
||||||
|
{
|
||||||
|
push_current_state_to_backend(false);
|
||||||
|
SampleRateChanged(); // emit a signal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate)
|
EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate)
|
||||||
{
|
{
|
||||||
|
|
@ -1181,7 +1213,7 @@ EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate)
|
||||||
framecnt_t sample_rate_to_set = new_sample_rate;
|
framecnt_t sample_rate_to_set = new_sample_rate;
|
||||||
if (AudioEngine::instance()->session() ) {
|
if (AudioEngine::instance()->session() ) {
|
||||||
// and we have current session we should restore it back to the one tracks uses
|
// and we have current session we should restore it back to the one tracks uses
|
||||||
framecnt_t sample_rate_to_set = _current_state->sample_rate;
|
sample_rate_to_set = _current_state->sample_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( set_new_sample_rate_in_controller (sample_rate_to_set) ) {
|
if ( set_new_sample_rate_in_controller (sample_rate_to_set) ) {
|
||||||
|
|
@ -1191,7 +1223,8 @@ EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate)
|
||||||
// if sample rate can't be set
|
// if sample rate can't be set
|
||||||
// switch to NONE device
|
// switch to NONE device
|
||||||
set_new_device_as_current ("None");
|
set_new_device_as_current ("None");
|
||||||
DeviceListChanged(true);
|
DeviceListChanged(false);
|
||||||
|
DeviceError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1466,6 +1499,16 @@ EngineStateController::_on_engine_halted ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EngineStateController::_on_device_error()
|
||||||
|
{
|
||||||
|
set_new_device_as_current ("None");
|
||||||
|
push_current_state_to_backend(true);
|
||||||
|
DeviceListChanged(false);
|
||||||
|
DeviceError();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EngineStateController::_on_parameter_changed (const std::string& parameter_name)
|
EngineStateController::_on_parameter_changed (const std::string& parameter_name)
|
||||||
{
|
{
|
||||||
|
|
@ -1503,26 +1546,41 @@ EngineStateController::push_current_state_to_backend(bool start)
|
||||||
|
|
||||||
bool was_running = AudioEngine::instance()->running();
|
bool was_running = AudioEngine::instance()->running();
|
||||||
|
|
||||||
|
Glib::Threads::RecMutex::Lock sl (AudioEngine::instance()->state_lock() );
|
||||||
if (state_changed) {
|
if (state_changed) {
|
||||||
|
|
||||||
if (was_running) {
|
if (was_running) {
|
||||||
if (AudioEngine::instance()->stop () ) {
|
if (AudioEngine::instance()->stop () ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
{
|
||||||
|
std::cout << "EngineStateController::Setting device: " << _current_state->device_name << std::endl;
|
||||||
|
if ((_current_state->device_name != backend->device_name()) && (result = backend->set_device_name (_current_state->device_name)) ) {
|
||||||
|
error << string_compose (_("Cannot set device name to %1"), get_current_device_name()) << endmsg;
|
||||||
|
}
|
||||||
|
|
||||||
if ((_current_state->device_name != backend->device_name()) && backend->set_device_name (_current_state->device_name)) {
|
std::cout << "EngineStateController::Setting device sample rate " << _current_state->sample_rate << std::endl;
|
||||||
error << string_compose (_("Cannot set device name to %1"), get_current_device_name()) << endmsg;
|
if (!result && (result = backend->set_sample_rate (_current_state->sample_rate)) ) {
|
||||||
}
|
error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate()) << endmsg;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend->set_sample_rate (_current_state->sample_rate )) {
|
std::cout << "EngineStateController::Setting device buffer size " << _current_state->buffer_size << std::endl;
|
||||||
error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate()) << endmsg;
|
if (!result && (result = backend->set_buffer_size (_current_state->buffer_size)) ) {
|
||||||
}
|
error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size()) << endmsg;
|
||||||
|
}
|
||||||
if (backend->set_buffer_size (_current_state->buffer_size )) {
|
}
|
||||||
error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size()) << endmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (result) // error during device setup
|
||||||
|
{
|
||||||
|
//switch to None device and notify about the issue
|
||||||
|
set_new_device_as_current ("None");
|
||||||
|
DeviceListChanged(false);
|
||||||
|
DeviceError();
|
||||||
|
}
|
||||||
|
|
||||||
//if (backend->set_input_channels (get_input_channels())) {
|
//if (backend->set_input_channels (get_input_channels())) {
|
||||||
// error << string_compose (_("Cannot set input channels to %1"), get_input_channels()) << endmsg;
|
// error << string_compose (_("Cannot set input channels to %1"), get_input_channels()) << endmsg;
|
||||||
// return -1;
|
// return -1;
|
||||||
|
|
@ -1545,7 +1603,12 @@ EngineStateController::push_current_state_to_backend(bool start)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(start || (was_running && state_changed) ) {
|
if(start || (was_running && state_changed) ) {
|
||||||
if (AudioEngine::instance()->start () ) {
|
if (AudioEngine::instance()->start () && !AudioEngine::instance()->is_reset_requested() ) {
|
||||||
|
//switch to None device and notify about the issue
|
||||||
|
set_new_device_as_current ("None");
|
||||||
|
AudioEngine::instance()->start ();
|
||||||
|
DeviceListChanged(false);
|
||||||
|
DeviceError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1562,12 +1625,7 @@ EngineStateController::set_desired_sample_rate(framecnt_t session_desired_sr)
|
||||||
if (session_desired_sr == 0 || session_desired_sr == _desired_sample_rate) {
|
if (session_desired_sr == 0 || session_desired_sr == _desired_sample_rate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_desired_sample_rate = session_desired_sr;
|
_desired_sample_rate = session_desired_sr;
|
||||||
|
|
||||||
// if we swithced to new desired sample rate successfuly - push the new state to the backend
|
|
||||||
if (set_new_sample_rate_in_controller (session_desired_sr) ) {
|
|
||||||
push_current_state_to_backend(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,12 @@ Port::get_connections (std::vector<std::string> & c) const
|
||||||
return c.size();
|
return c.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
return port_engine.get_connections (_port_handle, c);
|
if (_port_handle) {
|
||||||
|
port_engine.get_connections (_port_handle, c);
|
||||||
|
return c.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -369,6 +369,8 @@ Session::Session (AudioEngine &eng,
|
||||||
_engine.set_session (this);
|
_engine.set_session (this);
|
||||||
_engine.reset_timebase ();
|
_engine.reset_timebase ();
|
||||||
|
|
||||||
|
EngineStateController::instance()->set_session(this);
|
||||||
|
|
||||||
// Waves Tracks: always create master track
|
// Waves Tracks: always create master track
|
||||||
if ( ARDOUR::Profile->get_trx () ) {
|
if ( ARDOUR::Profile->get_trx () ) {
|
||||||
create_master_track();
|
create_master_track();
|
||||||
|
|
@ -419,6 +421,7 @@ Session::Session (AudioEngine &eng,
|
||||||
|
|
||||||
_is_new = false;
|
_is_new = false;
|
||||||
|
|
||||||
|
SessionLoaded();
|
||||||
BootMessage (_("Session loading complete"));
|
BootMessage (_("Session loading complete"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -524,6 +527,7 @@ Session::destroy ()
|
||||||
drop_connections ();
|
drop_connections ();
|
||||||
|
|
||||||
_engine.remove_session ();
|
_engine.remove_session ();
|
||||||
|
EngineStateController::instance()->remove_session();
|
||||||
|
|
||||||
/* deregister all ports - there will be no process or any other
|
/* deregister all ports - there will be no process or any other
|
||||||
* callbacks from the engine any more.
|
* callbacks from the engine any more.
|
||||||
|
|
|
||||||
|
|
@ -446,6 +446,10 @@ WavesAudioBackend::set_buffer_size (uint32_t buffer_size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if call to set buffer is successful but device buffer size differs from the value we tried to set
|
||||||
|
// this means we are driven by device for buffer size
|
||||||
|
buffer_size = _device->CurrentBufferSize ();
|
||||||
|
|
||||||
_buffer_size_change(buffer_size);
|
_buffer_size_change(buffer_size);
|
||||||
|
|
||||||
if (device_needs_restart) {
|
if (device_needs_restart) {
|
||||||
|
|
@ -472,9 +476,9 @@ WavesAudioBackend::set_sample_format (SampleFormat sample_format)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
WavesAudioBackend::_reset_device (uint32_t buffer_size, float sample_rate)
|
WavesAudioBackend::reset_device ()
|
||||||
{
|
{
|
||||||
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device (" << buffer_size <<", " << sample_rate << "):" << std::endl;
|
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl;
|
||||||
|
|
||||||
WTErr retVal = eNoErr;
|
WTErr retVal = eNoErr;
|
||||||
|
|
||||||
|
|
@ -483,95 +487,7 @@ WavesAudioBackend::_reset_device (uint32_t buffer_size, float sample_rate)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_needs_restart = _device->Streaming ();
|
return _device->ResetDevice();
|
||||||
|
|
||||||
if (device_needs_restart) {
|
|
||||||
retVal = _device->SetStreaming (false);
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (false);"<< std::endl;
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::_reset_device (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
retVal = _device->SetActive (false);
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetActive (false);"<< std::endl;
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::_reset_device (): [" << _device->DeviceName () << "]->SetActive (false) failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
retVal = _device->UpdateDeviceInfo ();
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::_reset_device (): [" << _device->DeviceName() << "]->UpdateDeviceInfo () failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer_size != 0)
|
|
||||||
{
|
|
||||||
retVal = _device->SetCurrentBufferSize (buffer_size);
|
|
||||||
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::_reset_device (): [" << _device->DeviceName() << "]->SetCurrentBufferSize (" << buffer_size << ") failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_buffer_size = buffer_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t current_buffer_size = _device->CurrentBufferSize();
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\tcurrent_buffer_size: " << current_buffer_size << std::endl;
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\t _buffer_size: " << _buffer_size << std::endl;
|
|
||||||
if(_buffer_size != current_buffer_size)
|
|
||||||
{
|
|
||||||
_buffer_size = current_buffer_size;
|
|
||||||
engine.buffer_size_change (_buffer_size);
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\tengine.buffer_size_change (" << buffer_size <<")" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sample_rate > 0.0)
|
|
||||||
{
|
|
||||||
retVal = _device->SetCurrentSamplingRate ((int)sample_rate);
|
|
||||||
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName() << "]->SetCurrentSamplingRate ((int)" << sample_rate << ") failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
_sample_rate = sample_rate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float current_sample_rate = _device->CurrentSamplingRate();
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\tcurrent_sample_rate: " << current_sample_rate << std::endl;
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\t _sample_rate: " << _sample_rate << std::endl;
|
|
||||||
if(_sample_rate != current_sample_rate)
|
|
||||||
{
|
|
||||||
_sample_rate = current_sample_rate;
|
|
||||||
engine.sample_rate_change (_sample_rate);
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\tengine.sample_rate_change (" << _sample_rate <<")" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_init_dsp_load_history();
|
|
||||||
|
|
||||||
if (device_needs_restart) {
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetActive (true);"<< std::endl;
|
|
||||||
retVal = _device->SetActive (true);
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::_reset_device (): [" << _device->DeviceName () << "]->SetActive (true) failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl;
|
|
||||||
_call_thread_init_callback = true;
|
|
||||||
retVal = _device->SetStreaming (true);
|
|
||||||
if (retVal != eNoErr) {
|
|
||||||
std::cerr << "WavesAudioBackend::_reset_device (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,10 @@ class WavesMidiPort;
|
||||||
virtual int set_systemic_output_latency (uint32_t);
|
virtual int set_systemic_output_latency (uint32_t);
|
||||||
|
|
||||||
int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; }
|
int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; }
|
||||||
|
|
||||||
int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; }
|
int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; }
|
||||||
|
|
||||||
|
virtual int reset_device ();
|
||||||
|
|
||||||
virtual std::string device_name () const;
|
virtual std::string device_name () const;
|
||||||
|
|
||||||
virtual float sample_rate () const;
|
virtual float sample_rate () const;
|
||||||
|
|
@ -345,7 +346,6 @@ class WavesMidiPort;
|
||||||
pframes_t sample_time,
|
pframes_t sample_time,
|
||||||
uint64_t cycle_start_time_nanos);
|
uint64_t cycle_start_time_nanos);
|
||||||
|
|
||||||
int _reset_device (uint32_t buffer_size, float sample_rate);
|
|
||||||
void _changed_midi_devices ();
|
void _changed_midi_devices ();
|
||||||
|
|
||||||
// DO change sample rate and buffer size
|
// DO change sample rate and buffer size
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ WavesAudioBackend::physically_connected (PortHandle port_handle, bool process_ca
|
||||||
int
|
int
|
||||||
WavesAudioBackend::get_connections (PortHandle port_handle, std::vector<std::string>& names, bool process_callback_safe)
|
WavesAudioBackend::get_connections (PortHandle port_handle, std::vector<std::string>& names, bool process_callback_safe)
|
||||||
{
|
{
|
||||||
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_connections ()" << std::endl;
|
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_connections ()" << std::endl;
|
||||||
|
|
||||||
if (!_registered (port_handle)) {
|
if (!_registered (port_handle)) {
|
||||||
std::cerr << "WavesAudioBackend::get_connections (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;
|
std::cerr << "WavesAudioBackend::get_connections (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,28 @@ WTErr WCMRAudioDevice::SetStreaming (bool newState)
|
||||||
return (eNoErr);
|
return (eNoErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WTErr WCMRAudioDevice::ResetDevice ()
|
||||||
|
{
|
||||||
|
// Keep device sates
|
||||||
|
bool wasStreaming = Streaming();
|
||||||
|
bool wasActive = Active();
|
||||||
|
|
||||||
|
WTErr err = SetStreaming(false);
|
||||||
|
|
||||||
|
if (err == eNoErr)
|
||||||
|
SetActive(false);
|
||||||
|
|
||||||
|
if (err == eNoErr && wasActive)
|
||||||
|
SetActive(true);
|
||||||
|
|
||||||
|
if (err == eNoErr && wasStreaming)
|
||||||
|
SetStreaming(true);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// IsProcessActive - returns true if process code is running.
|
// IsProcessActive - returns true if process code is running.
|
||||||
// A normal audio device should return the Streaming() value
|
// A normal audio device should return the Streaming() value
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,8 @@ public:
|
||||||
virtual bool Streaming();///<Streaming Status?
|
virtual bool Streaming();///<Streaming Status?
|
||||||
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
|
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
|
||||||
|
|
||||||
|
virtual WTErr ResetDevice ();
|
||||||
|
|
||||||
virtual bool IsProcessActive();
|
virtual bool IsProcessActive();
|
||||||
|
|
||||||
virtual WTErr DoIdle();///<Do Idle Processing
|
virtual WTErr DoIdle();///<Do Idle Processing
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,16 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <list>
|
||||||
using namespace wvNS;
|
using namespace wvNS;
|
||||||
#include "IncludeWindows.h"
|
#include "IncludeWindows.h"
|
||||||
#include <MMSystem.h>
|
#include <MMSystem.h>
|
||||||
#include "pa_asio.h"
|
#include "pa_asio.h"
|
||||||
#include "asio.h"
|
#include "asio.h"
|
||||||
|
|
||||||
#define PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS 200
|
#define PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS 500
|
||||||
#define PROPERTY_CHANGE_TIMEOUT_SECONDS 2
|
#define PROPERTY_CHANGE_TIMEOUT_SECONDS 2
|
||||||
|
#define PROPERTY_CHANGE_RETRIES 3
|
||||||
|
|
||||||
///< Supported Sample rates
|
///< Supported Sample rates
|
||||||
static const double gAllSampleRates[] =
|
static const double gAllSampleRates[] =
|
||||||
|
|
@ -308,14 +310,12 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
|
||||||
//update name.
|
//update name.
|
||||||
m_DeviceName = pDeviceInfo->name;
|
m_DeviceName = pDeviceInfo->name;
|
||||||
|
|
||||||
std::cout << "API::Device " << m_DeviceName << " Getting device info " << std::endl;
|
|
||||||
|
|
||||||
//following parameters are needed opening test stream and for sample rates validation
|
//following parameters are needed opening test stream and for sample rates validation
|
||||||
PaStreamParameters inputParameters, outputParameters;
|
PaStreamParameters inputParameters, outputParameters;
|
||||||
PaStreamParameters *pInS = NULL, *pOutS = NULL;
|
PaStreamParameters *pInS = NULL, *pOutS = NULL;
|
||||||
|
|
||||||
inputParameters.device = m_DeviceID;
|
inputParameters.device = m_DeviceID;
|
||||||
inputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxInputChannels);
|
inputParameters.channelCount = pDeviceInfo->maxInputChannels;
|
||||||
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
|
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
|
||||||
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
|
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
|
||||||
inputParameters.hostApiSpecificStreamInfo = 0;
|
inputParameters.hostApiSpecificStreamInfo = 0;
|
||||||
|
|
@ -324,7 +324,7 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
|
||||||
pInS = &inputParameters;
|
pInS = &inputParameters;
|
||||||
|
|
||||||
outputParameters.device = m_DeviceID;
|
outputParameters.device = m_DeviceID;
|
||||||
outputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxOutputChannels);
|
outputParameters.channelCount = pDeviceInfo->maxOutputChannels;
|
||||||
outputParameters.sampleFormat = paFloat32;
|
outputParameters.sampleFormat = paFloat32;
|
||||||
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
|
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
|
||||||
outputParameters.hostApiSpecificStreamInfo = 0;
|
outputParameters.hostApiSpecificStreamInfo = 0;
|
||||||
|
|
@ -332,7 +332,6 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
|
||||||
if (outputParameters.channelCount)
|
if (outputParameters.channelCount)
|
||||||
pOutS = &outputParameters;
|
pOutS = &outputParameters;
|
||||||
|
|
||||||
std::cout << "API::Device" << m_DeviceName << " Updating sample rates " << std::endl;
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
//update list of supported SRs...
|
//update list of supported SRs...
|
||||||
m_SamplingRates.clear();
|
m_SamplingRates.clear();
|
||||||
|
|
@ -348,54 +347,27 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "API::Device" << m_DeviceName << " Updating buffer sizes" << std::endl;
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
//update buffer sizes
|
//update buffer sizes
|
||||||
m_BufferSizes.clear();
|
m_BufferSizes.clear();
|
||||||
bool useDefaultBuffers = true;
|
bool useDefaultBuffers = true;
|
||||||
PaError paErr = paNoError;
|
|
||||||
|
|
||||||
//sometimes devices change buffer size if sample rate changes
|
// In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel
|
||||||
//it updates buffer size during stream opening
|
long minSize, maxSize, preferredSize, granularity;
|
||||||
//we need to find out how device would behave with current sample rate
|
PaError err = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
|
||||||
//try opening test stream to load device driver for current sample rate and buffer size
|
|
||||||
//(skip this step if the device is Active)
|
|
||||||
if ( !Active() )
|
|
||||||
{
|
|
||||||
if (paNoError != testStateValidness(m_CurrentSamplingRate, m_CurrentBufferSize) )
|
|
||||||
{
|
|
||||||
//buffer size did change
|
|
||||||
Pa_Terminate();
|
|
||||||
Pa_Initialize();
|
|
||||||
|
|
||||||
// test validness with current sample rate and device prefered buffer size
|
|
||||||
paErr = testStateValidness(m_CurrentSamplingRate, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paErr == paNoError)
|
|
||||||
{
|
|
||||||
// In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel
|
|
||||||
long minSize, maxSize, preferredSize, granularity;
|
|
||||||
paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
|
|
||||||
|
|
||||||
if (paErr == paNoError)
|
if (err == paNoError)
|
||||||
{
|
{
|
||||||
std::cout << "API::Device " << m_DeviceName << " Buffers: " << minSize << " " << maxSize << " " << preferredSize << std::endl;
|
std::cout << "API::Device " << m_DeviceName << " Buffers: " << minSize << " " << maxSize << " " << preferredSize << std::endl;
|
||||||
|
|
||||||
m_BufferSizes.push_back (preferredSize);
|
m_BufferSizes.push_back (preferredSize);
|
||||||
useDefaultBuffers = false;
|
useDefaultBuffers = false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "API::Device" << m_DeviceName << " Preffered buffer size is not supported" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "API::Device" << m_DeviceName << " Device does not start with sample rate: "<< m_CurrentSamplingRate << " and default buffer size" << std::endl;
|
std::cout << "API::Device" << m_DeviceName << " Preffered buffer size is not supported" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useDefaultBuffers)
|
if (useDefaultBuffers)
|
||||||
{
|
{
|
||||||
std::cout << "API::Device" << m_DeviceName << " Using default buffer sizes " <<std::endl;
|
std::cout << "API::Device" << m_DeviceName << " Using default buffer sizes " <<std::endl;
|
||||||
|
|
@ -476,18 +448,18 @@ PaError WCMRPortAudioDevice::testStateValidness(int sampleRate, int bufferSize)
|
||||||
PaStreamParameters *pInS = NULL, *pOutS = NULL;
|
PaStreamParameters *pInS = NULL, *pOutS = NULL;
|
||||||
|
|
||||||
inputParameters.device = m_DeviceID;
|
inputParameters.device = m_DeviceID;
|
||||||
inputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxInputChannels);
|
inputParameters.channelCount = pDeviceInfo->maxInputChannels;
|
||||||
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
|
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
|
||||||
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
|
inputParameters.suggestedLatency = 0;
|
||||||
inputParameters.hostApiSpecificStreamInfo = 0;
|
inputParameters.hostApiSpecificStreamInfo = 0;
|
||||||
|
|
||||||
if (inputParameters.channelCount)
|
if (inputParameters.channelCount)
|
||||||
pInS = &inputParameters;
|
pInS = &inputParameters;
|
||||||
|
|
||||||
outputParameters.device = m_DeviceID;
|
outputParameters.device = m_DeviceID;
|
||||||
outputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxOutputChannels);
|
outputParameters.channelCount = pDeviceInfo->maxOutputChannels;
|
||||||
outputParameters.sampleFormat = paFloat32;
|
outputParameters.sampleFormat = paFloat32;
|
||||||
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
|
outputParameters.suggestedLatency = 0;
|
||||||
outputParameters.hostApiSpecificStreamInfo = 0;
|
outputParameters.hostApiSpecificStreamInfo = 0;
|
||||||
|
|
||||||
if (outputParameters.channelCount)
|
if (outputParameters.channelCount)
|
||||||
|
|
@ -499,7 +471,7 @@ PaError WCMRPortAudioDevice::testStateValidness(int sampleRate, int bufferSize)
|
||||||
//it updates buffer size during stream opening
|
//it updates buffer size during stream opening
|
||||||
//we need to find out how device would behave with current sample rate
|
//we need to find out how device would behave with current sample rate
|
||||||
//try opening test stream to load device driver for current sample rate and buffer size
|
//try opening test stream to load device driver for current sample rate and buffer size
|
||||||
paErr = Pa_OpenStream (&portAudioStream, pInS, pOutS, m_CurrentSamplingRate, m_CurrentBufferSize, paDitherOff, NULL, NULL);
|
paErr = Pa_OpenStream (&portAudioStream, pInS, pOutS, sampleRate, bufferSize, paDitherOff, NULL, NULL);
|
||||||
|
|
||||||
if (portAudioStream)
|
if (portAudioStream)
|
||||||
{
|
{
|
||||||
|
|
@ -628,35 +600,17 @@ WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate)
|
||||||
return (retVal);
|
return (retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldActive)
|
|
||||||
{
|
|
||||||
//Deactivate it for the change...
|
|
||||||
SetActive (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//make the change...
|
//make the change...
|
||||||
m_CurrentSamplingRate = newRate;
|
m_CurrentSamplingRate = newRate;
|
||||||
|
PaError paErr = PaAsio_SetStreamSampleRate (m_PortAudioStream, m_CurrentSamplingRate);
|
||||||
|
|
||||||
// Before reactivating the device: opening stream we should try getting buffer size update from the device
|
if (paErr != paNoError)
|
||||||
// because for new sampling rate some devices may change buffer size as well
|
|
||||||
int oldBufferSize = m_CurrentBufferSize;
|
|
||||||
|
|
||||||
retVal = ResetDevice();
|
|
||||||
|
|
||||||
//reactivate it.
|
|
||||||
if (oldActive && retVal == eNoErr)
|
|
||||||
{
|
{
|
||||||
retVal = SetActive (true);
|
std::cout << "Sample rate change failed, cannot start with error: " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
}
|
if (paErr == paUnanticipatedHostError)
|
||||||
|
std::cout << "Details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl;
|
||||||
|
|
||||||
if (retVal != eNoErr)
|
retVal = eWrongObjectState;
|
||||||
{
|
|
||||||
//revert changes if the device was not activated
|
|
||||||
m_CurrentSamplingRate = oldRate;
|
|
||||||
m_CurrentBufferSize = oldBufferSize;
|
|
||||||
int bufferSize = m_CurrentBufferSize;
|
|
||||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
|
|
||||||
retVal = eCommandLineParameter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (retVal);
|
return (retVal);
|
||||||
|
|
@ -705,6 +659,15 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
|
||||||
if (oldSize == newSize)
|
if (oldSize == newSize)
|
||||||
return (retVal);
|
return (retVal);
|
||||||
|
|
||||||
|
if (Streaming())
|
||||||
|
{
|
||||||
|
//Can't change, perhaps use an "in use" type of error
|
||||||
|
retVal = eGenericErr;
|
||||||
|
return (retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Setting buffer: " << newSize << std::endl;
|
||||||
|
|
||||||
//see if this is one of our supported rates...
|
//see if this is one of our supported rates...
|
||||||
intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), newSize);
|
intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), newSize);
|
||||||
if (intIter == m_BufferSizes.end())
|
if (intIter == m_BufferSizes.end())
|
||||||
|
|
@ -714,10 +677,12 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
|
||||||
{
|
{
|
||||||
// we have only one aloved buffer size which is preffered by PA
|
// we have only one aloved buffer size which is preffered by PA
|
||||||
// this is the only value which could be set
|
// this is the only value which could be set
|
||||||
m_CurrentBufferSize = m_BufferSizes[0];
|
newSize = m_BufferSizes[0];
|
||||||
int bufferSize = m_CurrentBufferSize;
|
int bufferSize = newSize;
|
||||||
// notify client to update sample rate after us
|
// notify client to update sample rate after us
|
||||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
|
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
|
||||||
|
return retVal;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// more then one buffer size value is available
|
// more then one buffer size value is available
|
||||||
//Can't change, perhaps use an "invalid param" type of error
|
//Can't change, perhaps use an "invalid param" type of error
|
||||||
|
|
@ -726,13 +691,6 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Streaming())
|
|
||||||
{
|
|
||||||
//Can't change, perhaps use an "in use" type of error
|
|
||||||
retVal = eGenericErr;
|
|
||||||
return (retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldActive)
|
if (oldActive)
|
||||||
{
|
{
|
||||||
//Deactivate it for the change...
|
//Deactivate it for the change...
|
||||||
|
|
@ -789,6 +747,17 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
|
||||||
// if device is not active activate it
|
// if device is not active activate it
|
||||||
if (!Active() )
|
if (!Active() )
|
||||||
{
|
{
|
||||||
|
std::list<long> buffersSizes;
|
||||||
|
buffersSizes.push_back(m_CurrentBufferSize);
|
||||||
|
|
||||||
|
long minSize, maxSize, preferredSize, granularity;
|
||||||
|
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
|
||||||
|
|
||||||
|
if (paErr == paNoError)
|
||||||
|
{
|
||||||
|
buffersSizes.push_front(preferredSize);
|
||||||
|
}
|
||||||
|
|
||||||
PaStreamParameters inputParameters, outputParameters;
|
PaStreamParameters inputParameters, outputParameters;
|
||||||
PaStreamParameters *pInS = NULL, *pOutS = NULL;
|
PaStreamParameters *pInS = NULL, *pOutS = NULL;
|
||||||
|
|
||||||
|
|
@ -812,12 +781,13 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
|
||||||
|
|
||||||
if (outputParameters.channelCount)
|
if (outputParameters.channelCount)
|
||||||
pOutS = &outputParameters;
|
pOutS = &outputParameters;
|
||||||
|
|
||||||
std::cout << "API::Device" << m_DeviceName << " Opening device stream " << std::endl;
|
// try opening stream with current buffer and the rest if not successful
|
||||||
std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << m_CurrentBufferSize << std::endl;
|
std::list<long>::const_iterator bufferIter = buffersSizes.begin();
|
||||||
|
for (; bufferIter != buffersSizes.end(); ++bufferIter) {
|
||||||
int tryAgain = ((PROPERTY_CHANGE_TIMEOUT_SECONDS * 1000) / PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS) ;
|
|
||||||
while (tryAgain) {
|
std::cout << "API::Device" << m_DeviceName << " Opening device stream " << std::endl;
|
||||||
|
std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << *bufferIter << std::endl;
|
||||||
paErr = Pa_OpenStream(&m_PortAudioStream,
|
paErr = Pa_OpenStream(&m_PortAudioStream,
|
||||||
pInS,
|
pInS,
|
||||||
pOutS,
|
pOutS,
|
||||||
|
|
@ -826,20 +796,31 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
|
||||||
paDitherOff,
|
paDitherOff,
|
||||||
WCMRPortAudioDevice::TheCallback,
|
WCMRPortAudioDevice::TheCallback,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
if(paErr == paNoError)
|
if(paErr == paNoError)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Cannot open streamm sleeping for "<< PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS << "msec and trying again" << std::endl;
|
std::cout << "Cannot open streamm with buffer: "<< *bufferIter << " Error: " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
|
|
||||||
// sleep and try again
|
if (paErr == paUnanticipatedHostError)
|
||||||
wvThread::sleep_milliseconds (PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS);
|
std::cout << "Error details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl;
|
||||||
--tryAgain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(paErr == paNoError)
|
if(paErr == paNoError)
|
||||||
{
|
{
|
||||||
|
long minSize, maxSize, preferredSize, granularity;
|
||||||
|
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
|
||||||
|
|
||||||
|
if (paErr == paNoError && m_CurrentBufferSize != preferredSize)
|
||||||
|
{
|
||||||
|
m_CurrentBufferSize = preferredSize;
|
||||||
|
m_BufferSizes.clear();
|
||||||
|
m_BufferSizes.push_back(preferredSize);
|
||||||
|
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&preferredSize);
|
||||||
|
}
|
||||||
|
|
||||||
m_DropsDetected = 0;
|
m_DropsDetected = 0;
|
||||||
m_DropsReported = 0;
|
m_DropsReported = 0;
|
||||||
m_IgnoreThisDrop = true;
|
m_IgnoreThisDrop = true;
|
||||||
|
|
@ -861,8 +842,8 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//failed, do not update device state
|
//failed, do not update device state
|
||||||
std::cout << "Failed to open pa stream " << paErr << std::endl;
|
std::cout << "Failed to open pa stream: " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
DEBUG_MSG( "Failed to open pa stream " << paErr );
|
DEBUG_MSG( "Failed to open pa stream: " << Pa_GetErrorText (paErr) );
|
||||||
m_ConnectionStatus = DeviceErrors;
|
m_ConnectionStatus = DeviceErrors;
|
||||||
m_lastErr = eAsioFailed;
|
m_lastErr = eAsioFailed;
|
||||||
}
|
}
|
||||||
|
|
@ -922,8 +903,8 @@ void WCMRPortAudioDevice::deactivateDevice (bool callerIsWaiting/*=false*/)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//failed, do not update device state
|
//failed, do not update device state
|
||||||
std::cout << "Failed to close pa stream stream " << paErr << std::endl;
|
std::cout << "Failed to close pa stream stream " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
DEBUG_MSG( "Failed to open pa stream stream " << paErr );
|
DEBUG_MSG( "Failed to open pa stream stream " << Pa_GetErrorText (paErr) );
|
||||||
m_ConnectionStatus = DeviceErrors;
|
m_ConnectionStatus = DeviceErrors;
|
||||||
m_lastErr = eAsioFailed;
|
m_lastErr = eAsioFailed;
|
||||||
}
|
}
|
||||||
|
|
@ -954,17 +935,25 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
|
||||||
m_SampleCounter = 0;
|
m_SampleCounter = 0;
|
||||||
|
|
||||||
std::cout << "API::Device" << m_DeviceName << " Starting device stream" << std::endl;
|
std::cout << "API::Device" << m_DeviceName << " Starting device stream" << std::endl;
|
||||||
|
|
||||||
|
//get device info
|
||||||
|
const PaDeviceInfo *pDeviceInfo = Pa_GetDeviceInfo(m_DeviceID);
|
||||||
|
|
||||||
|
unsigned int inChannelCount = pDeviceInfo->maxInputChannels;
|
||||||
|
unsigned int outChannelCount = pDeviceInfo->maxOutputChannels;
|
||||||
|
|
||||||
paErr = Pa_StartStream( m_PortAudioStream );
|
paErr = Pa_StartStream( m_PortAudioStream );
|
||||||
|
|
||||||
if(paErr == paNoError)
|
if(paErr == paNoError)
|
||||||
{
|
{
|
||||||
// if the stream was started successfully
|
// if the stream was started successfully
|
||||||
m_IsStreaming = true;
|
m_IsStreaming = true;
|
||||||
|
std::cout << "API::Device" << m_DeviceName << " Device is streaming" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Failed to start PA stream: " << paErr << std::endl;
|
std::cout << "Failed to start PA stream: " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
DEBUG_MSG( "Failed to start PA stream: " << paErr );
|
DEBUG_MSG( "Failed to start PA stream: " << Pa_GetErrorText (paErr) );
|
||||||
m_lastErr = eGenericErr;
|
m_lastErr = eGenericErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1002,8 +991,8 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Failed to stop PA stream: " << paErr << std::endl;
|
std::cout << "Failed to stop PA stream: " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
DEBUG_MSG( "Failed to stop PA stream " << paErr );
|
DEBUG_MSG( "Failed to stop PA stream " << Pa_GetErrorText (paErr) );
|
||||||
m_lastErr = eGenericErr;
|
m_lastErr = eGenericErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1028,6 +1017,8 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
|
||||||
{
|
{
|
||||||
std::cout << "API::Device" << m_DeviceName << "Reseting device" << std::endl;
|
std::cout << "API::Device" << m_DeviceName << "Reseting device" << std::endl;
|
||||||
|
|
||||||
|
PaError paErr = paNoError;
|
||||||
|
|
||||||
// Keep device sates
|
// Keep device sates
|
||||||
bool wasStreaming = Streaming();
|
bool wasStreaming = Streaming();
|
||||||
bool wasActive = Active();
|
bool wasActive = Active();
|
||||||
|
|
@ -1036,49 +1027,72 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
|
||||||
stopStreaming();
|
stopStreaming();
|
||||||
deactivateDevice();
|
deactivateDevice();
|
||||||
|
|
||||||
// Reinitialize PA
|
|
||||||
Pa_Terminate();
|
|
||||||
Pa_Initialize();
|
|
||||||
|
|
||||||
updateDeviceInfo();
|
|
||||||
|
|
||||||
// Cache device buffer size as it might be changed during reset
|
// Cache device buffer size as it might be changed during reset
|
||||||
int oldBufferSize = m_CurrentBufferSize;
|
int oldBufferSize = m_CurrentBufferSize;
|
||||||
|
|
||||||
// In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel
|
// Now, validate the state and update device info if required
|
||||||
// Backend should always use preffered buffer size value in this case
|
unsigned int retry = PROPERTY_CHANGE_RETRIES;
|
||||||
long minSize, maxSize, preferredSize, granularity;
|
while (retry-- )
|
||||||
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
|
{
|
||||||
|
// Reinitialize PA
|
||||||
|
Pa_Terminate();
|
||||||
|
Pa_Initialize();
|
||||||
|
|
||||||
|
std::cout << "Updating device state... " << std::endl;
|
||||||
|
// update device info
|
||||||
|
updateDeviceInfo();
|
||||||
|
|
||||||
|
// take up buffers
|
||||||
|
long minSize, maxSize, preferredSize, granularity;
|
||||||
|
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
|
||||||
|
|
||||||
|
if (paErr != paNoError)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_CurrentBufferSize = preferredSize;
|
||||||
|
|
||||||
|
paErr = testStateValidness(m_CurrentSamplingRate, m_CurrentBufferSize);
|
||||||
|
if (paNoError == paErr)
|
||||||
|
{
|
||||||
|
std::cout << "Device state is valid" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Cannot start with current state: sr: " << m_CurrentSamplingRate << " bs:" << m_CurrentBufferSize \
|
||||||
|
<< "\nReason: " << Pa_GetErrorText (paErr) << std::endl;
|
||||||
|
if (paErr == paUnanticipatedHostError)
|
||||||
|
std::cout << "Details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Will try again in " << PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS << "msec" << std::endl;
|
||||||
|
|
||||||
|
Pa_Sleep(PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
if (paErr == paNoError)
|
if (paErr == paNoError)
|
||||||
{
|
{
|
||||||
m_CurrentBufferSize = preferredSize;
|
// Notify the Application about device setting changes
|
||||||
}
|
if (oldBufferSize != m_CurrentBufferSize)
|
||||||
else
|
{
|
||||||
{
|
std::cout << "API::Device" << m_DeviceName << " buffer size changed" << std::endl;
|
||||||
// if we can't get device buffer sizes, use the first one among supported
|
int bufferSize = m_CurrentBufferSize;
|
||||||
if (m_BufferSizes.size() != 0)
|
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
|
||||||
m_CurrentBufferSize = m_BufferSizes.front();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the Application about device setting changes
|
// Activate the device if it was active before
|
||||||
if (oldBufferSize != m_CurrentBufferSize)
|
if (wasActive)
|
||||||
{
|
activateDevice();
|
||||||
std::cout << "API::Device" << m_DeviceName << " buffer size changed" << std::endl;
|
|
||||||
int bufferSize = m_CurrentBufferSize;
|
|
||||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate the device if it was active before
|
// Resume streaming if the device was streaming before
|
||||||
if (wasActive)
|
if(wasStreaming && m_lastErr == eNoErr && m_ConnectionStatus == DeviceAvailable)
|
||||||
activateDevice();
|
{
|
||||||
|
// Notify the Application to prepare for the stream start
|
||||||
// Resume streaming if the device was streaming before
|
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
|
||||||
if(wasStreaming)
|
startStreaming();
|
||||||
{
|
}
|
||||||
// Notify the Application to prepare for the stream start
|
} else {
|
||||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
|
m_ConnectionStatus = DeviceErrors;
|
||||||
startStreaming();
|
m_lastErr = eWrongObjectState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callerIsWaiting)
|
if (callerIsWaiting)
|
||||||
|
|
@ -1557,7 +1571,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return eNoErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1700,6 +1714,12 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
|
||||||
|
|
||||||
WTErr retVal = eNoErr;
|
WTErr retVal = eNoErr;
|
||||||
|
|
||||||
|
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
|
||||||
|
{
|
||||||
|
sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() );
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
DeviceInfo devInfo;
|
DeviceInfo devInfo;
|
||||||
retVal = GetDeviceInfoByName(deviceName, devInfo);
|
retVal = GetDeviceInfoByName(deviceName, devInfo);
|
||||||
|
|
||||||
|
|
@ -1719,29 +1739,23 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
|
||||||
WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const
|
WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const
|
||||||
{
|
{
|
||||||
WTErr retVal = eNoErr;
|
WTErr retVal = eNoErr;
|
||||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: getting buffer size for device: "<< deviceName << std::endl;
|
|
||||||
|
buffers.clear();
|
||||||
|
|
||||||
//first check if the request has been made for None device
|
//first check if the request has been made for None device
|
||||||
if (deviceName == m_NoneDevice->DeviceName() )
|
if (deviceName == m_NoneDevice->DeviceName() )
|
||||||
{
|
{
|
||||||
buffers = m_NoneDevice->BufferSizes();
|
buffers.assign(m_NoneDevice->BufferSizes().begin(), m_NoneDevice->BufferSizes().end() );
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
|
||||||
|
{
|
||||||
|
buffers.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() );
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if we have current device initialized and it's PA device, reset it
|
Pa_Initialize();
|
||||||
//this procedure will reset PA corrently and update info for all PA devices as well
|
|
||||||
|
|
||||||
bool paLocalInit = false;
|
|
||||||
WCMRPortAudioDevice* portaudioDevice = dynamic_cast<WCMRPortAudioDevice*>(m_CurrentDevice);
|
|
||||||
if (portaudioDevice)
|
|
||||||
{
|
|
||||||
portaudioDevice->ResetDevice();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//initialize PA to get buffers for the device
|
|
||||||
Pa_Initialize();
|
|
||||||
paLocalInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceInfo devInfo;
|
DeviceInfo devInfo;
|
||||||
retVal = GetDeviceInfoByName(deviceName, devInfo);
|
retVal = GetDeviceInfoByName(deviceName, devInfo);
|
||||||
|
|
@ -1760,7 +1774,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retVal = eAsioFailed;
|
retVal = eAsioFailed;
|
||||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << paErr << " getting buffer size fo device: "<< deviceName << std::endl;
|
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer size fo device: "<< deviceName << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1768,9 +1782,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
|
||||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
|
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//deinitialize PA now
|
Pa_Terminate();
|
||||||
if (paLocalInit)
|
|
||||||
Pa_Terminate();
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
|
||||||