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
This commit is contained in:
Paul Davis 2014-09-02 10:28:52 -04:00
commit c7af2444a7
42 changed files with 617 additions and 493 deletions

View file

@ -211,14 +211,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
, _feedback_exists (false)
, _dsp_load_adjustment (0)
, _hd_load_adjustment (0)
, _dsp_load_label(0)
, _hd_load_label(0)
, _hd_remained_time_label(0)
, _dsp_load_label (0)
, _hd_load_label (0)
, _hd_remained_time_label (0)
, editor (0)
, mixer (0)
, _bit_depth_button(0)
, _sample_rate_button(0)
, _frame_rate_button(0)
, _tracks_button (0)
, _bit_depth_button (0)
, _sample_rate_button (0)
, _frame_rate_button (0)
, splash (0)
{
Gtkmm2ext::init(localedir);
@ -4026,15 +4027,17 @@ ARDOUR_UI::sr_mismatch_dialog (framecnt_t desired, framecnt_t actual)
ArdourDialog dialog (_("Sample Rate Mismatch"), true);
Label message (string_compose (_("\
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));
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
dialog.add_button (_("Cancel"), RESPONSE_REJECT);
dialog.add_button (_("Accept"), RESPONSE_ACCEPT);
dialog.set_default_response (RESPONSE_ACCEPT);
dialog.set_position (WIN_POS_CENTER);
message.show();

View file

@ -227,6 +227,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void focus_on_clock ();
AudioClock* big_clock;
WavesButton* _tracks_button;
void on_tracks_button (WavesButton*);
WavesButton* _bit_depth_button;
WavesButton* _sample_rate_button;
WavesButton* _frame_rate_button;

View file

@ -90,6 +90,8 @@ ARDOUR_UI::create_editor ()
_bit_depth_button = &editor->get_waves_button("bit_depth_button");
_sample_rate_button = &editor->get_waves_button("sample_rate_button");
_frame_rate_button = &editor->get_waves_button("frame_rate_button");
_tracks_button = &editor->get_waves_button("tracks_button");
}
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));
_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));
_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->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;
}
void
ARDOUR_UI::on_tracks_button (WavesButton*)
{
about->show ();
}
void
ARDOUR_UI::on_bit_depth_button (WavesButton*)
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 505 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -59,8 +59,14 @@ using namespace ARDOUR;
using namespace ARDOUR_UI_UTILS;
using namespace Gtkmm2ext;
Pango::FontDescription TimeAxisViewItem::NAME_FONT;
const double TimeAxisViewItem::NAME_HIGHLIGHT_Y_IDENT = 3.0;
// GZ: Should be moved to config
#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_Y_OFFSET = 5.0;
const double TimeAxisViewItem::GRAB_HANDLE_TOP = 2.0;
@ -71,16 +77,15 @@ const double TimeAxisViewItem::REGION_TOP_OFFSET = 2.0;
const double TimeAxisViewItem::REGION_BOTTOM_OFFSET = 3.0;
int TimeAxisViewItem::NAME_HEIGHT;
double TimeAxisViewItem::NAME_HIGHLIGHT_X_IDENT;
double TimeAxisViewItem::NAME_Y_OFFSET;
double TimeAxisViewItem::NAME_HIGHLIGHT_X_INDENT;
double TimeAxisViewItem::NAME_HIGHLIGHT_HEIGHT;
double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
void
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::Label foo;
win.add (foo);
@ -92,17 +97,17 @@ TimeAxisViewItem::set_constant_heights ()
layout->set_font_description (NAME_FONT);
get_pixel_size (layout, width, height);
NAME_HEIGHT = height + 2;
NAME_HIGHLIGHT_X_IDENT = width + 2;
NAME_HEIGHT = height;
NAME_HIGHLIGHT_X_INDENT = width;
/* 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:
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_THRESH = NAME_HIGHLIGHT_HEIGHT * 1.5;
NAME_HIGHLIGHT_HEIGHT = NAME_HEIGHT + NAME_HIGHLIGHT_Y_INDENT*2;
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
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,
ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
NAME_HIGHLIGHT_Y_OFFSET,
NAME_HIGHLIGHT_X_OFFSET + 2*NAME_HIGHLIGHT_X_IDENT,
NAME_HIGHLIGHT_HEIGHT) );
CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
name_highlight->set_data ("timeaxisviewitem", this);
name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0) );
name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
name_highlight = new ArdourCanvas::Rectangle (group,
ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
NAME_HIGHLIGHT_Y_OFFSET,
NAME_HIGHLIGHT_X_OFFSET + 2*NAME_HIGHLIGHT_X_INDENT,
NAME_HIGHLIGHT_HEIGHT + NAME_HIGHLIGHT_Y_OFFSET) );
CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
name_highlight->set_data ("timeaxisviewitem", this);
name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0) );
name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
}
{
name_text = new ArdourCanvas::Text (group);
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("");
name_text->set_font_description (NAME_FONT);
if (name_text->text().empty() ) {
if (name_text->text().empty()) {
name_highlight->hide();
}
}
@ -558,8 +564,9 @@ TimeAxisViewItem::set_name_text(const string& new_name)
if (!name_text) {
return;
}
name_text_width = pixel_width (new_name, NAME_FONT);
// This is a workaround.
// 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);
}
@ -601,12 +608,12 @@ TimeAxisViewItem::manage_name_highlight ()
high_enough_for_name = true;
}
double highlite_y1 = name_text_width + 2*NAME_HIGHLIGHT_X_IDENT + NAME_HIGHLIGHT_X_OFFSET;
if (_width < highlite_y1) {
highlite_y1 = _width;
double highlite_x1 = name_text_width + 2*NAME_HIGHLIGHT_X_INDENT + NAME_HIGHLIGHT_X_OFFSET;
if (_width < highlite_x1) {
highlite_x1 = _width;
}
if (highlite_y1 < NAME_HIGHLIGHT_X_OFFSET) {
if (highlite_x1 < NAME_HIGHLIGHT_X_OFFSET) {
wide_enough_for_name = false;
} else {
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() ) {
name_highlight->set (ArdourCanvas::Rect (NAME_HIGHLIGHT_X_OFFSET,
NAME_HIGHLIGHT_Y_OFFSET,
highlite_y1,
NAME_HIGHLIGHT_HEIGHT) );
highlite_x1,
NAME_HIGHLIGHT_HEIGHT + NAME_HIGHLIGHT_Y_OFFSET) );
name_highlight->show();
name_highlight->raise_to_top();
} else {
name_highlight->hide();
}
@ -948,8 +955,8 @@ TimeAxisViewItem::manage_name_text ()
visible_name_width = name_text_width;
if (visible_name_width > _width - NAME_HIGHLIGHT_X_OFFSET - NAME_HIGHLIGHT_X_IDENT) {
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_INDENT;
}
if (visible_name_width < 1) {
@ -957,6 +964,7 @@ TimeAxisViewItem::manage_name_text ()
} else {
name_text->clamp_width (visible_name_width);
name_text->show ();
name_text->raise_to_top ();
}
}

View file

@ -104,7 +104,7 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
// Default sizes, font and spacing
static Pango::FontDescription NAME_FONT;
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_Y_OFFSET;
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.
*/
static int NAME_HEIGHT;
static double NAME_HIGHLIGHT_X_IDENT;
static double NAME_HIGHLIGHT_X_INDENT;
static double NAME_X_OFFSET;
static double NAME_Y_OFFSET;
static double NAME_HIGHLIGHT_HEIGHT;
static double NAME_HIGHLIGHT_THRESH;

