From df1c4dddc39d1cc5132501afb94bbabb9935cc32 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 31 Jan 2007 18:51:33 +0000 Subject: [PATCH] remove ardour_message.{cc,h}; JACK latency menu now shows correct settings at startup and changes are handled correctly; export range markers doesn't start with /path/to/export.wav, just /path/to; hopefully improve ruler scrolling a little; fixed up short_path() implementation ; fix for export unsetting JACK freewheel too soon ; use ISO 8061 timestamps for snapshot default names git-svn-id: svn://localhost/ardour2/trunk@1400 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour_message.cc | 64 --------------- gtk2_ardour/ardour_message.h | 47 ----------- gtk2_ardour/ardour_ui.cc | 90 ++++++++++++++++++---- gtk2_ardour/ardour_ui.h | 3 + gtk2_ardour/ardour_ui_dialogs.cc | 2 + gtk2_ardour/ardour_ui_ed.cc | 52 +++++++++++++ gtk2_ardour/editor.cc | 27 +------ gtk2_ardour/editor.h | 1 + gtk2_ardour/editor_canvas.cc | 22 ++++++ gtk2_ardour/editor_hscroller.cc | 7 +- gtk2_ardour/editor_mixer.cc | 25 ++++++ gtk2_ardour/export_dialog.cc | 7 +- gtk2_ardour/export_dialog.h | 2 + gtk2_ardour/export_range_markers_dialog.cc | 4 +- gtk2_ardour/export_range_markers_dialog.h | 2 + gtk2_ardour/utils.cc | 54 +++++++++---- libs/ardour/ardour/audioengine.h | 2 + libs/ardour/audioengine.cc | 24 +++++- 18 files changed, 261 insertions(+), 174 deletions(-) delete mode 100644 gtk2_ardour/ardour_message.cc delete mode 100644 gtk2_ardour/ardour_message.h diff --git a/gtk2_ardour/ardour_message.cc b/gtk2_ardour/ardour_message.cc deleted file mode 100644 index 2948559f14..0000000000 --- a/gtk2_ardour/ardour_message.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ - -*/ - -#include - -#include "ardour_message.h" -#include "i18n.h" - -using namespace std; -using namespace Gtk; - -ArdourMessage::ArdourMessage (Gtk::Window* parent, - string name, string msg, - bool grab_focus, bool auto_run) - : ArdourDialog (name), - label (msg) -{ - label.set_name (X_("PrompterLabel")); - label.set_justify (JUSTIFY_CENTER); - label.show (); - - get_vbox()->pack_start (label); - - Button* ok_button = add_button (Stock::OK, RESPONSE_ACCEPT); - - set_name (X_("Prompter")); - set_position (Gtk::WIN_POS_MOUSE); - set_modal (true); - set_type_hint (Gdk::WINDOW_TYPE_HINT_MENU); - - if (grab_focus) { - ok_button->grab_focus (); - } - - if (parent) { - set_transient_for (*parent); - } - - if (auto_run) { - run (); - } -} - -ArdourMessage::~ArdourMessage() -{ -} diff --git a/gtk2_ardour/ardour_message.h b/gtk2_ardour/ardour_message.h deleted file mode 100644 index a9ac02a5bc..0000000000 --- a/gtk2_ardour/ardour_message.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ - -*/ - -#ifndef __ardour_message_h__ -#define __ardour_message_h__ - -#include - -#include -#include -#include - -#include "ardour_dialog.h" - -class ArdourMessage : public ArdourDialog -{ - public: - ArdourMessage (Gtk::Window* parent, - std::string name, std::string msg, - bool grabfocus = true, - bool autorun = true); - ~ArdourMessage(); - - private: - Gtk::Label label; - -}; - -#endif // __ardour_message_h__ diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 8b1bc78e68..c7813f968b 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 1999-2002 Paul Davis + Copyright (C) 1999-2007 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,6 +28,8 @@ #include +#include + #include #include @@ -87,6 +89,7 @@ ARDOUR_UI *ARDOUR_UI::theArdourUI = 0; sigc::signal ARDOUR_UI::Blink; sigc::signal ARDOUR_UI::RapidScreenUpdate; +sigc::signal ARDOUR_UI::MidRapidScreenUpdate; sigc::signal ARDOUR_UI::SuperRapidScreenUpdate; sigc::signal ARDOUR_UI::Clock; @@ -361,7 +364,24 @@ ARDOUR_UI::save_ardour_state () void ARDOUR_UI::startup () { - // relax + if (engine->is_realtime()) { + + struct rlimit limits; + + if (getrlimit (RLIMIT_MEMLOCK, &limits)) { + return; + } + + if (limits.rlim_cur != RLIM_INFINITY) { + MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. " + "This might cause Ardour to run out of memory before your system " + "runs out of memory. \n\n" + "You can view the memory limit with 'ulimit -l', " + "and it is normally controlled by /etc/security/limits.conf")); + + msg.run (); + } + } } void @@ -486,6 +506,13 @@ ARDOUR_UI::every_point_one_seconds () return TRUE; } +gint +ARDOUR_UI::every_point_oh_five_seconds () +{ + MidRapidScreenUpdate(); /* EMIT_SIGNAL */ + return true; +} + gint ARDOUR_UI::every_point_zero_one_seconds () { @@ -1244,6 +1271,49 @@ ARDOUR_UI::engine_running () ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running)); ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true); ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false); + + Glib::RefPtr action; + char* action_name = 0; + + switch (engine->frames_per_cycle()) { + case 32: + action_name = X_("JACKLatency32"); + break; + case 64: + action_name = X_("JACKLatency64"); + break; + case 128: + action_name = X_("JACKLatency128"); + break; + case 512: + action_name = X_("JACKLatency512"); + break; + case 1024: + action_name = X_("JACKLatency1024"); + break; + case 2048: + action_name = X_("JACKLatency2048"); + break; + case 4096: + action_name = X_("JACKLatency4096"); + break; + case 8192: + action_name = X_("JACKLatency8192"); + break; + default: + /* XXX can we do anything useful ? */ + break; + } + + if (action_name) { + + action = ActionManager::get_action (X_("JACK"), action_name); + + if (action) { + Glib::RefPtr ract = Glib::RefPtr::cast_dynamic (action); + ract->set_active (); + } + } } void @@ -1416,17 +1486,18 @@ ARDOUR_UI::snapshot_session () { ArdourPrompter prompter (true); string snapname; - string now; + char timebuf[128]; time_t n; + struct tm local_time; time (&n); - now = ctime (&n); - now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")"; + localtime_r (&n, &local_time); + strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time); prompter.set_name ("Prompter"); prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); prompter.set_prompt (_("Name of New Snapshot")); - prompter.set_initial_text (now); + prompter.set_initial_text (timebuf); switch (prompter.run()) { case RESPONSE_ACCEPT: @@ -2311,13 +2382,6 @@ ARDOUR_UI::reconnect_to_jack () } } -void -ARDOUR_UI::set_jack_buffer_size (nframes_t nframes) -{ - engine->request_buffer_size (nframes); - update_sample_rate (0); -} - int ARDOUR_UI::cmdline_new_session (string path) { diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 55f9806f5e..e1b7c55555 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -156,6 +156,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI static sigc::signal Blink; static sigc::signal RapidScreenUpdate; + static sigc::signal MidRapidScreenUpdate; static sigc::signal SuperRapidScreenUpdate; static sigc::signal Clock; @@ -496,10 +497,12 @@ class ARDOUR_UI : public Gtkmm2ext::UI gint every_second (); gint every_point_one_seconds (); + gint every_point_oh_five_seconds (); gint every_point_zero_one_seconds (); sigc::connection second_connection; sigc::connection point_one_second_connection; + sigc::connection point_oh_five_second_connection; sigc::connection point_zero_one_second_connection; gint session_menu (GdkEventButton *); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 140ee649ea..61144a62c0 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -139,6 +139,7 @@ ARDOUR_UI::connect_to_session (Session *s) second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000); point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100); + // point_oh_five_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_oh_five_seconds), 50); point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40); } @@ -158,6 +159,7 @@ ARDOUR_UI::unload_session () editor->hide (); second_connection.disconnect (); point_one_second_connection.disconnect (); + point_oh_five_second_connection.disconnect (); point_zero_one_second_connection.disconnect(); ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 8dd4913f0e..6e5aa01ac6 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -35,6 +35,7 @@ #include "actions.h" #include +#include #include #include @@ -522,6 +523,57 @@ ARDOUR_UI::toggle_control_protocol_feedback (ControlProtocolInfo* cpi, const cha } } +void +ARDOUR_UI::set_jack_buffer_size (nframes_t nframes) +{ + Glib::RefPtr action; + char* action_name = 0; + + switch (nframes) { + case 32: + action_name = X_("JACKLatency32"); + break; + case 64: + action_name = X_("JACKLatency64"); + break; + case 128: + action_name = X_("JACKLatency128"); + break; + case 512: + action_name = X_("JACKLatency512"); + break; + case 1024: + action_name = X_("JACKLatency1024"); + break; + case 2048: + action_name = X_("JACKLatency2048"); + break; + case 4096: + action_name = X_("JACKLatency4096"); + break; + case 8192: + action_name = X_("JACKLatency8192"); + break; + default: + /* XXX can we do anything useful ? */ + break; + } + + if (action_name) { + + action = ActionManager::get_action (X_("JACK"), action_name); + + if (action) { + Glib::RefPtr ract = Glib::RefPtr::cast_dynamic (action); + + if (ract && ract->get_active()) { + engine->request_buffer_size (nframes); + update_sample_rate (0); + } + } + } +} + void ARDOUR_UI::build_control_surface_menu () { diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index cae06c0612..6742fb0465 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -310,6 +310,7 @@ Editor::Editor (AudioEngine& eng) button_release_can_deselect = true; canvas_idle_queued = false; _dragging_playhead = false; + _dragging_hscrollbar = false; location_marker_color = color_map[cLocationMarker]; location_range_color = color_map[cLocationRange]; @@ -355,8 +356,8 @@ Editor::Editor (AudioEngine& eng) edit_vscrollbar.set_adjustment (vertical_adjustment); edit_hscrollbar.set_adjustment (horizontal_adjustment); - edit_hscrollbar.signal_button_press_event().connect (mem_fun(*this, &Editor::hscrollbar_button_press)); - edit_hscrollbar.signal_button_release_event().connect (mem_fun(*this, &Editor::hscrollbar_button_release)); + edit_hscrollbar.signal_button_press_event().connect (mem_fun(*this, &Editor::hscrollbar_button_press), false); + edit_hscrollbar.signal_button_release_event().connect (mem_fun(*this, &Editor::hscrollbar_button_release), false); edit_hscrollbar.signal_size_allocate().connect (mem_fun(*this, &Editor::hscrollbar_allocate)); edit_hscrollbar.set_name ("EditorHScrollbar"); @@ -985,6 +986,7 @@ Editor::handle_new_duration () if (new_end > last_canvas_frame) { last_canvas_frame = new_end; + horizontal_adjustment.set_upper (last_canvas_frame / frames_per_unit); reset_scrolling_region (); } @@ -3620,27 +3622,6 @@ Editor::set_frames_per_unit (double fpu) instant_save (); } -void -Editor::canvas_horizontally_scrolled () -{ - /* this is the core function that controls horizontal scrolling of the canvas. it is called - whenever the horizontal_adjustment emits its "value_changed" signal. it executes in an - idle handler, which is important because tempo_map_changed() should issue redraws immediately - and not defer them to an idle handler. - */ - - leftmost_frame = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit); - nframes_t rightmost_frame = leftmost_frame + current_page_frames (); - - if (rightmost_frame > last_canvas_frame) { - last_canvas_frame = rightmost_frame; - reset_scrolling_region (); - } - - update_fixed_rulers (); - tempo_map_changed (Change (0), true); -} - void Editor::queue_visual_change (nframes_t where) { diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index bf960f9f8e..a64738b432 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -653,6 +653,7 @@ class Editor : public PublicEditor void controls_layout_size_request (Gtk::Requisition*); Gtk::HScrollbar edit_hscrollbar; + bool _dragging_hscrollbar; void reset_hscrollbar_stepping (); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 87e593b0ea..6c3ab9e217 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -700,3 +700,25 @@ Editor::left_track_canvas (GdkEventCrossing *ev) } +void +Editor::canvas_horizontally_scrolled () +{ + /* this is the core function that controls horizontal scrolling of the canvas. it is called + whenever the horizontal_adjustment emits its "value_changed" signal. it typically executes in an + idle handler, which is important because tempo_map_changed() should issue redraws immediately + and not defer them to an idle handler. + */ + + leftmost_frame = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit); + nframes_t rightmost_frame = leftmost_frame + current_page_frames (); + + if (rightmost_frame > last_canvas_frame) { + last_canvas_frame = rightmost_frame; + reset_scrolling_region (); + } + + update_fixed_rulers (); + + tempo_map_changed (Change (0), !_dragging_hscrollbar); +} + diff --git a/gtk2_ardour/editor_hscroller.cc b/gtk2_ardour/editor_hscroller.cc index c95d923092..5951385cb8 100644 --- a/gtk2_ardour/editor_hscroller.cc +++ b/gtk2_ardour/editor_hscroller.cc @@ -34,17 +34,20 @@ Editor::hscrollbar_allocate (Gtk::Allocation &alloc) bool Editor::hscrollbar_button_press (GdkEventButton *ev) { - return true; + _dragging_hscrollbar = true; + return false; } bool Editor::hscrollbar_button_release (GdkEventButton *ev) { + _dragging_hscrollbar = false; + if (session) { } - return true; + return false; } void diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 13eafe1602..d1dd8be7fa 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -193,6 +193,31 @@ Editor::update_current_screen () } playhead_cursor->set_position (frame); + +#undef CONTINUOUS_SCROLL +#ifdef CONTINUOUS_SCROLL + + /* don't do continuous scroll till the new position is in the rightmost quarter of the + editor canvas + */ + +#if 0 + if (frame > leftmost_frame + (3 * current_page_frames() / 4)) { + + if (frame > playhead_cursor->current_frame) { + nframes_t delta = frame - playhead_cursor->current_frame; + horizontal_adjustment.set_value (horizontal_adjustment.get_value() + (delta/frames_per_unit)); + } else { + nframes_t delta = playhead_cursor->current_frame - frame; + horizontal_adjustment.set_value (horizontal_adjustment.get_value() - (delta/frames_per_unit)); + } + } +#else + horizontal_adjustment.set_value (frame / frames_per_unit); +#endif + +#endif // CONTINUOUS_SCROLL + } } else { diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc index cf94233072..bd4955933d 100644 --- a/gtk2_ardour/export_dialog.cc +++ b/gtk2_ardour/export_dialog.cc @@ -915,7 +915,6 @@ ExportDialog::do_export () end_dialog (); } - void ExportDialog::end_dialog () { @@ -956,11 +955,13 @@ ExportDialog::start_export () string dir = session->path(); string::size_type last_slash; - if ((last_slash = dir.find_last_of ('/')) != string::npos) { + if ((last_slash = dir.find_last_of ('/')) != string::npos && last_slash != 0) { dir = dir.substr (0, last_slash+1); } - dir = dir + "export.wav"; + if (!wants_dir()) { + dir = dir + "export.wav"; + } file_entry.set_text (dir); } diff --git a/gtk2_ardour/export_dialog.h b/gtk2_ardour/export_dialog.h index 13b327fe50..632d855163 100644 --- a/gtk2_ardour/export_dialog.h +++ b/gtk2_ardour/export_dialog.h @@ -86,6 +86,8 @@ class ExportDialog : public ArdourDialog // audio data. spec has already been filled with user input before calling // this method. The dialog will be closed after this function exited. virtual void export_audio_data() = 0; + + virtual bool wants_dir() { return false; } // reads the user input and fills spec with the according values // filepath: complete path to the target file, including filename diff --git a/gtk2_ardour/export_range_markers_dialog.cc b/gtk2_ardour/export_range_markers_dialog.cc index c91e1c101a..85c5efe4f2 100644 --- a/gtk2_ardour/export_range_markers_dialog.cc +++ b/gtk2_ardour/export_range_markers_dialog.cc @@ -90,7 +90,6 @@ ExportRangeMarkersDialog::process_range_markers_export(Locations::LocationList& } } - getSession().engine().freewheel (false); current_range_marker_index++; } } @@ -140,8 +139,7 @@ ExportRangeMarkersDialog::is_filepath_valid(string &filepath) if ( (stat (filepath.c_str(), &statbuf) != 0) || (!S_ISDIR (statbuf.st_mode)) ) { - string txt = _("Please select an existing target directory. Files\n" - "are not allowed!"); + string txt = _("Please select an existing target directory. Files are not allowed!"); MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true); msg.run(); return false; diff --git a/gtk2_ardour/export_range_markers_dialog.h b/gtk2_ardour/export_range_markers_dialog.h index 7aae9640bf..1087f4c4c6 100644 --- a/gtk2_ardour/export_range_markers_dialog.h +++ b/gtk2_ardour/export_range_markers_dialog.h @@ -34,6 +34,8 @@ class ExportRangeMarkersDialog : public ExportDialog virtual bool is_filepath_valid(string &filepath); void export_audio_data(); + + bool wants_dir() { return true; } private: // keeps the duration of all range_markers before the current diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 238622ea38..f978324ab2 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -547,35 +547,55 @@ key_is_legal_for_numeric_entry (guint keyval) return false; } + ustring short_path (ustring path, uint32_t target_characters) { - ustring::size_type slash; + ustring::size_type last_sep; ustring::size_type len = path.length(); - + const char separator = '/'; + if (len <= target_characters) { return path; } + if ((last_sep = path.find_last_of (separator)) == ustring::npos) { - slash = path.find_last_of ('/'); + /* just a filename, but its too long anyway */ - if (len - slash > target_characters) { - /* even the filename itself is too long, so just return it - its - the best we can do - */ - return path.substr (slash); + if (target_characters > 3) { + return path.substr (0, target_characters - 3) + ustring ("..."); + } else { + /* stupid caller, just hand back the whole thing */ + return path; + } + } + + if (len - last_sep >= target_characters) { + + /* even the filename itself is too long */ + + if (target_characters > 3) { + return path.substr (last_sep+1, target_characters - 3) + ustring ("..."); + } else { + /* stupid caller, just hand back the whole thing */ + return path; + } } - uint32_t so_far = (len - slash) + 4; // allow for .../ + uint32_t so_far = (len - last_sep); uint32_t space_for = target_characters - so_far; - - if (slash < target_characters) { - return path; + + if (space_for >= 3) { + ustring res = "..."; + res += path.substr (last_sep - space_for); + return res; + } else { + /* remove part of the end */ + ustring res = "..."; + res += path.substr (last_sep - space_for, len - last_sep + space_for - 3); + res += "..."; + return res; + } - - string res = ".../"; - res += path.substr (slash - space_for); - - return res; } diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 83d075a311..71639b3dc3 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -53,6 +53,8 @@ class AudioEngine : public sigc::trackable jack_client_t* jack() const { return _jack; } bool connected() const { return _jack != 0; } + bool is_realtime () const; + std::string client_name() const { return jack_client_name; } int reconnect_to_jack (); diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index ab08423c31..35a47c927b 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -292,6 +293,7 @@ AudioEngine::process_callback (nframes_t nframes) if (_freewheeling) { if (Freewheel (nframes)) { + cerr << "Freewheeling returned non-zero!\n"; _freewheeling = false; jack_set_freewheel (_jack, false); } @@ -963,6 +965,10 @@ AudioEngine::freewheel (bool onoff) _freewheel_thread_registered = false; } + if (!onoff) { + stacktrace (cout); + } + return jack_set_freewheel (_jack, onoff); } else { @@ -1184,8 +1190,13 @@ int AudioEngine::request_buffer_size (nframes_t nframes) { if (_jack) { - int ret = jack_set_buffer_size (_jack, nframes); - return ret; + + if (nframes == jack_get_buffer_size (_jack)) { + return 0; + } + + return jack_set_buffer_size (_jack, nframes); + } else { return -1; } @@ -1236,3 +1247,12 @@ AudioEngine::make_port_name_non_relative (string portname) return str; } +bool +AudioEngine::is_realtime () const +{ + if (_jack) { + return jack_is_realtime (_jack); + } else { + return false; + } +}