diff options
author | John Emmas <johne53@tiscali.co.uk> | 2013-10-14 19:31:22 +0100 |
---|---|---|
committer | John Emmas <johne53@tiscali.co.uk> | 2013-10-14 19:31:22 +0100 |
commit | e466ce40ad1ba591543020cb7c0aa15dbebef81e (patch) | |
tree | f8e43560917a0a70c48d32ac171e828472cfd794 /libs | |
parent | 4fac237fdcf025c5fd5aafe207113abd6abb469b (diff) | |
parent | a901f28c6287ff99444d6a8afe67b71531a5f7d0 (diff) |
Merge branch 'master' into windows+cc
Conflicts (hopefully resolved):
gtk2_ardour/ardour_ui.cc
Diffstat (limited to 'libs')
30 files changed, 297 insertions, 99 deletions
diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index 0e39625e8c..cbe0bfce50 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -239,7 +239,38 @@ class AudioBackend : public PortEngine { * app is undefined or cannot be launched. */ virtual void launch_control_app () = 0; - /* Basic state control */ + + /* @return a vector of strings that describe the available + * MIDI options. + * + * These can be presented to the user to decide which + * MIDI drivers, options etc. can be used. The returned strings + * should be thought of as the key to a map of possible + * approaches to handling MIDI within the backend. Ensure that + * the strings will make sense to the user. + */ + virtual std::vector<std::string> enumerate_midi_options () const = 0; + + /* Request the use of the MIDI option named @param option, which + * should be one of the strings returned by enumerate_midi_options() + * + * @return zero if successful, non-zero otherwise + */ + virtual int set_midi_option (const std::string& option) = 0; + + virtual std::string midi_option () const = 0; + + /* State Control */ + + /* non-virtual method to avoid possible overrides of default + * parameters. See Scott Meyers or other books on C++ to + * understand this pattern, or possibly just this: + * + * http://stackoverflow.com/questions/12139786/good-pratice-default-arguments-for-pure-virtual-method + */ + int start (bool for_latency_measurement=false) { + return _start (for_latency_measurement); + } /** Start using the device named in the most recent call * to set_device(), with the parameters set by various @@ -250,9 +281,14 @@ class AudioBackend : public PortEngine { * the AudioEngine referenced by @param engine. These calls will * occur in a thread created by and/or under the control of the backend. * + * @param for_latency_measurement if true, the device is being started + * to carry out latency measurements and the backend should this + * take care to return latency numbers that do not reflect + * any existing systemic latency settings. + * * Return zero if successful, negative values otherwise. */ - virtual int start () = 0; + virtual int _start (bool for_latency_measurement) = 0; /** Stop using the device currently in use. * diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index ddffd1d5c0..d5dcbffe2b 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -70,6 +70,7 @@ public: int discover_backends(); std::vector<const AudioBackendInfo*> available_backends() const; std::string current_backend_name () const; + boost::shared_ptr<AudioBackend> set_default_backend (); boost::shared_ptr<AudioBackend> set_backend (const std::string&, const std::string& arg1, const std::string& arg2); boost::shared_ptr<AudioBackend> current_backend() const { return _backend; } bool setup_required () const; @@ -82,8 +83,8 @@ public: * just forward to a backend implementation. */ - int start (); - int stop (); + int start (bool for_latency_measurement=false); + int stop (bool for_latency_measurement=false); int pause (); int freewheel (bool start_stop); float get_cpu_load() const ; @@ -193,7 +194,7 @@ public: MTDM* mtdm(); int prepare_for_latency_measurement (); - void start_latency_detection (); + int start_latency_detection (); void stop_latency_detection (); void set_latency_input_port (const std::string&); void set_latency_output_port (const std::string&); @@ -228,6 +229,7 @@ public: std::string _latency_input_name; std::string _latency_output_name; framecnt_t _latency_signal_latency; + bool _stopped_for_latency; bool _started_for_latency; bool _in_destructor; diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 772ae3520d..18f13dbc78 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -113,6 +113,9 @@ class Processor : public SessionObject, public Automatable, public Latent void set_ui (void*); void* get_ui () const { return _ui_pointer; } + void set_owner (SessionObject*); + SessionObject* owner() const; + protected: virtual int set_state_2X (const XMLNode&, int version); @@ -125,6 +128,7 @@ protected: bool _display_to_user; bool _pre_fader; ///< true if this processor is currently placed before the Amp, otherwise false void* _ui_pointer; + SessionObject* _owner; }; } // namespace ARDOUR diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 570fe1bee5..ae40b089db 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -78,7 +78,7 @@ AudioEngine::AudioEngine () , _latency_output_port (0) , _latency_flush_frames (0) , _latency_signal_latency (0) - , _started_for_latency (false) + , _stopped_for_latency (false) , _in_destructor (false) { g_atomic_int_set (&m_meter_exit, 0); @@ -565,6 +565,16 @@ AudioEngine::drop_backend () } boost::shared_ptr<AudioBackend> +AudioEngine::set_default_backend () +{ + if (_backends.empty()) { + return boost::shared_ptr<AudioBackend>(); + } + + return set_backend (_backends.begin()->first, "", ""); +} + +boost::shared_ptr<AudioBackend> AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2) { BackendMap::iterator b = _backends.find (name); @@ -593,7 +603,7 @@ AudioEngine::set_backend (const std::string& name, const std::string& arg1, cons /* BACKEND PROXY WRAPPERS */ int -AudioEngine::start () +AudioEngine::start (bool for_latency) { if (!_backend) { return -1; @@ -606,7 +616,7 @@ AudioEngine::start () _processed_frames = 0; last_monitor_check = 0; - if (_backend->start()) { + if (_backend->start (for_latency)) { return -1; } @@ -622,7 +632,7 @@ AudioEngine::start () start_metering_thread (); - if (!_started_for_latency) { + if (!for_latency) { Running(); /* EMIT SIGNAL */ } @@ -630,7 +640,7 @@ AudioEngine::start () } int -AudioEngine::stop () +AudioEngine::stop (bool for_latency) { if (!_backend) { return 0; @@ -651,7 +661,10 @@ AudioEngine::stop () stop_metering_thread (); Port::PortDrop (); - Stopped (); /* EMIT SIGNAL */ + + if (!for_latency) { + Stopped (); /* EMIT SIGNAL */ + } return 0; } @@ -1015,7 +1028,10 @@ AudioEngine::halted_callback (const char* why) _running = false; Port::PortDrop (); /* EMIT SIGNAL */ - Halted (why); /* EMIT SIGNAL */ + + if (!_started_for_latency) { + Halted (why); /* EMIT SIGNAL */ + } } bool @@ -1044,23 +1060,26 @@ AudioEngine::mtdm() int AudioEngine::prepare_for_latency_measurement () { - if (!running()) { - _started_for_latency = true; + if (running()) { + _stopped_for_latency = true; + stop (true); + } - if (start()) { - _started_for_latency = false; - return -1; - } + if (start (true)) { + _started_for_latency = true; + return -1; } return 0; } -void +int AudioEngine::start_latency_detection () { - if (prepare_for_latency_measurement ()) { - return; + if (!running()) { + if (prepare_for_latency_measurement ()) { + return -1; + } } PortEngine& pe (port_engine()); @@ -1074,27 +1093,32 @@ AudioEngine::start_latency_detection () PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name); if (!out || !in) { - return; + stop (true); + return -1; } /* create the ports we will use to read/write data */ if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) { - return; + stop (true); + return -1; } if (pe.connect (_latency_output_port, _latency_output_name)) { pe.unregister_port (_latency_output_port); - return; + stop (true); + return -1; } const string portname ("latency_in"); if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) { pe.unregister_port (_latency_output_port); - return; + stop (true); + return -1; } if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) { pe.unregister_port (_latency_output_port); - return; + stop (true); + return -1; } LatencyRange lr; @@ -1110,6 +1134,7 @@ AudioEngine::start_latency_detection () _measuring_latency = true; _latency_flush_frames = samples_per_cycle(); + return 0; } void @@ -1125,9 +1150,15 @@ AudioEngine::stop_latency_detection () port_engine().unregister_port (_latency_input_port); _latency_input_port = 0; } - if (_started_for_latency) { - stop (); + + stop (true); + + if (_stopped_for_latency) { + start (); } + + _stopped_for_latency = false; + _started_for_latency = false; } void diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc index 3f8fdf509d..f9590bee11 100644 --- a/libs/ardour/processor.cc +++ b/libs/ardour/processor.cc @@ -269,3 +269,15 @@ Processor::set_ui (void* p) { _ui_pointer = p; } + +void +Processor::set_owner (SessionObject* o) +{ + _owner = o; +} + +SessionObject* +Processor::owner() const +{ + return _owner; +} diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 026ee4ec5c..25ee527e2c 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -149,6 +149,7 @@ Route::init () */ _meter.reset (new PeakMeter (_session, _name)); + _meter->set_owner (this); _meter->set_display_to_user (false); _meter->activate (); @@ -1011,6 +1012,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr< } _processors.insert (loc, processor); + processor->set_owner (this); // Set up processor list channels. This will set processor->[input|output]_streams(), // configure redirect ports properly, etc. @@ -1161,6 +1163,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> } _processors.insert (loc, *i); + (*i)->set_owner (this); if ((*i)->active()) { (*i)->activate (); @@ -2620,6 +2623,7 @@ Route::set_processor_state (const XMLNode& node) for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { + (*i)->set_owner (this); (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); boost::shared_ptr<PluginInsert> pi; diff --git a/libs/ardour/run-session-tests.sh b/libs/ardour/run-session-tests.sh index 63218d8887..034f8b5a7f 100644..100755 --- a/libs/ardour/run-session-tests.sh +++ b/libs/ardour/run-session-tests.sh @@ -8,20 +8,7 @@ if [ ! -f './tempo.cc' ]; then exit 1; fi -cd ../.. -top=`pwd` -cd build - -libs='libs' - -export LD_LIBRARY_PATH=$libs/audiographer:$libs/vamp-sdk:$libs/surfaces:$libs/surfaces/control_protocol:$libs/ardour:$libs/midi++2:$libs/pbd:$libs/rubberband:$libs/soundtouch:$libs/gtkmm2ext:$libs/appleutility:$libs/taglib:$libs/evoral:$libs/evoral/src/libsmf:$libs/timecode:/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH - -export ARDOUR_CONFIG_PATH=$top:$top/gtk2_ardour:$libs/..:$libs/../gtk2_ardour -export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap -export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie -export ARDOUR_MCP_PATH="../mcp" -export ARDOUR_DLL_PATH=$libs -export ARDOUR_DATA_PATH=$top/gtk2_ardour:$top/build/gtk2_ardour:. +. test-env.sh f="" if [ "$1" == "--debug" -o "$1" == "--valgrind" ]; then diff --git a/libs/ardour/run-tests.sh b/libs/ardour/run-tests.sh index fc7d68a8a5..e894fecb63 100755 --- a/libs/ardour/run-tests.sh +++ b/libs/ardour/run-tests.sh @@ -2,6 +2,7 @@ # # Run libardour test suite. # +. test-env.sh if [ "$1" == "--single" ] || [ "$2" == "--single" ]; then if [ "$1" == "--single" ]; then diff --git a/libs/ardour/test-env.sh b/libs/ardour/test-env.sh index aa2cff9219..561f54d694 100644 --- a/libs/ardour/test-env.sh +++ b/libs/ardour/test-env.sh @@ -22,3 +22,4 @@ export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs export ARDOUR_MCP_PATH="../mcp" export ARDOUR_DLL_PATH=$libs export ARDOUR_DATA_PATH=$top/gtk2_ardour:$top/build/gtk2_ardour:. +export ARDOUR_BACKEND_PATH=$libs/backends/jack diff --git a/libs/ardour/test/audio_region_read_test.cc b/libs/ardour/test/audio_region_read_test.cc index dc3127ea2e..6a8e3600f1 100644 --- a/libs/ardour/test/audio_region_read_test.cc +++ b/libs/ardour/test/audio_region_read_test.cc @@ -20,7 +20,6 @@ #include "ardour/region.h" #include "ardour/audioregion.h" #include "audio_region_read_test.h" -#include "test_globals.h" CPPUNIT_TEST_SUITE_REGISTRATION (AudioRegionReadTest); diff --git a/libs/ardour/test/audio_region_test.cc b/libs/ardour/test/audio_region_test.cc index df3fa72d10..a25a78a40b 100644 --- a/libs/ardour/test/audio_region_test.cc +++ b/libs/ardour/test/audio_region_test.cc @@ -27,7 +27,6 @@ #include "ardour/audioregion.h" #include "ardour/audioplaylist.h" #include "audio_region_test.h" -#include "test_globals.h" #include "test_common.h" using namespace std; @@ -42,7 +41,7 @@ AudioRegionTest::setUp () std::string const test_wav_path = Glib::build_filename (new_test_output_dir(), "test.wav"); _playlist = PlaylistFactory::create (DataType::AUDIO, *_session, "test"); _audio_playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_playlist); - _source = SourceFactory::createWritable (DataType::AUDIO, *_session, test_wav_path, "", false, Fs); + _source = SourceFactory::createWritable (DataType::AUDIO, *_session, test_wav_path, false, get_test_sample_rate ()); /* Write a staircase to the source */ diff --git a/libs/ardour/test/automation_list_property_test.cc b/libs/ardour/test/automation_list_property_test.cc index 90e2e22989..e5a74cad2f 100644 --- a/libs/ardour/test/automation_list_property_test.cc +++ b/libs/ardour/test/automation_list_property_test.cc @@ -16,11 +16,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <glibmm/fileutils.h> +#include <glibmm/miscutils.h> + #include "pbd/properties.h" #include "pbd/stateful_diff_command.h" #include "ardour/automation_list.h" #include "automation_list_property_test.h" #include "test_util.h" +#include "test_common.h" CPPUNIT_TEST_SUITE_REGISTRATION (AutomationListPropertyTest); @@ -29,6 +33,16 @@ using namespace PBD; using namespace ARDOUR; void +write_automation_list_xml (XMLNode* node, std::string filename) +{ + // use the same output dir for all of them + static std::string test_output_dir = new_test_output_dir ("automation_list_property"); + std::string output_file = Glib::build_filename (test_output_dir, filename); + + CPPUNIT_ASSERT (write_ref (node, output_file)); +} + +void AutomationListPropertyTest::basicTest () { list<string> ignore_properties; @@ -52,9 +66,18 @@ AutomationListPropertyTest::basicTest () /* Now it has changed */ CPPUNIT_ASSERT_EQUAL (true, property.changed()); + std::string test_data_filename = "automation_list_property_test1.ref"; + std::string test_data_file1 = Glib::build_filename (test_search_path().front(), test_data_filename); + CPPUNIT_ASSERT (Glib::file_test (test_data_file1, Glib::FILE_TEST_EXISTS)); + XMLNode* foo = new XMLNode ("test"); property.get_changes_as_xml (foo); - check_xml (foo, "../libs/ardour/test/data/automation_list_property_test1.ref", ignore_properties); + write_automation_list_xml (foo, test_data_filename); + check_xml (foo, test_data_file1, ignore_properties); + + test_data_filename = "automation_list_property_test2.ref"; + std::string test_data_file2 = Glib::build_filename (test_search_path().front(), test_data_filename); + CPPUNIT_ASSERT (Glib::file_test (test_data_file2, Glib::FILE_TEST_EXISTS)); /* Do some more */ property.clear_changes (); @@ -64,7 +87,8 @@ AutomationListPropertyTest::basicTest () CPPUNIT_ASSERT_EQUAL (true, property.changed()); foo = new XMLNode ("test"); property.get_changes_as_xml (foo); - check_xml (foo, "../libs/ardour/test/data/automation_list_property_test2.ref", ignore_properties); + write_automation_list_xml (foo, test_data_filename); + check_xml (foo, test_data_file2, ignore_properties); } /** Here's a StatefulDestructible class that has a AutomationListProperty */ @@ -119,11 +143,21 @@ AutomationListPropertyTest::undoTest () sheila->_jim->add (7, 8); StatefulDiffCommand sdc (sheila); + std::string test_data_filename = "automation_list_property_test3.ref"; + std::string test_data_file3 = Glib::build_filename (test_search_path().front(), test_data_filename); + CPPUNIT_ASSERT (Glib::file_test (test_data_file3, Glib::FILE_TEST_EXISTS)); + /* Undo */ sdc.undo (); - check_xml (&sheila->get_state(), "../libs/ardour/test/data/automation_list_property_test3.ref", ignore_properties); + write_automation_list_xml (&sheila->get_state(), test_data_filename); + check_xml (&sheila->get_state(), test_data_file3, ignore_properties); + + test_data_filename = "automation_list_property_test4.ref"; + std::string test_data_file4 = Glib::build_filename (test_search_path().front(), test_data_filename); + CPPUNIT_ASSERT (Glib::file_test (test_data_file4, Glib::FILE_TEST_EXISTS)); /* Redo */ sdc.redo (); - check_xml (&sheila->get_state(), "../libs/ardour/test/data/automation_list_property_test4.ref", ignore_properties); + write_automation_list_xml (&sheila->get_state(), test_data_filename); + check_xml (&sheila->get_state(), test_data_file4, ignore_properties); } diff --git a/libs/ardour/test/load_session.cc b/libs/ardour/test/load_session.cc index 3f56e63577..f2a2a6922e 100644 --- a/libs/ardour/test/load_session.cc +++ b/libs/ardour/test/load_session.cc @@ -3,7 +3,6 @@ #include "ardour/ardour.h" #include "ardour/audioengine.h" #include "ardour/session.h" -#include "midi++/manager.h" #include <iostream> #include <cstdlib> @@ -41,9 +40,8 @@ int main (int argc, char* argv[]) AudioEngine::instance()->remove_session (); delete s; - AudioEngine::instance()->stop (true); + AudioEngine::instance()->stop (); - MIDI::Manager::destroy (); AudioEngine::destroy (); return 0; diff --git a/libs/ardour/test/playlist_read_test.cc b/libs/ardour/test/playlist_read_test.cc index 54b0bc4fd5..78b2e4eadd 100644 --- a/libs/ardour/test/playlist_read_test.cc +++ b/libs/ardour/test/playlist_read_test.cc @@ -22,7 +22,6 @@ #include "ardour/audioregion.h" #include "ardour/session.h" #include "playlist_read_test.h" -#include "test_globals.h" CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistReadTest); diff --git a/libs/ardour/test/profiling/load_session.cc b/libs/ardour/test/profiling/load_session.cc index 3f56e63577..f2a2a6922e 100644 --- a/libs/ardour/test/profiling/load_session.cc +++ b/libs/ardour/test/profiling/load_session.cc @@ -3,7 +3,6 @@ #include "ardour/ardour.h" #include "ardour/audioengine.h" #include "ardour/session.h" -#include "midi++/manager.h" #include <iostream> #include <cstdlib> @@ -41,9 +40,8 @@ int main (int argc, char* argv[]) AudioEngine::instance()->remove_session (); delete s; - AudioEngine::instance()->stop (true); + AudioEngine::instance()->stop (); - MIDI::Manager::destroy (); AudioEngine::destroy (); return 0; diff --git a/libs/ardour/test/profiling/runpc.cc b/libs/ardour/test/profiling/runpc.cc index ddbd463234..6538fcf88a 100644 --- a/libs/ardour/test/profiling/runpc.cc +++ b/libs/ardour/test/profiling/runpc.cc @@ -1,5 +1,4 @@ #include <iostream> -#include "midi++/manager.h" #include "pbd/textreceiver.h" #include "pbd/compose.h" #include "pbd/enumwriter.h" @@ -31,7 +30,7 @@ main (int argc, char* argv[]) cout << "INFO: " << session->get_routes()->size() << " routes.\n"; for (int i = 0; i < 32768; ++i) { - session->process (session->engine().frames_per_cycle ()); + session->process (session->engine().samples_per_cycle ()); } return 0; diff --git a/libs/ardour/test/session_test.cc b/libs/ardour/test/session_test.cc index 83273b5a2e..ba57b4bd63 100644 --- a/libs/ardour/test/session_test.cc +++ b/libs/ardour/test/session_test.cc @@ -3,7 +3,7 @@ #include <glibmm/miscutils.h> #include <stdexcept> -#include "midi++/manager.h" + #include "pbd/textreceiver.h" #include "pbd/file_utils.h" #include "ardour/session.h" @@ -33,17 +33,12 @@ SessionTest::setUp () text_receiver.listen_to (fatal); text_receiver.listen_to (warning); - // this is not a good singleton constructor pattern - AudioEngine* engine = 0; - - try { - engine = new AudioEngine ("session_test", ""); - } catch (const AudioEngine::NoBackendAvailable& engine_exception) { - cerr << engine_exception.what (); - } + AudioEngine* engine = AudioEngine::create (); CPPUNIT_ASSERT (engine); + CPPUNIT_ASSERT (engine->set_default_backend()); + init_post_engine (); CPPUNIT_ASSERT (engine->start () == 0); @@ -53,9 +48,8 @@ void SessionTest::tearDown () { // this is needed or there is a crash in MIDI::Manager::destroy - AudioEngine::instance()->stop (true); + AudioEngine::instance()->stop (); - MIDI::Manager::destroy (); AudioEngine::destroy (); } diff --git a/libs/ardour/test/test_common.cc b/libs/ardour/test/test_common.cc index 5f802fbf5a..71eba65bbb 100644 --- a/libs/ardour/test/test_common.cc +++ b/libs/ardour/test/test_common.cc @@ -37,13 +37,14 @@ test_search_path () } std::string -new_test_output_dir () +new_test_output_dir (std::string prefix) { std::string tmp_dir = Glib::build_filename (g_get_tmp_dir(), "ardour_test"); std::string dir_name; std::string new_test_dir; do { ostringstream oss; + oss << prefix; oss << g_random_int (); dir_name = oss.str(); new_test_dir = Glib::build_filename (tmp_dir, dir_name); @@ -51,3 +52,9 @@ new_test_output_dir () } while (g_mkdir_with_parents (new_test_dir.c_str(), 0755) != 0); return new_test_dir; } + +int +get_test_sample_rate () +{ + return 44100; +} diff --git a/libs/ardour/test/test_common.h b/libs/ardour/test/test_common.h index 10bfdbc694..bfda543508 100644 --- a/libs/ardour/test/test_common.h +++ b/libs/ardour/test/test_common.h @@ -23,6 +23,8 @@ PBD::Searchpath test_search_path (); -std::string new_test_output_dir (); +std::string new_test_output_dir (std::string prefix = ""); + +int get_test_sample_rate (); #endif diff --git a/libs/ardour/test/test_globals.cc b/libs/ardour/test/test_globals.cc deleted file mode 100644 index e40f951d75..0000000000 --- a/libs/ardour/test/test_globals.cc +++ /dev/null @@ -1,3 +0,0 @@ -#include "test_globals.h" - -int const Fs = 44100; diff --git a/libs/ardour/test/test_globals.h b/libs/ardour/test/test_globals.h deleted file mode 100644 index ccd5c27384..0000000000 --- a/libs/ardour/test/test_globals.h +++ /dev/null @@ -1,2 +0,0 @@ - -extern int const Fs; diff --git a/libs/ardour/test/test_needing_session.cc b/libs/ardour/test/test_needing_session.cc index 181d391e01..4525a758b3 100644 --- a/libs/ardour/test/test_needing_session.cc +++ b/libs/ardour/test/test_needing_session.cc @@ -1,6 +1,5 @@ #include <glibmm/miscutils.h> -#include "midi++/manager.h" #include "pbd/compose.h" #include "pbd/enumwriter.h" #include "ardour/session.h" @@ -26,8 +25,7 @@ TestNeedingSession::tearDown () { AudioEngine::instance()->remove_session (); delete _session; - AudioEngine::instance()->stop (true); + AudioEngine::instance()->stop (); - MIDI::Manager::destroy (); AudioEngine::destroy (); } diff --git a/libs/ardour/test/test_util.cc b/libs/ardour/test/test_util.cc index 1514012d97..dfbf40d351 100644 --- a/libs/ardour/test/test_util.cc +++ b/libs/ardour/test/test_util.cc @@ -60,12 +60,12 @@ check_xml (XMLNode* node, string ref_file, list<string> const & ignore_propertie check_nodes (p, q, ignore_properties); } -void +bool write_ref (XMLNode* node, string ref_file) { XMLTree ref; ref.set_root (node); - ref.write (ref_file); + return ref.write (ref_file); } class TestReceiver : public Receiver @@ -124,7 +124,10 @@ load_session (string dir, string state) */ Config->set_use_lxvst (false); - AudioEngine* engine = new AudioEngine ("test", ""); + AudioEngine* engine = AudioEngine::create (); + + CPPUNIT_ASSERT (engine->set_default_backend ()); + init_post_engine (); CPPUNIT_ASSERT (engine->start () == 0); diff --git a/libs/ardour/test/test_util.h b/libs/ardour/test/test_util.h index fea74a2ea8..dd4b078e9f 100644 --- a/libs/ardour/test/test_util.h +++ b/libs/ardour/test/test_util.h @@ -8,5 +8,5 @@ namespace ARDOUR { } extern void check_xml (XMLNode *, std::string, std::list<std::string> const &); -extern void write_ref (XMLNode *, std::string); +extern bool write_ref (XMLNode *, std::string); extern ARDOUR::Session* load_session (std::string, std::string); diff --git a/libs/ardour/wscript b/libs/ardour/wscript index d0c8eeb877..39584c6390 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -402,7 +402,7 @@ def build(bld): # only build these common sources once testcommon = bld(features = 'cxx') testcommon.includes = obj.includes + ['test', '../pbd', '..'] - testcommon.source = ['test/test_globals.cc', 'test/testrunner.cc', 'test/test_needing_session.cc', + testcommon.source = ['test/testrunner.cc', 'test/test_needing_session.cc', 'test/test_common.cc', 'test/dummy_lxvst.cc', 'test/audio_region_test.cc', 'test/test_util.cc'] testcommon.uselib = ['CPPUNIT','SIGCPP','GLIBMM','GTHREAD', 'SAMPLERATE','XML','LRDF','COREAUDIO'] diff --git a/libs/backends/jack/jack_audiobackend.cc b/libs/backends/jack/jack_audiobackend.cc index a9bbe4b35a..ff76486bad 100644 --- a/libs/backends/jack/jack_audiobackend.cc +++ b/libs/backends/jack/jack_audiobackend.cc @@ -409,6 +409,12 @@ JACKAudioBackend::interleaved () const return false; } +string +JACKAudioBackend::midi_option () const +{ + return _target_midi_option; +} + uint32_t JACKAudioBackend::input_channels () const { @@ -465,7 +471,7 @@ JACKAudioBackend::raw_buffer_size(DataType t) } void -JACKAudioBackend::setup_jack_startup_command () +JACKAudioBackend::setup_jack_startup_command (bool for_latency_measurement) { /* first we map the parameters that have been set onto a * JackCommandLineOptions object. @@ -490,6 +496,8 @@ JACKAudioBackend::setup_jack_startup_command () options.realtime = true; options.ports_max = 2048; + ARDOUR::set_midi_option (options, _target_midi_option); + /* this must always be true for any server instance we start ourselves */ @@ -497,7 +505,7 @@ JACKAudioBackend::setup_jack_startup_command () string cmdline; - if (!get_jack_command_line_string (options, cmdline)) { + if (!get_jack_command_line_string (options, cmdline, for_latency_measurement)) { /* error, somehow - we will still try to start JACK * automatically but it will be without our preferred options */ @@ -512,7 +520,7 @@ JACKAudioBackend::setup_jack_startup_command () /* ---- BASIC STATE CONTROL API: start/stop/pause/freewheel --- */ int -JACKAudioBackend::start () +JACKAudioBackend::_start (bool for_latency_measurement) { if (!available()) { @@ -520,7 +528,7 @@ JACKAudioBackend::start () /* we will be starting JACK, so set up the command that JACK will use when it (auto-)starts */ - setup_jack_startup_command (); + setup_jack_startup_command (for_latency_measurement); } if (_jack_connection->open ()) { @@ -597,7 +605,7 @@ JACKAudioBackend::freewheel (bool onoff) } if (jack_set_freewheel (_priv_jack, onoff) == 0) { - _freewheeling = true; + _freewheeling = onoff; return 0; } @@ -1110,3 +1118,16 @@ JACKAudioBackend::launch_control_app () args.push_back (appname); Glib::spawn_async ("", args, Glib::SPAWN_SEARCH_PATH); } + +vector<string> +JACKAudioBackend::enumerate_midi_options () const +{ + return ARDOUR::enumerate_midi_options (); +} + +int +JACKAudioBackend::set_midi_option (const string& opt) +{ + _target_midi_option = opt; + return 0; +} diff --git a/libs/backends/jack/jack_audiobackend.h b/libs/backends/jack/jack_audiobackend.h index cb24835d5b..3c48be5ead 100644 --- a/libs/backends/jack/jack_audiobackend.h +++ b/libs/backends/jack/jack_audiobackend.h @@ -89,7 +89,7 @@ class JACKAudioBackend : public AudioBackend { std::string control_app_name () const; void launch_control_app (); - int start (); + int _start (bool for_latency_measurement); int stop (); int pause (); int freewheel (bool); @@ -149,6 +149,10 @@ class JACKAudioBackend : public AudioBackend { /* MIDI */ + std::vector<std::string> enumerate_midi_options () const; + int set_midi_option (const std::string&); + std::string midi_option () const; + int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index); int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size); uint32_t get_midi_event_count (void* port_buffer); @@ -221,7 +225,7 @@ class JACKAudioBackend : public AudioBackend { void* process_thread (); static void* _start_process_thread (void*); - void setup_jack_startup_command (); + void setup_jack_startup_command (bool for_latency_measurement); /* pffooo */ @@ -237,6 +241,7 @@ class JACKAudioBackend : public AudioBackend { uint32_t _target_systemic_output_latency; uint32_t _current_sample_rate; uint32_t _current_buffer_size; + std::string _target_midi_option; typedef std::set<std::string> DeviceList; typedef std::map<std::string,DeviceList> DriverDeviceMap; diff --git a/libs/backends/jack/jack_utils.cc b/libs/backends/jack/jack_utils.cc index a78c6491c7..83919eadb6 100644 --- a/libs/backends/jack/jack_utils.cc +++ b/libs/backends/jack/jack_utils.cc @@ -83,6 +83,7 @@ namespace { const char * const dummy_driver_command_line_name = X_("dummy"); // should we provide more "pretty" names like above? + const char * const alsaint_midi_driver_name = X_("alsa"); const char * const alsaseq_midi_driver_name = X_("seq"); const char * const alsaraw_midi_driver_name = X_("raw"); const char * const winmme_midi_driver_name = X_("winmme"); @@ -92,6 +93,8 @@ namespace { const char * const default_device_name = X_("Default"); } +static ARDOUR::MidiOptions midi_options; + std::string get_none_string () { @@ -682,7 +685,7 @@ ARDOUR::JackCommandLineOptions::JackCommandLineOptions () } bool -ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line) +ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line, bool for_latency_measurement) { vector<string> args; @@ -740,6 +743,13 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c } #endif + if (options.driver == alsa_driver_name) { + if (options.midi_driver == alsaint_midi_driver_name) { + args.push_back ("-I"); + args.push_back ("alsa_midi"); + } + } + string command_line_driver_name; if (!get_jack_command_line_audio_driver_name (options.driver, command_line_driver_name)) { @@ -811,7 +821,7 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c args.push_back ("-p"); args.push_back (to_string (options.period_size, std::dec)); - if (get_jack_audio_driver_supports_latency_adjustment (options.driver)) { + if (!for_latency_measurement && get_jack_audio_driver_supports_latency_adjustment (options.driver)) { if (options.input_latency) { args.push_back ("-I"); args.push_back (to_string (options.input_latency, std::dec)); @@ -846,10 +856,15 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c if (options.soft_mode) { args.push_back ("-s"); } + } - if (!options.midi_driver.empty() && options.midi_driver != get_none_string ()) { - args.push_back ("-X"); - args.push_back (options.midi_driver); + if (options.driver == alsa_driver_name || options.driver == coreaudio_driver_name) { + + if (options.midi_driver != alsaint_midi_driver_name) { + if (!options.midi_driver.empty() && options.midi_driver != get_none_string ()) { + args.push_back ("-X"); + args.push_back (options.midi_driver); + } } } @@ -900,3 +915,53 @@ ARDOUR::write_jack_config_file (const std::string& config_file_path, const strin jackdrc.close (); return true; } + +vector<string> +ARDOUR::enumerate_midi_options () +{ + if (midi_options.empty()) { +#ifdef HAVE_ALSA + midi_options.push_back (make_pair (_("ALSA"), alsaint_midi_driver_name)); + midi_options.push_back (make_pair (_("(legacy) ALSA raw devices"), alsaraw_midi_driver_name)); + midi_options.push_back (make_pair (_("(legacy) ALSA sequencer"), alsaseq_midi_driver_name)); +#endif +#ifdef HAVE_PORTAUDIO + /* Windows folks: what name makes sense here? Are there other + choices as well ? + */ + midi_options.push_back (make_pair (_("Multimedia Extension"), winmme_midi_driver_name)); +#endif +#ifdef __APPLE__ + midi_options.push_back (make_pair (_("CoreMIDI"), coremidi_midi_driver_name)); +#endif + } + + vector<string> v; + + v.push_back (get_none_string()); + + for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) { + v.push_back (i->first); + } + + return v; +} + +int +ARDOUR::set_midi_option (ARDOUR::JackCommandLineOptions& options, const string& opt) +{ + if (opt.empty() || opt == get_none_string()) { + options.midi_driver = ""; + return 0; + } + + for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) { + if (i->first == opt) { + options.midi_driver = i->second; + return 0; + } + } + + return -1; +} + diff --git a/libs/backends/jack/jack_utils.h b/libs/backends/jack/jack_utils.h index a7521ad1c4..ee8575c5c8 100644 --- a/libs/backends/jack/jack_utils.h +++ b/libs/backends/jack/jack_utils.h @@ -180,6 +180,8 @@ namespace ARDOUR { */ bool get_jack_default_server_path (std::string& server_path); + typedef std::vector<std::pair<std::string,std::string> > MidiOptions; + /** * @return The name of the jack server config file */ @@ -228,8 +230,11 @@ namespace ARDOUR { std::string midi_driver; }; + std::vector<std::string> enumerate_midi_options (); + int set_midi_option (ARDOUR::JackCommandLineOptions&, const std::string& opt); + /** * @return true if able to build a valid command line based on options */ - bool get_jack_command_line_string (JackCommandLineOptions& options, std::string& command_line); + bool get_jack_command_line_string (JackCommandLineOptions& options, std::string& command_line, bool for_latency_measurement); } diff --git a/libs/pbd/controllable_descriptor.cc b/libs/pbd/controllable_descriptor.cc index 9c930e4dbd..392b917ec8 100644 --- a/libs/pbd/controllable_descriptor.cc +++ b/libs/pbd/controllable_descriptor.cc @@ -104,11 +104,10 @@ ControllableDescriptor::set (const std::string& str) } } else if (path[1] == "send") { - if (path.size() == 3 && rest.size() == 3) { + if (path.size() == 3 && rest.size() == 2) { if (path[2] == "gain") { _subtype = SendGain; _target.push_back (atoi (rest[1])); - _target.push_back (atoi (rest[2])); } else { return -1; } |