View file

@ -116,6 +116,7 @@ TracksControlPanel::init ()
EngineStateController::instance()->OutputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_audio_output_configuration_changed, this), gui_context());
EngineStateController::instance()->MIDIInputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_midi_input_configuration_changed, this), gui_context());
EngineStateController::instance()->MIDIOutputConfigChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_midi_output_configuration_changed, this), gui_context());
EngineStateController::instance()->DeviceError.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_device_error, this), gui_context());
/* Global configuration parameters update */
Config->ParameterChanged.connect (update_connections, MISSING_INVALIDATOR, boost::bind (&TracksControlPanel::on_parameter_changed, this, _1), gui_context());
@ -1243,6 +1244,21 @@ TracksControlPanel::on_session_settings (WavesButton*)
_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
TracksControlPanel::on_multi_out (WavesButton*)

View file

@ -115,6 +115,7 @@
void on_audio_output_configuration_changed ();
void on_midi_input_configuration_changed ();
void on_midi_output_configuration_changed ();
void on_device_error ();
void cleanup_input_channels_list();
void cleanup_output_channels_list();

View file

@ -1,145 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<RouteUI bgnormal="#383838" bgactive="#545454">
<Vbox>
<EventBox id="upper_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3"/>
<HBox>
<VBox>
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
<HBox box.expand="true" box.fill="true">
<EventBox id="selected_track_color_box" width="29" bgactive="#5BA55C">
<HBox>
<!--<Igor! width="2" below is the shift from RIGHT side of the space>-->
<VBox width="2" box.pack="end"/>
<VBox box.pack="end">
<!--<Igor! height="4" below is the shift from TOP side of the space>-->
<HBox height="4"/>
<Label id="number_label"
text="32"
fgnormal="#ffffff"
fgactive="#ffffff"
winfont ="Arial Bold 13"
macfont ="Helvetica Bold 13"/>
</VBox>
</HBox>
</EventBox>
<EventBox id="track_color_box" width="6" bgnormal="#5BA55C" bgactive="#5BA55C"/>
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
</HBox>
<EventBox height="1" bgnormal="#000000" bgactive="#000000" box.pack="end"/>
</VBox>
<VBox>
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
<!--<Igor! About the track name: height="5" below is the shift from TOP side of the space>-->
<HBox height="5"/>
<HBox width="80"
id="name_label_home">
<HBox width="5"/>
<Label id="name_label"
winfont ="Arial 10"
macfont ="Helvetica 10"
fgnormal="#ffffff"
fgactive="#ffffff"/>
<FocusEntry id="name_entry"
width="80"
height="20"
fgnormal="#ffffff"
winfont ="Arial 10"
macfont ="Helvetica 10"
cssname="EditorTrackNameDisplay"
textcolornormal="#ffffff"
textcoloractive="#ffffff"
textcolorselected="#ffffff"
noshowall="true"
visible="false"/>
</HBox>
<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"/>
<Vbox>
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
<EventBox id="upper_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3"/>
<HBox box.fill="true" box.expand="true">
<VBox>
<HBox box.expand="true" box.fill="true">
<EventBox id="selected_track_color_box" width="29" bgactive="#5BA55C">
<HBox>
<!--<Igor! width="2" below is the shift from RIGHT side of the space>-->
<VBox width="2" box.pack="end"/>
<VBox box.pack="end">
<!--<Igor! height="4" below is the shift from TOP side of the space>-->
<HBox height="4"/>
<Label id="number_label"
text="32"
fgnormal="#ffffff"
fgactive="#ffffff"
winfont ="Arial Bold 13"
macfont ="Helvetica Bold 13"/>
</VBox>
</HBox>
</EventBox>
<EventBox id="track_color_box" width="6" bgnormal="#5BA55C" bgactive="#5BA55C"/>
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
</HBox>
</VBox>
<VBox>
<!--<Igor! About the track name: height="5" below is the shift from TOP side of the space>-->
<HBox height="5"/>
<HBox width="80"
id="name_label_home">
<HBox width="5"/>
<Label id="name_label"
winfont ="Arial 10"
macfont ="Helvetica 10"
fgnormal="#ffffff"
fgactive="#ffffff"/>
<FocusEntry id="name_entry"
width="80"
height="20"
fgnormal="#ffffff"
winfont ="Arial 10"
macfont ="Helvetica 10"
cssname="EditorTrackNameDisplay"
textcolornormal="#ffffff"
textcoloractive="#ffffff"
textcolorselected="#ffffff"
noshowall="true"
visible="false"/>
</HBox>
</VBox>
<VBox>
<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"/>
<VBox>
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
<iconbutton id="rec_enable_button"
<iconbutton id="monitor_input_button"
width="41"
height="20"
normalicon="time_axis_record"
activeicon="time_axis_record_active"
prelighticon="time_axis_record_prelight"
tooltip="Record Enable"/>
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>
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
<iconbutton id="solo_button"
<iconbutton id="mute_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"/>
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>
</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>
<VBox width="24"/>
<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"/>
<VBox width="1"/>
<VBox id="gain_meter_home" width="7" />
<EventBox width="1" bgnormal="#000000" bgactive="#000000"/>
</HBox>
<!--<HBox id="gain_meter_home" box.pack="end"/>-->
<VBox id="gain_meter_home" width="7">
<EventBox height="1" bgnormal="#494949" bgactive="#494949"/>
<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>
<EventBox id="lower_drop_indicator" visible="false" noshowall="true" height="2" bgnormal="#1CA3B3" bgactive="#1CA3B3"/>
<EventBox height="1" bgnormal="#000000" bgactive="#000000"/>
</Vbox>
</RouteUI>

