Add basic test of playlist layering.
authorCarl Hetherington <carl@carlh.net>
Thu, 15 Dec 2011 14:33:20 +0000 (14:33 +0000)
committerCarl Hetherington <carl@carlh.net>
Thu, 15 Dec 2011 14:33:20 +0000 (14:33 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@11011 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/audioengine.h
libs/ardour/audioengine.cc
libs/ardour/test/playlist_layering_test.cc [new file with mode: 0644]
libs/ardour/test/playlist_layering_test.h [new file with mode: 0644]
libs/ardour/wscript
libs/midi++2/manager.cc
libs/midi++2/midi++/manager.h
libs/midi++2/port.cc
libs/pbd/enumwriter.cc
libs/pbd/pbd/enumwriter.h

index 7d9cb3f28a2cab90c22a96194d0f92455370dad7..ca580419b65e80a31c834c76266fefaaf71a9492 100644 (file)
@@ -254,6 +254,7 @@ _      the regular process() call to session->process() is not made.
        bool port_is_mine (const std::string&) const;
 
        static AudioEngine* instance() { return _instance; }
+       static void destroy();
        void died ();
 
        int create_process_thread (boost::function<void()>, pthread_t*, size_t stacksize);
index 74936fbc34ab53c3ff632033e3c2120b76079b3b..c6cb20bc4d430c01d31d37c76a3ebff07b55f4ac 100644 (file)
@@ -1513,3 +1513,10 @@ AudioEngine::update_latencies ()
                 jack_recompute_total_latencies (_priv_jack);
         }
 }
+
+void
+AudioEngine::destroy ()
+{
+       delete _instance;
+       _instance = 0;
+}
diff --git a/libs/ardour/test/playlist_layering_test.cc b/libs/ardour/test/playlist_layering_test.cc
new file mode 100644 (file)
index 0000000..278fb0a
--- /dev/null
@@ -0,0 +1,144 @@
+#include "midi++/manager.h"
+#include "pbd/textreceiver.h"
+#include "pbd/compose.h"
+#include "ardour/session.h"
+#include "ardour/audioengine.h"
+#include "ardour/playlist_factory.h"
+#include "ardour/source_factory.h"
+#include "ardour/region.h"
+#include "ardour/region_factory.h"
+#include "playlist_layering_test.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistLayeringTest);
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+class TestReceiver : public Receiver 
+{
+protected:
+       void receive (Transmitter::Channel chn, const char * str) {
+               const char *prefix = "";
+               
+               switch (chn) {
+               case Transmitter::Error:
+                       prefix = ": [ERROR]: ";
+                       break;
+               case Transmitter::Info:
+                       /* ignore */
+                       return;
+               case Transmitter::Warning:
+                       prefix = ": [WARNING]: ";
+                       break;
+               case Transmitter::Fatal:
+                       prefix = ": [FATAL]: ";
+                       break;
+               case Transmitter::Throw:
+                       /* this isn't supposed to happen */
+                       abort ();
+               }
+               
+               /* note: iostreams are already thread-safe: no external
+                  lock required.
+               */
+               
+               cout << prefix << str << endl;
+               
+               if (chn == Transmitter::Fatal) {
+                       exit (9);
+               }
+       }
+};
+
+TestReceiver test_receiver;
+
+void
+PlaylistLayeringTest::setUp ()
+{
+       string const test_session_path = "libs/ardour/test/playlist_layering_test";
+       string const test_wav_path = "libs/ardour/test/playlist_layering_test/playlist_layering_test.wav";
+       system (string_compose ("rm -rf %1", test_session_path).c_str());
+       
+       init (false, true);
+       SessionEvent::create_per_thread_pool ("test", 512);
+
+       test_receiver.listen_to (error);
+       test_receiver.listen_to (info);
+       test_receiver.listen_to (fatal);
+       test_receiver.listen_to (warning);
+
+       AudioEngine* engine = new AudioEngine ("test", "");
+       MIDI::Manager::create (engine->jack ());
+       CPPUNIT_ASSERT (engine->start () == 0);
+
+       _session = new Session (*engine, test_session_path, "playlist_layering_test");
+       engine->set_session (_session);
+
+       _playlist = PlaylistFactory::create (DataType::AUDIO, *_session, "test");
+       _source = SourceFactory::createWritable (DataType::AUDIO, *_session, test_wav_path, "", false, 44100);
+}
+
+void
+PlaylistLayeringTest::tearDown ()
+{
+       AudioEngine::instance()->remove_session ();
+       EnumWriter::destroy ();
+       MIDI::Manager::destroy ();
+       AudioEngine::destroy ();
+}
+
+void
+PlaylistLayeringTest::create_three_short_regions ()
+{
+       PropertyList plist;
+       plist.add (Properties::start, 0);
+       plist.add (Properties::length, 100);
+       for (int i = 0; i < 3; ++i) {
+               _region[i] = RegionFactory::create (_source, plist);
+       }
+}
+
+void
+PlaylistLayeringTest::addHigherTest ()
+{
+       _session->config.set_layer_model (AddHigher);
+       create_three_short_regions ();
+
+       _playlist->add_region (_region[0], 0);
+       _playlist->add_region (_region[1], 10);
+       _playlist->add_region (_region[2], 20);
+
+       CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[0]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[1]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[2]->layer ());
+
+       _region[0]->set_position (5);
+
+       /* region move should have no effect */
+       CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[0]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[1]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[2]->layer ());
+}
+
+void
+PlaylistLayeringTest::moveAddHigherTest ()
+{
+       _session->config.set_layer_model (MoveAddHigher);
+       create_three_short_regions ();
+
+       _playlist->add_region (_region[0], 0);
+       _playlist->add_region (_region[1], 10);
+       _playlist->add_region (_region[2], 20);
+
+       CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[0]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[1]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[2]->layer ());
+
+       _region[0]->set_position (5);
+
+       /* region move should have put 0 on top */
+       CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[0]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[1]->layer ());
+       CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[2]->layer ());
+}
diff --git a/libs/ardour/test/playlist_layering_test.h b/libs/ardour/test/playlist_layering_test.h
new file mode 100644 (file)
index 0000000..7757e01
--- /dev/null
@@ -0,0 +1,31 @@
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace ARDOUR {
+       class Session;
+       class Playlist;
+       class Source;
+}
+
+class PlaylistLayeringTest : public CppUnit::TestFixture
+{
+       CPPUNIT_TEST_SUITE (PlaylistLayeringTest);
+       CPPUNIT_TEST (addHigherTest);
+       CPPUNIT_TEST (moveAddHigherTest);
+       CPPUNIT_TEST_SUITE_END ();
+
+public:
+       void setUp ();
+       void tearDown ();
+
+       void addHigherTest ();
+       void moveAddHigherTest ();
+
+private:
+       void create_three_short_regions ();
+       
+       ARDOUR::Session* _session;
+       boost::shared_ptr<ARDOUR::Playlist> _playlist;
+       boost::shared_ptr<ARDOUR::Source> _source;
+       boost::shared_ptr<ARDOUR::Region> _region[16];
+};
index 1c26a16fd04f9622d6a6d9a87ec86b4f3fc402a4..42c72784f9b10b4411eb419e1c18116026766b54 100644 (file)
@@ -430,6 +430,7 @@ def build(bld):
                 test/framewalk_to_beats_test.cc
                 test/framepos_plus_beats_test.cc
                 test/framepos_minus_beats_test.cc
