diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 61 | ||||
-rw-r--r-- | test/audiocacheeventhandlertest.cc | 52 | ||||
-rw-r--r-- | test/audiocachefiletest.cc | 240 | ||||
-rw-r--r-- | test/audiocacheidmanagertest.cc | 101 | ||||
-rw-r--r-- | test/audiocachetest.cc | 180 | ||||
-rw-r--r-- | test/engine.cc | 1 | ||||
-rw-r--r-- | test/kit/ride-multi-channel.wav | bin | 0 -> 28591492 bytes | |||
-rw-r--r-- | test/kit/ride-single-channel.wav | bin | 0 -> 694144 bytes | |||
-rw-r--r-- | test/lv2.cc | 67 | ||||
-rw-r--r-- | test/lv2_test_host.cc | 178 | ||||
-rw-r--r-- | test/lv2_test_host.h | 61 |
11 files changed, 816 insertions, 125 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index 29ab4b1..8a746a6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,8 @@ # Rules for the test code (use `make check` to execute) include $(top_srcdir)/src/Makefile.am.drumgizmo -TESTS = resource engine gui resampler lv2 configfile +TESTS = resource engine gui resampler lv2 configfile audiocache \ + audiocachefile audiocacheidmanager audiocacheeventhandler check_PROGRAMS = $(TESTS) @@ -15,9 +16,65 @@ resource_SOURCES = \ test.cc \ resource_test.cc +audiocache_CXXFLAGS = -DOUTPUT=\"audiocache\" $(CPPUNIT_CFLAGS) \ + -I$(top_srcdir)/src -I$(top_srcdir)/include \ + -I$(top_srcdir)/hugin -DDISABLE_HUGIN $(PTHREAD_CFLAGS) $(SNDFILE_CFLAGS) +audiocache_LDFLAGS = $(PTHREAD_LIBS) $(CPPUNIT_LIBS) $(SNDFILE_LIBS) +audiocache_SOURCES = \ + $(top_srcdir)/src/audiocache.cc \ + $(top_srcdir)/src/audiocacheeventhandler.cc \ + $(top_srcdir)/src/audiocachefile.cc \ + $(top_srcdir)/src/audiocacheidmanager.cc \ + $(top_srcdir)/src/thread.cc \ + $(top_srcdir)/src/mutex.cc \ + $(top_srcdir)/src/semaphore.cc \ + $(top_srcdir)/src/configuration.cc \ + $(top_srcdir)/src/audiofile.cc \ + test.cc \ + audiocachetest.cc + +audiocachefile_CXXFLAGS = -DOUTPUT=\"audiocachefile\" $(CPPUNIT_CFLAGS) \ + -I$(top_srcdir)/src -I$(top_srcdir)/include \ + -I$(top_srcdir)/hugin -DDISABLE_HUGIN $(PTHREAD_CFLAGS) $(SNDFILE_CFLAGS) +audiocachefile_LDFLAGS = $(PTHREAD_LIBS) $(CPPUNIT_LIBS) $(SNDFILE_LIBS) +audiocachefile_SOURCES = \ + $(top_srcdir)/src/audiocachefile.cc \ + $(top_srcdir)/src/thread.cc \ + $(top_srcdir)/src/mutex.cc \ + $(top_srcdir)/src/semaphore.cc \ + $(top_srcdir)/src/configuration.cc \ + $(top_srcdir)/src/audiofile.cc \ + test.cc \ + audiocachefiletest.cc + +audiocacheidmanager_CXXFLAGS = -DOUTPUT=\"audiocacheidmanager\" \ + $(CPPUNIT_CFLAGS) \ + -I$(top_srcdir)/src -I$(top_srcdir)/include \ + -I$(top_srcdir)/hugin -DDISABLE_HUGIN $(SNDFILE_CFLAGS) +audiocacheidmanager_LDFLAGS = $(CPPUNIT_LIBS) $(SNDFILE_LIBS) +audiocacheidmanager_SOURCES = \ + $(top_srcdir)/src/audiocacheidmanager.cc \ + test.cc \ + audiocacheidmanagertest.cc + +audiocacheeventhandler_CXXFLAGS = -DOUTPUT=\"audiocacheeventhandler\" \ + $(CPPUNIT_CFLAGS) \ + -I$(top_srcdir)/src -I$(top_srcdir)/include \ + -I$(top_srcdir)/hugin -DDISABLE_HUGIN $(PTHREAD_CFLAGS) $(SNDFILE_CFLAGS) +audiocacheeventhandler_LDFLAGS = $(PTHREAD_LIBS) $(CPPUNIT_LIBS) $(SNDFILE_LIBS) +audiocacheeventhandler_SOURCES = \ + $(top_srcdir)/src/audiocacheeventhandler.cc \ + $(top_srcdir)/src/audiocacheidmanager.cc \ + $(top_srcdir)/src/audiocachefile.cc \ + $(top_srcdir)/src/mutex.cc \ + $(top_srcdir)/src/thread.cc \ + $(top_srcdir)/src/semaphore.cc \ + test.cc \ + audiocacheeventhandlertest.cc + engine_CXXFLAGS = -DOUTPUT=\"engine\" $(CPPUNIT_CFLAGS) \ -I$(top_srcdir)/src -I$(top_srcdir)/include \ - -I$(top_srcdir)/hugin -DDISABLE_HUGIN + -I$(top_srcdir)/hugin -DDISABLE_HUGIN $(PTHREAD_CFLAGS) engine_CFLAGS = -DDISABLE_HUGIN engine_LDFLAGS = $(CPPUNIT_LIBS) $(DRUMGIZMO_LIBS) $(PTHREAD_LIBS) engine_SOURCES = \ diff --git a/test/audiocacheeventhandlertest.cc b/test/audiocacheeventhandlertest.cc new file mode 100644 index 0000000..5f30d2e --- /dev/null +++ b/test/audiocacheeventhandlertest.cc @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * audiocacheeventhandlertest.cc + * + * Thu Jan 7 15:44:14 CET 2016 + * Copyright 2016 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo 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. + * + * DrumGizmo 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 DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <cppunit/extensions/HelperMacros.h> + +#include <audiocacheeventhandler.h> + +class AudioCacheEventHandlerTest + : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(AudioCacheEventHandlerTest); + CPPUNIT_TEST(threadedTest); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + void threadedTest() + { + AudioCacheIDManager id_manager; + id_manager.init(10); + + AudioCacheEventHandler event_handler(id_manager); + } +}; + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(AudioCacheEventHandlerTest); diff --git a/test/audiocachefiletest.cc b/test/audiocachefiletest.cc new file mode 100644 index 0000000..98b7ab5 --- /dev/null +++ b/test/audiocachefiletest.cc @@ -0,0 +1,240 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * audiocachefiletest.cc + * + * Thu Jan 7 15:43:12 CET 2016 + * Copyright 2016 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo 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. + * + * DrumGizmo 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 DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <cppunit/extensions/HelperMacros.h> + +#include <cstring> + +#include <audiocachefile.h> +#include <audiofile.h> + +class TestableAudioCacheFiles + : public AudioCacheFiles +{ +public: + //CacheAudioFile& getAudioFile(const std::string& filename); + //void release(const std::string& filename); + int getRef(const std::string& filename) + { + if(audiofiles.find(filename) == audiofiles.end()) + { + return -1; + } + + return audiofiles[filename]->ref; + } +}; + +class AudioCacheFileTest + : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(AudioCacheFileTest); + CPPUNIT_TEST(refTest); + CPPUNIT_TEST(readTest); + CPPUNIT_TEST(noFileTest); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + void refTest() + { + TestableAudioCacheFiles audiofiles; + std::string filename = "kit/ride-single-channel.wav"; + CPPUNIT_ASSERT_EQUAL(-1, audiofiles.getRef(filename)); + + audiofiles.getFile(filename); + CPPUNIT_ASSERT_EQUAL(1, audiofiles.getRef(filename)); + + audiofiles.getFile(filename); + CPPUNIT_ASSERT_EQUAL(2, audiofiles.getRef(filename)); + + audiofiles.releaseFile(filename); + CPPUNIT_ASSERT_EQUAL(1, audiofiles.getRef(filename)); + + audiofiles.releaseFile(filename); + CPPUNIT_ASSERT_EQUAL(-1, audiofiles.getRef(filename)); + } + + void readTestHelper(size_t buffer_size) + { + printf("Test buffer size: %d samples\n", (int)buffer_size); + + std::string filename = "kit/ride-multi-channel.wav"; + AudioFile* ref_file[13]; + for(size_t c = 0; c < 13; ++c) + { + ref_file[c] = new AudioFile(filename, c); + ref_file[c]->load(); + } + + AudioCacheFile file(filename); + CPPUNIT_ASSERT_EQUAL(filename, file.getFilename()); + CPPUNIT_ASSERT_EQUAL(13, (int)file.getChannelCount()); // Sanity check + + CacheChannels channels; + + sample_t samples[13][buffer_size]; + volatile bool ready[13]; + for(size_t c = 0; c < 13; ++c) + { + for(size_t i = 0; i < buffer_size; ++i) + { + samples[c][i] = 42; + } + + channels.push_back( + { + c, // channel + samples[c], // samples + buffer_size, // max_num_samples + &ready[c] // ready + } + ); + } + + for(size_t offset = 0; offset < file.getSize(); offset += buffer_size) + { + for(size_t c = 0; c < 13; ++c) + { + ready[c] = false; + } + + size_t read_size = file.getSize() - offset; + if(read_size > buffer_size) + { + read_size = buffer_size; + } + else + { + printf("Last read: %d samples\n", (int)read_size); + } + + file.readChunk(channels, offset, read_size); + + for(size_t c = 0; c < 13; ++c) + { + CPPUNIT_ASSERT_EQUAL(true, ready[c]?true:false); + } + + sample_t diff[13] = {0.0}; + for(size_t c = 0; c < 13; ++c) + { + for(size_t i = 0; i < read_size; ++i) + { + diff[c] += abs(ref_file[c]->data[i + offset] - samples[c][i]); + } + } + + for(int c = 0; c < 13; ++c) + { + CPPUNIT_ASSERT_EQUAL((sample_t)0.0, diff[c]); + } + } + + for(size_t c = 0; c < 13; ++c) + { + delete ref_file[c]; + } + } + + void readTest() + { + // Exhaustive test for 1...64 + for(size_t buffer_size = 1; buffer_size < 64; ++buffer_size) + { + readTestHelper(buffer_size); + } + + // Binary test for 64 .. 4096 + for(size_t buffer_size = 64; buffer_size < 4096; buffer_size *= 2) + { + readTestHelper(buffer_size); + } + + // And some sporadic tests for some "wierd" sizes. + for(size_t buffer_size = 65; buffer_size < 4096; buffer_size *= 1.1) + { + readTestHelper(buffer_size); + } + } + + void noFileTest() + { + size_t buffer_size = 64; + std::string filename = "kits/no-such-file.wav"; + + AudioCacheFile file(filename); + CPPUNIT_ASSERT_EQUAL(filename, file.getFilename()); + CPPUNIT_ASSERT_EQUAL(0u, (unsigned int)file.getSize()); + CPPUNIT_ASSERT_EQUAL(0u, (unsigned int)file.getChannelCount()); + + CacheChannels channels; + + sample_t samples[13][buffer_size]; + volatile bool ready[13]; + for(size_t c = 0; c < 13; ++c) + { + for(size_t i = 0; i < buffer_size; ++i) + { + samples[c][i] = 42.0f; + } + + channels.push_back( + { + c, // channel + samples[c], // samples + buffer_size, // max_num_samples + &ready[c] // ready + } + ); + } + + for(size_t c = 0; c < 13; ++c) + { + ready[c] = false; + } + + file.readChunk(channels, 0, buffer_size); + + for(size_t c = 0; c < 13; ++c) + { + CPPUNIT_ASSERT_EQUAL(false, ready[c]?true:false); + } + + for(size_t c = 0; c < 13; ++c) + { + for(size_t i = 0; i < buffer_size; ++i) + { + CPPUNIT_ASSERT_EQUAL(42.0f, samples[c][i]); + } + } + } +}; + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(AudioCacheFileTest); diff --git a/test/audiocacheidmanagertest.cc b/test/audiocacheidmanagertest.cc new file mode 100644 index 0000000..a9cc878 --- /dev/null +++ b/test/audiocacheidmanagertest.cc @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * audiocacheidmanagertest.cc + * + * Thu Jan 7 15:42:31 CET 2016 + * Copyright 2016 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo 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. + * + * DrumGizmo 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 DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <cppunit/extensions/HelperMacros.h> + +#include <audiocacheidmanager.h> + +class TestableAudioCacheIDManager + : public AudioCacheIDManager +{ +public: + int getAvailableIDs() + { + return availableids.size(); + } +}; + +class AudioCacheIDManagerTest + : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(AudioCacheIDManagerTest); + CPPUNIT_TEST(registerReleaseTest); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + void registerReleaseTest() + { + TestableAudioCacheIDManager manager; + manager.init(2); + + cache_t c1; c1.afile = (AudioCacheFile*)1; + auto id1 = manager.registerID(c1); + CPPUNIT_ASSERT(id1 != CACHE_DUMMYID); + CPPUNIT_ASSERT(id1 != CACHE_NOID); + CPPUNIT_ASSERT_EQUAL(1, manager.getAvailableIDs()); + + cache_t c2; c2.afile = (AudioCacheFile*)2; + auto id2 = manager.registerID(c2); + CPPUNIT_ASSERT(id2 != CACHE_DUMMYID); + CPPUNIT_ASSERT(id2 != CACHE_NOID); + CPPUNIT_ASSERT_EQUAL(0, manager.getAvailableIDs()); + + cache_t c3; c3.afile = (AudioCacheFile*)3; + auto id3 = manager.registerID(c3); + CPPUNIT_ASSERT(id3 == CACHE_DUMMYID); + CPPUNIT_ASSERT_EQUAL(0, manager.getAvailableIDs()); + + cache_t& tc1 = manager.getCache(id1); + CPPUNIT_ASSERT_EQUAL(c1.afile, tc1.afile); + + cache_t& tc2 = manager.getCache(id2); + CPPUNIT_ASSERT_EQUAL(c2.afile, tc2.afile); + + manager.releaseID(id1); + CPPUNIT_ASSERT_EQUAL(1, manager.getAvailableIDs()); + + cache_t c4; c4.afile = (AudioCacheFile*)4; + auto id4 = manager.registerID(c4); + CPPUNIT_ASSERT(id4 != CACHE_DUMMYID); + CPPUNIT_ASSERT(id4 != CACHE_NOID); + CPPUNIT_ASSERT_EQUAL(0, manager.getAvailableIDs()); + + cache_t& tc4 = manager.getCache(id4); + CPPUNIT_ASSERT_EQUAL(c4.afile, tc4.afile); + + manager.releaseID(id2); + CPPUNIT_ASSERT_EQUAL(1, manager.getAvailableIDs()); + + manager.releaseID(id4); + CPPUNIT_ASSERT_EQUAL(2, manager.getAvailableIDs()); + } +}; + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(AudioCacheIDManagerTest); diff --git a/test/audiocachetest.cc b/test/audiocachetest.cc new file mode 100644 index 0000000..5db5940 --- /dev/null +++ b/test/audiocachetest.cc @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * cachemanagertest.cc + * + * Sun Apr 19 10:15:59 CEST 2015 + * Copyright 2015 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo 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. + * + * DrumGizmo 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 DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <cppunit/extensions/HelperMacros.h> + +#include <audiofile.h> +#include <audiocache.h> +#include <unistd.h> + +#define FRAMESIZE 64 + +class AudioCacheTest + : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(AudioCacheTest); + CPPUNIT_TEST(singleChannelNonThreaded); + CPPUNIT_TEST(singleChannelThreaded); + CPPUNIT_TEST(multiChannelNonThreaded); + CPPUNIT_TEST(multiChannelThreaded); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + //! Test runner. + //! \param filename The name of the file to read. + //! \param channel The channel number to do comparison on. + //! \param thread Control if this test is running in threaded mode or not. + //! \param framesize The initial framesize to use. + void testHelper(const char* filename, int channel, bool threaded, + int framesize) + { + // Reference file: + AudioFile audio_file_ref(filename, channel); + printf("audio_file_ref.load\n"); + audio_file_ref.load(ALL_SAMPLES); + + // Input file: + AudioFile audio_file(filename, channel); + printf("audio_file.load\n"); + audio_file.load(4096); + + AudioCache audio_cache; + printf("audio_cache.init\n"); + audio_cache.init(100); + audio_cache.setAsyncMode(threaded); + + // Set initial (upper limit) framesize + audio_cache.setFrameSize(framesize); + + cacheid_t id; + + for(size_t initial_samples_needed = 0; + initial_samples_needed < (size_t)(framesize + 1); + ++initial_samples_needed) + { + + printf("open: initial_samples_needed: %d\n", (int)initial_samples_needed); + sample_t *samples = + audio_cache.open(&audio_file, initial_samples_needed, channel, id); + size_t size = initial_samples_needed; + size_t offset = 0; + + // Test pre cache: + for(size_t i = 0; i < size; ++i) + { + CPPUNIT_ASSERT_EQUAL(audio_file_ref.data[offset], samples[i]); + ++offset; + } + + // Test the rest + while(offset < audio_file_ref.size) + { + if(threaded) + { + // Wait until we are finished reading + int timeout = 1000; + while(!audio_cache.isReady(id)) + { + usleep(1000); + if(--timeout == 0) + { + CPPUNIT_ASSERT(false); // timeout + } + } + } + + samples = audio_cache.next(id, size); + + CPPUNIT_ASSERT_EQUAL(0, (int)audio_cache.getNumberOfUnderruns()); + + for(size_t i = 0; (i < size) && (offset < audio_file_ref.size); ++i) + { + if(audio_file_ref.data[offset] != samples[i]) + { + printf("-----> offset: %d, size: %d, diff: %d," + " i: %d, size: %d, block-diff: %d\n", + (int)offset, (int)audio_file_ref.size, + (int)(audio_file_ref.size - offset), + (int)i, (int)size, (int)(size - i)); + } + CPPUNIT_ASSERT_EQUAL(audio_file_ref.data[offset], samples[i]); + ++offset; + } + } + + audio_cache.close(id); + } + + printf("done\n"); + } + + void singleChannelNonThreaded() + { + printf("\nsinglechannel_nonthreaded()\n"); + const char filename[] = "kit/ride-single-channel.wav"; + int channel = 0; + bool threaded = false; + testHelper(filename, channel, threaded, FRAMESIZE); + } + + void singleChannelThreaded() + { + printf("\nsinglechannel_threaded()\n"); + const char filename[] = "kit/ride-single-channel.wav"; + int channel = 0; + bool threaded = true; + testHelper(filename, channel, threaded, FRAMESIZE); + } + + void multiChannelNonThreaded() + { + printf("\nmultichannel_nonthreaded()\n"); + const char filename[] = "kit/ride-multi-channel.wav"; + int channel = 0; + bool threaded = false; + testHelper(filename, channel, threaded, FRAMESIZE); + ++channel; + testHelper(filename, channel, threaded, FRAMESIZE); + } + + void multiChannelThreaded() + { + printf("\nmultichannel_threaded()\n"); + const char filename[] = "kit/ride-multi-channel.wav"; + int channel = 0; + bool threaded = true; + testHelper(filename, channel, threaded, FRAMESIZE); + ++channel; + testHelper(filename, channel, threaded, FRAMESIZE); + } + +}; + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(AudioCacheTest); diff --git a/test/engine.cc b/test/engine.cc index 69d2a37..4c49a6c 100644 --- a/test/engine.cc +++ b/test/engine.cc @@ -43,6 +43,7 @@ public: AudioOutputEngine *oe = NULL; AudioInputEngine *ie = NULL; DrumGizmo dg(oe, ie); + dg.setFrameSize(100); // Switch kits emmidiately with giving the loader time to work: for(int i = 0; i < 100; i++) { diff --git a/test/kit/ride-multi-channel.wav b/test/kit/ride-multi-channel.wav Binary files differnew file mode 100644 index 0000000..3dec8a9 --- /dev/null +++ b/test/kit/ride-multi-channel.wav diff --git a/test/kit/ride-single-channel.wav b/test/kit/ride-single-channel.wav Binary files differnew file mode 100644 index 0000000..1760697 --- /dev/null +++ b/test/kit/ride-single-channel.wav diff --git a/test/lv2.cc b/test/lv2.cc index 32d896c..0ecf178 100644 --- a/test/lv2.cc +++ b/test/lv2.cc @@ -35,6 +35,12 @@ #define DG_URI "http://drumgizmo.org/lv2" +enum class Ports { + FreeWheel = 0, + MidiPort, + AudioPortOffset, +}; + /** * Tests that should be performed: * ------------------------------- @@ -86,7 +92,7 @@ public: res = h.verify(); CPPUNIT_ASSERT_EQUAL(0, res); - res = h.createInstance(); + res = h.createInstance(44100); CPPUNIT_ASSERT_EQUAL(0, res); const char config_fmt[] = @@ -127,7 +133,7 @@ public: // run for 1 samples to trigger kit loading res = h.run(1); CPPUNIT_ASSERT_EQUAL(0, res); - sleep(1); // wait for kit to get loaded (async), + usleep(1000); // wait for kit to get loaded (async), res = h.run(100); CPPUNIT_ASSERT_EQUAL(0, res); @@ -151,7 +157,7 @@ public: res = h.verify(); CPPUNIT_ASSERT_EQUAL(0, res); - res = h.createInstance(); + res = h.createInstance(44100); CPPUNIT_ASSERT_EQUAL(0, res); const char config_fmt[] = @@ -191,15 +197,19 @@ public: // Port buffers: char sequence_buffer[4096]; + bool freeWheel = false; + + // Free wheel port + res = h.connectPort((int)Ports::FreeWheel, (void*)&freeWheel); LV2TestHost::Sequence seq(sequence_buffer, sizeof(sequence_buffer)); - res = h.connectPort(0, seq.data()); + res = h.connectPort((int)Ports::MidiPort, seq.data()); CPPUNIT_ASSERT_EQUAL(0, res); // run for 1 samples to trigger kit loading res = h.run(1); CPPUNIT_ASSERT_EQUAL(0, res); - sleep(1); // wait for kit to get loaded (async), + usleep(1000); // wait for kit to get loaded (async), seq.addMidiNote(5, 1, 127); res = h.run(100); @@ -224,7 +234,7 @@ public: res = h.verify(); CPPUNIT_ASSERT_EQUAL(0, res); - res = h.createInstance(); + res = h.createInstance(44100); CPPUNIT_ASSERT_EQUAL(0, res); const char config_fmt[] = @@ -265,14 +275,22 @@ public: // Port buffers: char sequence_buffer[4096]; float pcm_buffer[16][10]; + bool freeWheel = true; + + // Free wheel port + res = h.connectPort((int)Ports::FreeWheel, (void*)&freeWheel); LV2TestHost::Sequence seq(sequence_buffer, sizeof(sequence_buffer)); - res = h.connectPort(0, seq.data()); + res = h.connectPort((int)Ports::MidiPort, seq.data()); CPPUNIT_ASSERT_EQUAL(0, res); - for(int i = 1; i <= 16; i++) { - memset(pcm_buffer, 1, sizeof(pcm_buffer)); - res += h.connectPort(i, pcm_buffer[i-1]); + for(int i = 0; i < 16; ++i) + { + for(int j = 0; j < 10; ++j) + { + pcm_buffer[i][j] = 0.42; + } + res += h.connectPort((int)Ports::AudioPortOffset + i, pcm_buffer[i]); } CPPUNIT_ASSERT_EQUAL(0, res); @@ -282,19 +300,19 @@ public: sleep(1); // wait for kit to get loaded (async), seq.addMidiNote(5, 1, 127); - for(int i = 0; i < 10; i++) { + for(int i = 0; i < 10; i++) + { res = h.run(10); + usleep(1000); CPPUNIT_ASSERT_EQUAL(0, res); - /* - printf("Iteration:\n"); - for(int k = 0; k < 4; k++) { - printf("#%d ", k); - for(int j = 0; j < 10; j++) printf("[%f]", pcm_buffer[k][j]); - printf("\n"); - } - printf("\n"); - */ + //printf("Iteration:\n"); + //for(int k = 0; k < 16; k++) { + // printf("#%d ", k); + // for(int j = 0; j < 10; j++) printf("[%f]", pcm_buffer[k][j]); + // printf("\n"); + //} + //printf("\n"); seq.clear(); } @@ -302,6 +320,7 @@ public: seq.addMidiNote(5, 1, 127); res = h.run(10); + usleep(1000); CPPUNIT_ASSERT_EQUAL(0, res); /* @@ -321,9 +340,11 @@ public: comp_val.u = 1040744448; // floating point value 0.133301.... - for(int k = 0; k < 4; k++) { - for(int j = 0; j < 10; j++) { - CPPUNIT_ASSERT_EQUAL(((j==0)?comp_val.f:0), pcm_buffer[k][j]); + for(int k = 0; k < 4; k++) + { + for(int j = 0; j < 10; j++) + { + CPPUNIT_ASSERT_EQUAL(((j==5)?comp_val.f:0), pcm_buffer[k][j]); } } seq.clear(); diff --git a/test/lv2_test_host.cc b/test/lv2_test_host.cc index 375ae40..9b4fc7a 100644 --- a/test/lv2_test_host.cc +++ b/test/lv2_test_host.cc @@ -42,6 +42,7 @@ #include <openssl/err.h> #include <openssl/evp.h> #include <string> + class Base64 { public: Base64() @@ -64,36 +65,44 @@ public: std::string write(const char *in, size_t size) { std::string out; - + BIO_write((BIO*)bio, in, size); size_t osize = BIO_ctrl_pending((BIO*)mbio); char *outbuf = (char*)malloc(osize); int len = BIO_read((BIO*)mbio, outbuf, osize); - if(len < 1) return ""; + if(len < 1) + { + return ""; + } + out.append(outbuf, len); free(outbuf); - + return out; } - + std::string flush() { std::string out; - + (void)BIO_flush((BIO*)bio); size_t size = BIO_ctrl_pending((BIO*)mbio); char *outbuf = (char*)malloc(size); int len = BIO_read((BIO*)mbio, outbuf, size); - if(len < 1) return ""; + if(len < 1) + { + return ""; + } + out.append(outbuf, len); free(outbuf); - + return out; } @@ -107,13 +116,15 @@ private: // TODO: Use map<int, std::string> instead -static char** uris = NULL; +static char** uris = nullptr; static size_t n_uris = 0; static LV2_URID map_uri(LV2_URID_Map_Handle handle, const char* uri) { - for(size_t i = 0; i < n_uris; ++i) { - if(!strcmp(uris[i], uri)) { + for(size_t i = 0; i < n_uris; ++i) + { + if(!strcmp(uris[i], uri)) + { return i + 1; } } @@ -126,22 +137,23 @@ static LV2_URID map_uri(LV2_URID_Map_Handle handle, const char* uri) static const char* unmap_uri(LV2_URID_Map_Handle handle, LV2_URID urid) { - if(urid > 0 && urid <= n_uris) { + if((urid > 0) && (urid <= n_uris)) + { return uris[urid - 1]; } - return NULL; + return nullptr; } -LV2_URID_Map map = { NULL, map_uri }; +LV2_URID_Map map = { nullptr, map_uri }; LV2_Feature map_feature = { LV2_URID_MAP_URI, &map }; -LV2_URID_Unmap unmap = { NULL, unmap_uri }; +LV2_URID_Unmap unmap = { nullptr, unmap_uri }; LV2_Feature unmap_feature = { LV2_URID_UNMAP_URI, &unmap }; -const LV2_Feature* features[] = { &map_feature, &unmap_feature, NULL }; +const LV2_Feature* features[] = { &map_feature, &unmap_feature, nullptr }; LV2TestHost::Sequence::Sequence(void *buffer, size_t buffer_size) { - this->buffer = buffer; - this->buffer_size = buffer_size; + this->buffer = buffer; + this->buffer_size = buffer_size; seq = (LV2_Atom_Sequence *)buffer; @@ -152,15 +164,14 @@ LV2TestHost::Sequence::Sequence(void *buffer, size_t buffer_size) } // Keep this to support atom extension from lv2 < 1.10 -static inline void -_lv2_atom_sequence_clear(LV2_Atom_Sequence* seq) +static inline void _lv2_atom_sequence_clear(LV2_Atom_Sequence* seq) { - seq->atom.size = sizeof(LV2_Atom_Sequence_Body); + seq->atom.size = sizeof(LV2_Atom_Sequence_Body); } void LV2TestHost::Sequence::clear() { - _lv2_atom_sequence_clear(seq); + _lv2_atom_sequence_clear(seq); } // Keep this to support atom extension from lv2 < 1.10 @@ -169,18 +180,19 @@ _lv2_atom_sequence_append_event(LV2_Atom_Sequence* seq, uint32_t capacity, const LV2_Atom_Event* event) { - const uint32_t total_size = (uint32_t)sizeof(*event) + event->body.size; - - if (capacity - seq->atom.size < total_size) { - return NULL; - } - - LV2_Atom_Event* e = lv2_atom_sequence_end(&seq->body, seq->atom.size); - memcpy(e, event, total_size); - - seq->atom.size += lv2_atom_pad_size(total_size); - - return e; + const uint32_t total_size = (uint32_t)sizeof(*event) + event->body.size; + + if(capacity - seq->atom.size < total_size) + { + return nullptr; + } + + LV2_Atom_Event* e = lv2_atom_sequence_end(&seq->body, seq->atom.size); + memcpy(e, event, total_size); + + seq->atom.size += lv2_atom_pad_size(total_size); + + return e; } void LV2TestHost::Sequence::addMidiNote(uint64_t pos, @@ -197,66 +209,88 @@ void LV2TestHost::Sequence::addMidiNote(uint64_t pos, ev.event.time.frames = pos;// sample position ev.event.body.type = map.map(map.handle, LV2_MIDI__MidiEvent); ev.event.body.size = sizeof(ev.msg); - + ev.msg[0] = note_on; ev.msg[1] = key; ev.msg[2] = velocity; LV2_Atom_Event *e = _lv2_atom_sequence_append_event(seq, this->buffer_size, &ev.event); - (void)e; + (void)e; } void *LV2TestHost::Sequence::data() { - return buffer; + return buffer; } LV2TestHost::LV2TestHost(const char *lv2_path) { - if(lv2_path) { - setenv("LV2_PATH", lv2_path, 1); - } + if(lv2_path) + { + setenv("LV2_PATH", lv2_path, 1); + } world = lilv_world_new(); - if(world == NULL) return; + if(world == nullptr) + { + return; + } lilv_world_load_all(world); } LV2TestHost::~LV2TestHost() { - if(world) lilv_world_free(world); + if(world) + { + lilv_world_free(world); + } } int LV2TestHost::open(const char *plugin_uri) { - if(world == NULL) return 1; + if(world == nullptr) + { + return 1; + } plugins = lilv_world_get_all_plugins(world); - if(plugins == NULL) return 2; + if(plugins == nullptr) + { + return 2; + } uri = lilv_new_uri(world, plugin_uri); - if(uri == NULL) return 3; + if(uri == nullptr) + { + return 3; + } plugin = lilv_plugins_get_by_uri(plugins, uri); - if(plugin == NULL) return 4; - + if(plugin == nullptr) + { + return 4; + } - return 0; + return 0; } int LV2TestHost::verify() { bool verify = lilv_plugin_verify(plugin); - if(!verify) return 1; - return 0; + if(!verify) + { + return 1; + } + + return 0; } int LV2TestHost::close() { - // plugin is a const pointer; nothing to close here. - return 0; + // plugin is a const pointer; nothing to close here. + return 0; } /* // Get metadata @@ -330,29 +364,37 @@ int LV2TestHost::getPorts() } } */ -int LV2TestHost::createInstance() +int LV2TestHost::createInstance(size_t samplerate) { - instance = lilv_plugin_instantiate(plugin, 48000, features); - if(instance == NULL) return 1; - return 0; + instance = lilv_plugin_instantiate(plugin, samplerate, features); + if(instance == nullptr) + { + return 1; + } + + return 0; } int LV2TestHost::destroyInstance() { - if(instance) lilv_instance_free(instance); - return 0; + if(instance) + { + lilv_instance_free(instance); + } + + return 0; } int LV2TestHost::activate() { lilv_instance_activate(instance); - return 0; + return 0; } int LV2TestHost::deactivate() { lilv_instance_deactivate(instance); - return 0; + return 0; } int LV2TestHost::loadConfig(const char *config, size_t size) @@ -379,26 +421,26 @@ int LV2TestHost::loadConfig(const char *config, size_t size) { LilvState* restore_state = lilv_state_new_from_string(world, &map, ttl_config); - - lilv_state_restore(restore_state, instance, NULL, NULL, - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE, - features); + + lilv_state_restore(restore_state, instance, nullptr, nullptr, + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE, + features); } - return 0; + return 0; } int LV2TestHost::connectPort(int port, void *portdata) { - // if(lilv_port_is_a(p, port, lv2_ControlPort)) ... + // if(lilv_port_is_a(p, port, lv2_ControlPort)) ... lilv_instance_connect_port(instance, port, portdata); - return 0; + return 0; } int LV2TestHost::run(int num_samples) { - lilv_instance_run(instance, num_samples); - return 0; + lilv_instance_run(instance, num_samples); + return 0; } diff --git a/test/lv2_test_host.h b/test/lv2_test_host.h index f0677c7..81aa413 100644 --- a/test/lv2_test_host.h +++ b/test/lv2_test_host.h @@ -24,56 +24,53 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_LV2_TEST_HOST_H__ -#define __DRUMGIZMO_LV2_TEST_HOST_H__ +#pragma once #include <lilv/lilv.h> #include <lv2/lv2plug.in/ns/ext/atom/atom.h> class LV2TestHost { public: - class Sequence { - public: - Sequence(void *buffer, size_t buffer_size); - void clear(); - void addMidiNote(uint64_t pos, uint8_t key, int8_t velocity); - void *data(); + class Sequence { + public: + Sequence(void *buffer, size_t buffer_size); + void clear(); + void addMidiNote(uint64_t pos, uint8_t key, int8_t velocity); + void *data(); - private: - void *buffer; - size_t buffer_size; - LV2_Atom_Sequence *seq; - }; + private: + void *buffer; + size_t buffer_size; + LV2_Atom_Sequence *seq; + }; - LV2TestHost(const char *lv2_path); - ~LV2TestHost(); + LV2TestHost(const char *lv2_path); + ~LV2TestHost(); - int open(const char *plugin_uri); - int close(); + int open(const char *plugin_uri); + int close(); - int verify(); + int verify(); - //void getMetadata(); - //int getPorts(); + //void getMetadata(); + //int getPorts(); - int createInstance(); - int destroyInstance(); + int createInstance(size_t samplerate); + int destroyInstance(); - int connectPort(int port, void *portdata); + int connectPort(int port, void *portdata); - int activate(); - int deactivate(); + int activate(); + int deactivate(); - int loadConfig(const char *config, size_t size); - int run(int num_samples); + int loadConfig(const char *config, size_t size); + int run(int num_samples); private: - LilvWorld* world; - const LilvPlugins* plugins; + LilvWorld* world; + const LilvPlugins* plugins; LilvNode* uri; const LilvPlugin* plugin; - LilvInstance* instance; + LilvInstance* instance; }; - -#endif/*__DRUMGIZMO_LV2_TEST_HOST_H__*/ |