View file

@ -41,7 +41,6 @@
<HBox id="primary_clock_home"
x="132"
y="6"/>
<Button id="bit_depth_button"
text="bit depth"
fgnormal="#ffffff"
@ -78,8 +77,26 @@
activeicon="top_bar_button"
prelighticon="top_bar_button"/>
</Layout>
<Layout box.pack="end" width="114" height="51">
<icon source="metrics_display.png"/>
<EventBox bgnormal="#383838"
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"
minvalue="1"
maxvalue="100"
@ -93,7 +110,7 @@
maxposx="56"
maxposy="3"
readonly="true"
x="28"
x="29"
y="8"
width="56"
height="5"/>
@ -103,7 +120,7 @@
fgnormal="#ffffff"
winfont ="Arial 8"
macfont ="Helvetica 8"
x="87"
x="88"
y="8"/>
<Adjustment id="hd_load_adjustment"
minvalue="1"
@ -118,7 +135,7 @@
maxposx="56"
maxposy="3"
readonly="true"
x="28"
x="29"
y="18"
width="56"
height="5"/>
@ -128,7 +145,7 @@
fgnormal="#ffffff"
winfont ="Arial 8"
macfont ="Helvetica 8"
x="87"
x="88"
y="18"/>
<Label id="hd_remained_time"
@ -136,16 +153,11 @@
fgnormal="#ffffff"
winfont ="Arial 9"
macfont ="Helvetica 9"
x="58"
x="59"
y="33"/>
</Layout>
<EventBox bgnormal="#383838"
width="420"
box.padding="4">
<EventBox bgnormal="#474747"
borderwidth="1"/>
</EventBox>
<VBox spacing ="1" box.pack="end">
<VBox spacing ="1"
box.pack="end">
<iconbutton id="mode_stereo_out_button"
tooltip="Stereo Out Mode"
width="79" height="25"
@ -183,7 +195,9 @@
normalicon="meter_bridge_on"
activeicon="meter_bridge_on_active"
prelighticon="meter_bridge_on_prelight"/>
<layout width="54" height="26" bgnormal="#3E3E3E"/>
<Layout width="54"
height="26"
bgnormal="#3E3E3E"/>
<iconbutton id="transport_start_button"
tooltip="Rewind"
width="34" height="26"
@ -226,7 +240,9 @@
normalicon="lock_session"
activeicon="lock_session_active"
prelighticon="lock_session_prelight"/>
<layout width="60" height="26" bgnormal="#3E3E3E"/>
<Layout width="60"
height="26"
bgnormal="#3E3E3E"/>
<iconbutton id="tool_marker_button"
tooltip="Range Select Tool"
width="34" height="26"