+                test/playlist_layering_test.cc
                 test/testrunner.cc
         '''.split()
 
index 03e418e4b24f48fbd3d77b9375d1c7c909b16ca7..61d4c4c363ba31ac25c5f9fa8198af6058eb9ad4 100644 (file)
@@ -167,3 +167,10 @@ Manager::set_port_states (list<XMLNode*> s)
                }
        }
 }
+
+void
+Manager::destroy ()
+{
+       delete theManager;
+       theManager = 0;
+}
index ecfd7a01118aa6fa47f8b1a2a968192fac44048e..bab4a18dd22dc4635f74d36389d8d9bfbf5ce73f 100644 (file)
@@ -74,6 +74,7 @@ class Manager {
        static Manager *instance () {
                return theManager;
        }
+       static void destroy ();
 
        void reestablish (jack_client_t *);
        void reconnect ();
index 59f76041d63c1417b45087fb077e2e301cbcc55c..213f55aa19470f697d629bd0deec2a718f09eb9f 100644 (file)
@@ -113,10 +113,10 @@ Port::~Port ()
        }
 
        if (_jack_port) {
-               if (_jack_client && _jack_port) {
+               if (_jack_client) {
                        jack_port_unregister (_jack_client, _jack_port);
+                       _jack_port = 0;
                }
-               _jack_port = 0;
        }
 }
 
index 5263a886fbc21845f873a90d5c69cb59762d728c..3ce296c664ccc695b0a774c65d82bc408079228d 100644 (file)
@@ -73,6 +73,13 @@ EnumWriter::instance()
        return *_instance;
 }
 
+void
+EnumWriter::destroy ()
+{
+       delete _instance;
+       _instance = 0;
+}
+
 EnumWriter::EnumWriter ()
 {
 }
index a253719c85f9b44f18cd8c876ba85c797814f215..600f59bf29e4a33c35c8c5ced165adf6f52fb10a 100644 (file)
@@ -37,6 +37,7 @@ class unknown_enumeration : public std::exception {
 class EnumWriter {
   public:
        static EnumWriter& instance();
+       static void destroy();
 
        void register_distinct (std::string type, std::vector<int>, std::vector<std::string>);
        void register_bits     (std::string type, std::vector<int>, std::vector<std::string>);