View file

@ -81,6 +81,8 @@ WavesUI::create_widget (const XMLNode& definition, const XMLNodeMap& styles)
child = manage (new WavesButton(text));
} else if (widget_type == "ICONBUTTON") {
child = manage (new WavesIconButton);
} else if (widget_type == "DROPDOWN") {
child = manage (new WavesDropdown);
} else if (widget_type == "ICON") {
std::string image_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);
if (table) {
table->set_col_spacings (xml_property (definition, "columnspacing", styles, 0));
@ -813,6 +820,16 @@ WavesUI::get_waves_grid (const char* id)
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&
WavesUI::get_paned (const char* id)
{

View file

@ -37,6 +37,7 @@
#include "waves_grid.h"
#include "waves_button.h"
#include "waves_icon_button.h"
#include "waves_dropdown.h"
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::Fixed& get_fixed (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::HPaned& get_h_paned (const char* id);
Gtk::VPaned& get_v_paned (const char* id);

View file

@ -28,6 +28,7 @@ path_prefix = 'gtk2_ardour/'
gtk2_ardour_sources = [
'mixer_bridge_view.cc',
'waves_dropdown.cc',
'waves_zoom_control.cc',
'waves_ui.cc',
'waves_grid.cc',

View file

@ -386,6 +386,12 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
*/
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
* configuration, start (or stop) calling the process_callback() of @param engine
* without waiting for the device. Once process_callback() has returned, it

View file

@ -114,6 +114,9 @@ public:
bool is_realtime() 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_sample_rate (float);
int set_buffer_size (uint32_t);
@ -129,6 +132,7 @@ public:
bool running() const { return _running; }
Glib::Threads::Mutex& process_lock() { return _process_lock; }
Glib::Threads::RecMutex& state_lock() { return _state_lock; }
int request_buffer_size (pframes_t samples) {
return set_buffer_size (samples);
@ -169,6 +173,10 @@ public:
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 */
PBD::Signal0<void> DeviceListChanged;
@ -228,7 +236,8 @@ public:
static AudioEngine* _instance;
Glib::Threads::Mutex _process_lock;
Glib::Threads::Mutex _process_lock;
Glib::Threads::RecMutex _state_lock;
Glib::Threads::Cond session_removed;
bool session_remove_pending;
frameoffset_t session_removal_countdown;

View file

@ -48,6 +48,9 @@ public:
static EngineStateController* instance();
void set_session(Session* session);
void remove_session ();
//Interfaces
void available_backends(std::vector<const AudioBackendInfo*>&);
@ -128,6 +131,8 @@ public:
PBD::Signal0<void> BufferSizeChanged;
/* this signal is emitted if the device list changes */
PBD::Signal1<void, bool> DeviceListChanged;
/* this signal is emitted if the device cannot operate properly */
PBD::Signal0<void> DeviceError;
//ENGINE STATE SIGNALS
/* this signal is emitted when the engine is started */
@ -260,11 +265,13 @@ private:
void _on_engine_running();
void _on_engine_halted();
void _on_engine_stopped();
void _on_device_error();
void _on_sample_rate_change(ARDOUR::framecnt_t);
void _on_buffer_size_change(ARDOUR::pframes_t);
void _on_device_list_change();
void _on_parameter_changed (const std::string&);
void _on_ports_registration_update ();
void _on_session_loaded();
////////////////////////////////////////
////////////////////////////////////////
@ -282,12 +289,14 @@ private:
ARDOUR::framecnt_t _desired_sample_rate;
bool _have_control;
Session* _session;
// Engine connections stuff
PBD::ScopedConnectionList update_connections;
PBD::ScopedConnectionList session_connections;
PBD::ScopedConnection running_connection;
PBD::ScopedConnection halt_connection;
PBD::ScopedConnection stopped_connection;
};
} // namespace ARDOUR

View file

@ -301,6 +301,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
PBD::Signal0<void> RecordStateChanged;
/* Emited when session is loaded */
PBD::Signal0<void> SessionLoaded;
/* Transport mechanism signals */
/** Emitted on the following changes in transport state:

View file

@ -406,29 +406,40 @@ AudioEngine::do_reset_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);
std::cout << "AudioEngine::RESET::Reset request processing" << std::endl;
// backup the device name
std::string name = _backend->device_name ();
stop();
if (_session) {
// 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 ();
}
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 ();
}
// "hard reset" the device
_backend->drop_device ();
_backend->set_device_name (name);
std::cout << "AudioEngine::RESET::Stoping engine..." << std::endl;
stop();
start ();
std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
if ( 0 == _backend->reset_device () ) {
// inform about possible changes
SampleRateChanged (_backend->sample_rate() );
BufferSizeChanged (_backend->buffer_size() );
std::cout << "AudioEngine::RESET::Starting engine..." << std::endl;
start ();
// inform about possible changes
BufferSizeChanged (_backend->buffer_size() );
} else {
DeviceError();
}
std::cout << "AudioEngine::RESET::Done." << std::endl;
_reset_request_lock.lock();
@ -611,7 +622,7 @@ AudioEngine::died ()
stop_metering_thread ();
_running = false;
_running = false;
}
int
@ -1177,7 +1188,7 @@ AudioEngine::halted_callback (const char* why)
return;
}
stop_metering_thread ();
stop_metering_thread ();
_running = false;
Port::PortDrop (); /* EMIT SIGNAL */

View file

@ -9,9 +9,11 @@
#include "ardour/engine_state_controller.h"
#include "ardour/audioengine.h"
#include "ardour/session.h"
#include "ardour/rc_configuration.h"
#include "ardour/data_type.h"
#include "pbd/pthread_utils.h"
#include "pbd/error.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()->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()->DeviceError.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_error, this) );
/* Global configuration parameters update */
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&
EngineStateController::serialize_audio_midi_settings() {
EngineStateController::serialize_audio_midi_settings()
{
XMLNode* root = new XMLNode ("AudioMidiSettings");
@ -92,7 +112,8 @@ EngineStateController::serialize_audio_midi_settings() {
void
EngineStateController::save_audio_midi_settings() {
EngineStateController::save_audio_midi_settings()
{
Config->add_extra_xml (serialize_audio_midi_settings() );
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
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;
if (AudioEngine::instance()->session() ) {
// 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) ) {
@ -1191,7 +1223,8 @@ EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate)
// if sample rate can't be set
// switch to NONE device
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
EngineStateController::_on_parameter_changed (const std::string& parameter_name)
{
@ -1503,6 +1546,7 @@ EngineStateController::push_current_state_to_backend(bool start)
bool was_running = AudioEngine::instance()->running();
Glib::Threads::RecMutex::Lock sl (AudioEngine::instance()->state_lock() );
if (state_changed) {
if (was_running) {
@ -1511,17 +1555,31 @@ EngineStateController::push_current_state_to_backend(bool start)
}
}
if ((_current_state->device_name != backend->device_name()) && backend->set_device_name (_current_state->device_name)) {
error << string_compose (_("Cannot set device name to %1"), get_current_device_name()) << endmsg;
}
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 (backend->set_sample_rate (_current_state->sample_rate )) {
error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate()) << endmsg;
}
std::cout << "EngineStateController::Setting device sample rate " << _current_state->sample_rate << std::endl;
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_buffer_size (_current_state->buffer_size )) {
error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size()) << endmsg;
}
std::cout << "EngineStateController::Setting device buffer size " << _current_state->buffer_size << std::endl;
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 (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())) {
// error << string_compose (_("Cannot set input channels to %1"), get_input_channels()) << endmsg;
@ -1545,7 +1603,12 @@ EngineStateController::push_current_state_to_backend(bool start)
}
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;
}
}
@ -1564,10 +1627,5 @@ EngineStateController::set_desired_sample_rate(framecnt_t 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);
}
}

View file

@ -135,7 +135,12 @@ Port::get_connections (std::vector<std::string> & c) const
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

View file

@ -369,6 +369,8 @@ Session::Session (AudioEngine &eng,
_engine.set_session (this);
_engine.reset_timebase ();
EngineStateController::instance()->set_session(this);
// Waves Tracks: always create master track
if ( ARDOUR::Profile->get_trx () ) {
create_master_track();
@ -419,6 +421,7 @@ Session::Session (AudioEngine &eng,
_is_new = false;
SessionLoaded();
BootMessage (_("Session loading complete"));
}
@ -524,6 +527,7 @@ Session::destroy ()
drop_connections ();
_engine.remove_session ();
EngineStateController::instance()->remove_session();
/* deregister all ports - there will be no process or any other
* callbacks from the engine any more.

View file

@ -446,6 +446,10 @@ WavesAudioBackend::set_buffer_size (uint32_t buffer_size)
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);
if (device_needs_restart) {
@ -472,9 +476,9 @@ WavesAudioBackend::set_sample_format (SampleFormat sample_format)
}
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;
@ -483,95 +487,7 @@ WavesAudioBackend::_reset_device (uint32_t buffer_size, float sample_rate)
return -1;
}
bool device_needs_restart = _device->Streaming ();
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;
return _device->ResetDevice();
}

View file

@ -122,9 +122,10 @@ class WavesMidiPort;
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_output_latency (std::string const, uint32_t) { return 0; }
virtual int reset_device ();
virtual std::string device_name () const;
virtual float sample_rate () const;
@ -345,7 +346,6 @@ class WavesMidiPort;
pframes_t sample_time,
uint64_t cycle_start_time_nanos);
int _reset_device (uint32_t buffer_size, float sample_rate);
void _changed_midi_devices ();
// DO change sample rate and buffer size

View file

@ -425,7 +425,7 @@ WavesAudioBackend::physically_connected (PortHandle port_handle, bool process_ca
int
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)) {
std::cerr << "WavesAudioBackend::get_connections (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;

View file

@ -345,6 +345,28 @@ WTErr WCMRAudioDevice::SetStreaming (bool newState)
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.
// A normal audio device should return the Streaming() value

View file

@ -151,6 +151,8 @@ public:
virtual bool Streaming();///<Streaming Status?
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
virtual WTErr ResetDevice ();
virtual bool IsProcessActive();
virtual WTErr DoIdle();///<Do Idle Processing

View file

@ -13,14 +13,16 @@
#include <iostream>
#include <sstream>
#include <algorithm>
#include <list>
using namespace wvNS;
#include "IncludeWindows.h"
#include <MMSystem.h>
#include "pa_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_RETRIES 3
///< Supported Sample rates
static const double gAllSampleRates[] =
@ -308,14 +310,12 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
//update 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
PaStreamParameters inputParameters, outputParameters;
PaStreamParameters *pInS = NULL, *pOutS = NULL;
inputParameters.device = m_DeviceID;
inputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxInputChannels);
inputParameters.channelCount = pDeviceInfo->maxInputChannels;
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
inputParameters.hostApiSpecificStreamInfo = 0;
@ -324,7 +324,7 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
pInS = &inputParameters;
outputParameters.device = m_DeviceID;
outputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxOutputChannels);
outputParameters.channelCount = pDeviceInfo->maxOutputChannels;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
outputParameters.hostApiSpecificStreamInfo = 0;
@ -332,7 +332,6 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
if (outputParameters.channelCount)
pOutS = &outputParameters;
std::cout << "API::Device" << m_DeviceName << " Updating sample rates " << std::endl;
////////////////////////////////////////////////////////////////////////////////////
//update list of supported SRs...
m_SamplingRates.clear();
@ -348,52 +347,25 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
}
}
std::cout << "API::Device" << m_DeviceName << " Updating buffer sizes" << std::endl;
///////////////////////////////////////////////////////////////////////////////////
//update buffer sizes
m_BufferSizes.clear();
bool useDefaultBuffers = true;
PaError paErr = paNoError;
//sometimes devices change buffer size if sample rate changes
//it updates buffer size during stream opening
//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
//(skip this step if the device is Active)
if ( !Active() )
// In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel
long minSize, maxSize, preferredSize, granularity;
PaError err = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
if (err == paNoError)
{
if (paNoError != testStateValidness(m_CurrentSamplingRate, m_CurrentBufferSize) )
{
//buffer size did change
Pa_Terminate();
Pa_Initialize();
std::cout << "API::Device " << m_DeviceName << " Buffers: " << minSize << " " << maxSize << " " << preferredSize << std::endl;
// 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)
{
std::cout << "API::Device " << m_DeviceName << " Buffers: " << minSize << " " << maxSize << " " << preferredSize << std::endl;
m_BufferSizes.push_back (preferredSize);
useDefaultBuffers = false;
}
else
{
std::cout << "API::Device" << m_DeviceName << " Preffered buffer size is not supported" << std::endl;
}
m_BufferSizes.push_back (preferredSize);
useDefaultBuffers = false;
}
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)
@ -476,18 +448,18 @@ PaError WCMRPortAudioDevice::testStateValidness(int sampleRate, int bufferSize)
PaStreamParameters *pInS = NULL, *pOutS = NULL;
inputParameters.device = m_DeviceID;
inputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxInputChannels);
inputParameters.channelCount = pDeviceInfo->maxInputChannels;
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
inputParameters.suggestedLatency = 0;
inputParameters.hostApiSpecificStreamInfo = 0;
if (inputParameters.channelCount)
pInS = &inputParameters;
outputParameters.device = m_DeviceID;
outputParameters.channelCount = std::min<int>(2, pDeviceInfo->maxOutputChannels);
outputParameters.channelCount = pDeviceInfo->maxOutputChannels;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
outputParameters.suggestedLatency = 0;
outputParameters.hostApiSpecificStreamInfo = 0;
if (outputParameters.channelCount)
@ -499,7 +471,7 @@ PaError WCMRPortAudioDevice::testStateValidness(int sampleRate, int bufferSize)
//it updates buffer size during stream opening
//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
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)
{
@ -628,35 +600,17 @@ WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate)
return (retVal);
}
if (oldActive)
{
//Deactivate it for the change...
SetActive (false);
}
//make the change...
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
// 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)
if (paErr != paNoError)
{
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)
{
//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;
retVal = eWrongObjectState;
}
return (retVal);
@ -705,6 +659,15 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
if (oldSize == newSize)
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...
intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), newSize);
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
// this is the only value which could be set
m_CurrentBufferSize = m_BufferSizes[0];
int bufferSize = m_CurrentBufferSize;
newSize = m_BufferSizes[0];
int bufferSize = newSize;
// notify client to update sample rate after us
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
return retVal;
} else {
// more then one buffer size value is available
//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)
{
//Deactivate it for the change...
@ -789,6 +747,17 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
// if device is not active activate it
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 *pInS = NULL, *pOutS = NULL;
@ -813,11 +782,12 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
if (outputParameters.channelCount)
pOutS = &outputParameters;
std::cout << "API::Device" << m_DeviceName << " Opening device stream " << std::endl;
std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << m_CurrentBufferSize << std::endl;
// try opening stream with current buffer and the rest if not successful
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,
pInS,
pOutS,
@ -826,20 +796,31 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
paDitherOff,
WCMRPortAudioDevice::TheCallback,
this);
if(paErr == paNoError)
{
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
wvThread::sleep_milliseconds (PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS);
--tryAgain;
if (paErr == paUnanticipatedHostError)
std::cout << "Error details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl;
}
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_DropsReported = 0;
m_IgnoreThisDrop = true;
@ -861,8 +842,8 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
else
{
//failed, do not update device state
std::cout << "Failed to open pa stream " << paErr << std::endl;
DEBUG_MSG( "Failed to open pa stream " << paErr );
std::cout << "Failed to open pa stream: " << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to open pa stream: " << Pa_GetErrorText (paErr) );
m_ConnectionStatus = DeviceErrors;
m_lastErr = eAsioFailed;
}
@ -922,8 +903,8 @@ void WCMRPortAudioDevice::deactivateDevice (bool callerIsWaiting/*=false*/)
else
{
//failed, do not update device state
std::cout << "Failed to close pa stream stream " << paErr << std::endl;
DEBUG_MSG( "Failed to open pa stream stream " << paErr );
std::cout << "Failed to close pa stream stream " << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to open pa stream stream " << Pa_GetErrorText (paErr) );
m_ConnectionStatus = DeviceErrors;
m_lastErr = eAsioFailed;
}
@ -954,17 +935,25 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
m_SampleCounter = 0;
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 );
if(paErr == paNoError)
{
// if the stream was started successfully
m_IsStreaming = true;
std::cout << "API::Device" << m_DeviceName << " Device is streaming" << std::endl;
}
else
{
std::cout << "Failed to start PA stream: " << paErr << std::endl;
DEBUG_MSG( "Failed to start PA stream: " << paErr );
std::cout << "Failed to start PA stream: " << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to start PA stream: " << Pa_GetErrorText (paErr) );
m_lastErr = eGenericErr;
}
}
@ -1002,8 +991,8 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
}
else
{
std::cout << "Failed to stop PA stream: " << paErr << std::endl;
DEBUG_MSG( "Failed to stop PA stream " << paErr );
std::cout << "Failed to stop PA stream: " << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to stop PA stream " << Pa_GetErrorText (paErr) );
m_lastErr = eGenericErr;
}
}
@ -1028,6 +1017,8 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
{
std::cout << "API::Device" << m_DeviceName << "Reseting device" << std::endl;
PaError paErr = paNoError;
// Keep device sates
bool wasStreaming = Streaming();
bool wasActive = Active();
@ -1036,49 +1027,72 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
stopStreaming();
deactivateDevice();
// Reinitialize PA
Pa_Terminate();
Pa_Initialize();
updateDeviceInfo();
// Cache device buffer size as it might be changed during reset
int oldBufferSize = m_CurrentBufferSize;
// In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel
// Backend should always use preffered buffer size value in this case
long minSize, maxSize, preferredSize, granularity;
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
// Now, validate the state and update device info if required
unsigned int retry = PROPERTY_CHANGE_RETRIES;
while (retry-- )
{
// 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)
{
m_CurrentBufferSize = preferredSize;
}
else
{
// if we can't get device buffer sizes, use the first one among supported
if (m_BufferSizes.size() != 0)
m_CurrentBufferSize = m_BufferSizes.front();
}
// Notify the Application about device setting changes
if (oldBufferSize != m_CurrentBufferSize)
{
std::cout << "API::Device" << m_DeviceName << " buffer size changed" << std::endl;
int bufferSize = m_CurrentBufferSize;
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
}
// Notify the Application about device setting changes
if (oldBufferSize != m_CurrentBufferSize)
{
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
if (wasActive)
activateDevice();
// Activate the device if it was active before
if (wasActive)
activateDevice();
// Resume streaming if the device was streaming before
if(wasStreaming)
{
// Notify the Application to prepare for the stream start
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
startStreaming();
// Resume streaming if the device was streaming before
if(wasStreaming && m_lastErr == eNoErr && m_ConnectionStatus == DeviceAvailable)
{
// Notify the Application to prepare for the stream start
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
startStreaming();
}
} else {
m_ConnectionStatus = DeviceErrors;
m_lastErr = eWrongObjectState;
}
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;
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
{
sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() );
return retVal;
}
DeviceInfo 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 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
if (deviceName == m_NoneDevice->DeviceName() )
{
buffers = m_NoneDevice->BufferSizes();
buffers.assign(m_NoneDevice->BufferSizes().begin(), m_NoneDevice->BufferSizes().end() );
return retVal;
}
//if we have current device initialized and it's PA device, reset it
//this procedure will reset PA corrently and update info for all PA devices as well
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
{
buffers.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() );
return retVal;
}
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;
}
Pa_Initialize();
DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo);
@ -1760,7 +1774,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
else
{
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
@ -1768,9 +1782,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
}
//deinitialize PA now
if (paLocalInit)
Pa_Terminate();
Pa_Terminate();
return retVal;
}