diff --git a/CMakeLists.txt b/CMakeLists.txt index 3decff49..f8edc1f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,7 +134,7 @@ add_executable(sfizz_tests ${TEST_SOURCES} ${COMMON_SOURCES}) if(UNIX) target_link_libraries(sfizz_tests stdc++fs) endif(UNIX) -target_link_libraries(sfizz_tests Catch2::Catch2 absl::strings) +target_link_libraries(sfizz_tests Catch2::Catch2 absl::strings absl::flat_hash_map sndfile readerwriterqueue) target_include_directories(sfizz_tests SYSTEM PRIVATE sources) file(COPY "tests" DESTINATION ${CMAKE_BINARY_DIR}) @@ -147,9 +147,17 @@ endif(UNIX) target_link_libraries(bench_fill absl::strings benchmark) ############################### -add_executable(bench_read benchmarks/Stereo_Read_Interleaved.cpp ${COMMON_SOURCES}) +add_executable(bench_read benchmarks/Stereo_Read_Interleaved.cpp sources/StereoBufferSSE.cpp) # Per OS properties if(UNIX) target_link_libraries(bench_read stdc++fs) endif(UNIX) target_link_libraries(bench_read absl::strings benchmark) + +############################### +add_executable(bench_write benchmarks/Stereo_Write_Interleaved.cpp sources/StereoBufferSSE.cpp) +# Per OS properties +if(UNIX) + target_link_libraries(bench_write stdc++fs) +endif(UNIX) +target_link_libraries(bench_write absl::strings benchmark) diff --git a/benchmarks/Stereo_Write_Interleaved.cpp b/benchmarks/Stereo_Write_Interleaved.cpp new file mode 100644 index 00000000..393d108c --- /dev/null +++ b/benchmarks/Stereo_Write_Interleaved.cpp @@ -0,0 +1,53 @@ +#include +#include "../sources/StereoBuffer.h" +#include +#include + +static void Interleaved_Write(benchmark::State& state) { + StereoBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + buffer.readInterleaved(input.data(), state.range(0)); + std::vector output (state.range(0) * 2); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.writeInterleaved(output.data(), state.range(0)); + } +} +BENCHMARK(Interleaved_Write)->Range((8<<10) + 3, (8<<20) + 3); + +static void Interleaved_Write_SSE(benchmark::State& state) { + StereoBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + buffer.readInterleaved(input.data(), state.range(0)); + std::vector output (state.range(0) * 2); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.writeInterleaved(output.data(), state.range(0)); + } +} +BENCHMARK(Interleaved_Write_SSE)->Range((8<<10) + 3, (8<<20) + 3); + +static void Unaligned_Interleaved_Write(benchmark::State& state) { + StereoBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + buffer.readInterleaved(input.data(), state.range(0)); + std::vector output (state.range(0) * 2 + 1); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.writeInterleaved(output.data() + 1, state.range(0)); + } +} +BENCHMARK(Unaligned_Interleaved_Write)->Range((8<<10) + 3, (8<<20) + 3); + +static void Unaligned_Interleaved_Write_SSE(benchmark::State& state) { + StereoBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + buffer.readInterleaved(input.data(), state.range(0)); + std::vector output (state.range(0) * 2 + 1); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.writeInterleaved(output.data() + 1, state.range(0)); + } +} +BENCHMARK(Unaligned_Interleaved_Write_SSE)->Range((8<<10) + 3, (8<<20) + 3); +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/sources/Buffer.h b/sources/Buffer.h index cbf80982..dbb1dcbd 100644 --- a/sources/Buffer.h +++ b/sources/Buffer.h @@ -33,6 +33,8 @@ public: normalEnd = normalData + alignedSize; if (auto endMisalignment = (alignedSize & TypeAlignmentMask); endMisalignment != 0) _alignedEnd = normalEnd + Alignment - endMisalignment; + else + _alignedEnd = normalEnd; return true; } diff --git a/sources/FilePool.cpp b/sources/FilePool.cpp index 08bd6562..3db91c98 100644 --- a/sources/FilePool.cpp +++ b/sources/FilePool.cpp @@ -1,4 +1,6 @@ #include "FilePool.h" +#include +using namespace std::chrono_literals; std::optional sfz::FilePool::getFileInformation(std::string_view filename) { @@ -38,9 +40,11 @@ void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int nu void sfz::FilePool::loadingThread() { FileLoadingInformation fileToLoad; - while (true) + while (!quitThread) { - loadingQueue.wait_dequeue(fileToLoad); + if (!loadingQueue.wait_dequeue_timed(fileToLoad, 1ms)) + continue; + if (fileToLoad.voice == nullptr) { DBG("Background thread error: voice is null."); diff --git a/sources/FilePool.h b/sources/FilePool.h index 04c2f373..424d2b4a 100644 --- a/sources/FilePool.h +++ b/sources/FilePool.h @@ -19,7 +19,13 @@ public: FilePool() : fileLoadingThread(std::thread(&FilePool::loadingThread, this)) { + + } + ~FilePool() + { + quitThread = true; + fileLoadingThread.join(); } void setRootDirectory(const std::filesystem::path& directory) { rootDirectory = directory; } size_t getNumPreloadedSamples() { return preloadedData.size(); } @@ -45,6 +51,7 @@ private: moodycamel::BlockingReaderWriterQueue loadingQueue; void loadingThread(); std::thread fileLoadingThread; + bool quitThread { false }; Buffer tempReadBuffer { config::preloadSize * 2 }; // std::map>> preloadedData; absl::flat_hash_map>> preloadedData; diff --git a/sources/InterleavedStereoBuffer.h b/sources/InterleavedStereoBuffer.h new file mode 100644 index 00000000..07c7b98b --- /dev/null +++ b/sources/InterleavedStereoBuffer.h @@ -0,0 +1,48 @@ +#include "Globals.h" +template +class InterleavedStereoBuffer +{ +public: + static constexpr int numChannels { 2 }; + InterleavedStereoBuffer() = default; + InterleavedStereoBuffer(int numFrames) + { + resize(numFrames); + } + + bool resize(int numFrames) + { + // should have a positive number of frames... + ASSERT(numFrames >= 0); + if (buffer.resize(static_cast(2*numFrames))) + { + this->numFrames = numFrames; + return true; + } + return false; + } + + struct Frame + { + Type left; + Type right; + }; + + Frame& getFrame(int frameIndex) + { + return *static_cast(buffer.data() + 2 * frameIndex); + } + + int getNumFrames() const noexcept { return numFrames; } + int getNumChannels() const noexcept { return numChannels; } + bool empty() const noexcept { return numFrames == 0; } +private: + static constexpr auto TypeAlignment { Alignment / sizeof(Type) }; + static constexpr auto TypeAlignmentMask { TypeAlignment - 1 }; + static_assert(TypeAlignment * sizeof(Type) == Alignment, "The alignment does not appear to be divided by the size of the Type"); + int numFrames { 0 }; + int totalSize { 0 }; + int padding { 0 }; + Buffer buffer {}; + Type trash { 0 }; +}; \ No newline at end of file diff --git a/sources/Range.h b/sources/Range.h index 3901a008..297cb318 100644 --- a/sources/Range.h +++ b/sources/Range.h @@ -67,13 +67,13 @@ private: template bool operator==(const Range& lhs, const Range& rhs) { - return (lhs.start() == rhs.start()) && (lhs.end() == rhs.end()); + return (lhs.getStart() == rhs.getStart()) && (lhs.getEnd() == rhs.getEnd()); } template bool operator==(const Range& lhs, const std::pair& rhs) { - return (lhs.start() == rhs.first) && (lhs.end() == rhs.second); + return (lhs.getStart() == rhs.first) && (lhs.getEnd() == rhs.second); } template diff --git a/sources/StereoBuffer.h b/sources/StereoBuffer.h index ed7e94f9..6aeec758 100644 --- a/sources/StereoBuffer.h +++ b/sources/StereoBuffer.h @@ -70,6 +70,20 @@ public: } } + template + void writeInterleaved(Type* output, int numFrames) noexcept + { + ASSERT(numFrames <= this->numFrames); + auto [lIn, rIn] = getChannels(); + auto* out = output; + auto* end = output + numChannels * numFrames; + while (out < end) + { + *out++ = *lIn++; + *out++ = *rIn++; + } + } + Type* getChannel(Channel channel) noexcept { switch(channel) diff --git a/sources/StereoBufferSSE.cpp b/sources/StereoBufferSSE.cpp index d126041f..099d47c2 100644 --- a/sources/StereoBufferSSE.cpp +++ b/sources/StereoBufferSSE.cpp @@ -5,6 +5,7 @@ template <> template <> void StereoBuffer::readInterleaved(float *input, int numFrames) noexcept { + // The number of frames to read has to fit! ASSERT(this->numFrames >= numFrames); const int residualFrames = numFrames & (2 * TypeAlignment - 1); const int lastAligned = numFrames - residualFrames; @@ -47,6 +48,7 @@ void StereoBuffer::fill(float value) noexcept const __m128 mmValue = _mm_set_ps1(value); auto [lBegin, rBegin] = getChannels(); auto [lEnd, rEnd] = alignedEnds(); + // Cast to m128 so that pointer arithmetics make sense auto mmLeft = reinterpret_cast<__m128*>(lBegin); auto mmRight = reinterpret_cast<__m128*>(rBegin); while (mmLeft < reinterpret_cast<__m128*>(lEnd)) // we should only need to test a single channel @@ -56,4 +58,38 @@ void StereoBuffer::fill(float value) noexcept mmLeft++; mmRight++; } +} + +template<> +template<> +void StereoBuffer::writeInterleaved(float* output, int numFrames) noexcept +{ + ASSERT(numFrames <= this->numFrames); + const int residualFrames = numFrames & (TypeAlignment - 1); + const int lastAligned = numFrames - residualFrames; + auto [lIn, rIn] = getChannels(); + auto* out = output; + const auto* sseEnd = lIn + lastAligned; + while (lIn < sseEnd) + { + const auto lInRegister = _mm_load_ps(lIn); + const auto rInRegister = _mm_load_ps(rIn); + + const auto outRegister1 = _mm_unpacklo_ps(lInRegister, rInRegister); + _mm_storeu_ps(out, outRegister1); + out += TypeAlignment; + const auto outRegister2 = _mm_unpackhi_ps(lInRegister, rInRegister); + _mm_storeu_ps(out, outRegister2); + out += TypeAlignment; + + lIn += TypeAlignment; + rIn += TypeAlignment; + } + + const auto* end = output + numChannels * numFrames; + while (out < end) + { + *out++ = *lIn++; + *out++ = *rIn++; + } } \ No newline at end of file diff --git a/tests/BufferT.cpp b/tests/BufferT.cpp index 09df03b2..5a3a22bf 100644 --- a/tests/BufferT.cpp +++ b/tests/BufferT.cpp @@ -32,11 +32,11 @@ TEST_CASE("[Buffer] Empty (uint8_t)") } template -void checkBoundaries(Buffer& buffer, size_t expectedSize) +void checkBoundaries(Buffer& buffer, int expectedSize) { - REQUIRE(buffer.size() == expectedSize); - REQUIRE(((size_t)buffer.data() & (config::defaultAlignment - 1)) == 0); - REQUIRE(((size_t)buffer.alignedEnd() & (config::defaultAlignment - 1)) == 0); + REQUIRE((int)buffer.size() == expectedSize); + REQUIRE(((size_t)buffer.data() & (SIMDConfig::defaultAlignment - 1)) == 0); + REQUIRE(((size_t)buffer.alignedEnd() & (SIMDConfig::defaultAlignment - 1)) == 0); REQUIRE(std::distance(buffer.begin(), buffer.end()) == expectedSize); REQUIRE(std::distance(buffer.begin(), buffer.alignedEnd()) >= expectedSize); } diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index ba96e76a..50ec99db 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -79,18 +79,20 @@ TEST_CASE("[Files] Subdir include Win") REQUIRE( synth.getRegionView(0)->sample == "dummy_subdir.wav" ); } -TEST_CASE("[Files] Recursive include") +TEST_CASE("[Files] Recursive include (with include guard)") { sfz::Synth synth; + synth.enableRecursiveIncludeGuard(); synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/Includes/root_recursive.sfz"); REQUIRE( synth.getNumRegions() == 2 ); REQUIRE( synth.getRegionView(0)->sample == "dummy_recursive2.wav" ); REQUIRE( synth.getRegionView(1)->sample == "dummy_recursive1.wav" ); } -TEST_CASE("[Files] Include loops") +TEST_CASE("[Files] Include loops (with include guard)") { sfz::Synth synth; + synth.enableRecursiveIncludeGuard(); synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/Includes/root_loop.sfz"); REQUIRE( synth.getNumRegions() == 2 ); REQUIRE( synth.getRegionView(0)->sample == "dummy_loop2.wav" ); diff --git a/tests/StereoBufferT.cpp b/tests/StereoBufferT.cpp index 2f803cec..b5c41923 100644 --- a/tests/StereoBufferT.cpp +++ b/tests/StereoBufferT.cpp @@ -200,10 +200,10 @@ TEST_CASE("[AudioBuffer] fills") REQUIRE( real == expected ); } - SECTION("Floats - 0.0 - SSE") + SECTION("Floats - 0.0 - SIMD") { StereoBuffer buffer(10); - buffer.fill(0.0f); + buffer.fill(0.0f); std::array expected; std::fill(expected.begin(), expected.end(), 0.0f); std::array real { 2.0f }; @@ -217,10 +217,10 @@ TEST_CASE("[AudioBuffer] fills") REQUIRE( real == expected ); } - SECTION("Floats - 1.0 - SSE") + SECTION("Floats - 1.0 - SIMD") { StereoBuffer buffer(10); - buffer.fill(1.0f); + buffer.fill(1.0f); std::array expected { 1.0f }; std::fill(expected.begin(), expected.end(), 1.0f); std::array real { 2.0f }; @@ -250,12 +250,12 @@ TEST_CASE("[StereoBuffer] Interleave read") REQUIRE( real == expected ); } -TEST_CASE("[StereoBuffer] Interleave read -- SSE") +TEST_CASE("[StereoBuffer] Interleave read -- SIMD") { StereoBuffer buffer(8); std::array input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f}; std::array expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; - buffer.readInterleaved(input.data(), 8); + buffer.readInterleaved(input.data(), 8); std::array real { 0.0f }; auto realIdx = 0; for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) @@ -265,12 +265,12 @@ TEST_CASE("[StereoBuffer] Interleave read -- SSE") REQUIRE( real == expected ); } -TEST_CASE("[StereoBuffer] Interleave read unaligned end -- SSE") +TEST_CASE("[StereoBuffer] Interleave read unaligned end -- SIMD") { StereoBuffer buffer(10); std::array input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f}; std::array expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f}; - buffer.readInterleaved(input.data(), 10); + buffer.readInterleaved(input.data(), 10); std::array real { 0.0f }; auto realIdx = 0; for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) @@ -280,7 +280,22 @@ TEST_CASE("[StereoBuffer] Interleave read unaligned end -- SSE") REQUIRE( real == expected ); } -TEST_CASE("[StereoBuffer] SSE vs scalar") +TEST_CASE("[StereoBuffer] small interleaved read unaligned end -- SIMD") +{ + StereoBuffer buffer(3); + std::array input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f}; + std::array expected = { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f}; + buffer.readInterleaved(input.data(), 3); + std::array real { 0.0f }; + auto realIdx = 0; + for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) + real[realIdx++] = buffer(Channel::left, frameIdx); + for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) + real[realIdx++] = buffer(Channel::right, frameIdx); + REQUIRE( real == expected ); +} + +TEST_CASE("[StereoBuffer] SIMD vs scalar") { constexpr int numFrames { 91 }; StereoBuffer buffer(numFrames); @@ -288,7 +303,7 @@ TEST_CASE("[StereoBuffer] SSE vs scalar") std::iota(input.begin(), input.end(), 0.0f); StereoBuffer expectedBuffer (numFrames); expectedBuffer.readInterleaved(input.data(), 10); - buffer.readInterleaved(input.data(), 10); + buffer.readInterleaved(input.data(), 10); std::array expectedArray { 0.0f }; std::array realArray { 0.0f }; auto sampleIdx = 0; @@ -312,4 +327,34 @@ TEST_CASE("[AudioBuffer] Fill a big Audiobuffer") std::vector input (2*size); std::iota(input.begin(), input.end(), 1.0f); buffer.readInterleaved(input.data(), size); +} + +TEST_CASE("[StereoBuffer] Interleaved write -- Scalar") +{ + StereoBuffer buffer(10); + std::array input = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f}; + std::array output { 0.0f }; + buffer.readInterleaved(input.data(), 10); + buffer.writeInterleaved(output.data(), 10); + REQUIRE( output == input ); +} + +TEST_CASE("[StereoBuffer] Interleaved write -- SIMD") +{ + StereoBuffer buffer(10); + std::array input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f}; + std::array output { 0.0f }; + buffer.readInterleaved(input.data(), 10); + buffer.writeInterleaved(output.data(), 10); + REQUIRE( output == input ); +} + +TEST_CASE("[StereoBuffer] Small interleaved write -- SIMD") +{ + StereoBuffer buffer(3); + std::array input = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f}; + std::array output { 0.0f }; + buffer.readInterleaved(input.data(), 3); + buffer.writeInterleaved(output.data(), 3); + REQUIRE( output == input ); } \ No newline at end of file diff --git a/tests/TestFiles/36-CajonCenter-1.wav b/tests/TestFiles/36-CajonCenter-1.wav new file mode 100755 index 00000000..d31835e5 Binary files /dev/null and b/tests/TestFiles/36-CajonCenter-1.wav differ diff --git a/tests/TestFiles/36-CajonCenter-2.wav b/tests/TestFiles/36-CajonCenter-2.wav new file mode 100755 index 00000000..703d521d Binary files /dev/null and b/tests/TestFiles/36-CajonCenter-2.wav differ diff --git a/tests/TestFiles/36-CajonCenter-3.wav b/tests/TestFiles/36-CajonCenter-3.wav new file mode 100755 index 00000000..2ced2683 Binary files /dev/null and b/tests/TestFiles/36-CajonCenter-3.wav differ diff --git a/tests/TestFiles/36-CajonCenter-4.wav b/tests/TestFiles/36-CajonCenter-4.wav new file mode 100755 index 00000000..cebfc34e Binary files /dev/null and b/tests/TestFiles/36-CajonCenter-4.wav differ diff --git a/tests/TestFiles/36-CajonCenter-5.wav b/tests/TestFiles/36-CajonCenter-5.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/36-CajonCenter-5.wav differ diff --git a/tests/TestFiles/Includes/dummy.wav b/tests/TestFiles/Includes/dummy.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy.wav differ diff --git a/tests/TestFiles/Includes/dummy2.wav b/tests/TestFiles/Includes/dummy2.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy2.wav differ diff --git a/tests/TestFiles/Includes/dummy_loop1.wav b/tests/TestFiles/Includes/dummy_loop1.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy_loop1.wav differ diff --git a/tests/TestFiles/Includes/dummy_loop2.wav b/tests/TestFiles/Includes/dummy_loop2.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy_loop2.wav differ diff --git a/tests/TestFiles/Includes/dummy_recursive1.wav b/tests/TestFiles/Includes/dummy_recursive1.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy_recursive1.wav differ diff --git a/tests/TestFiles/Includes/dummy_recursive2.wav b/tests/TestFiles/Includes/dummy_recursive2.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy_recursive2.wav differ diff --git a/tests/TestFiles/Includes/dummy_subdir.wav b/tests/TestFiles/Includes/dummy_subdir.wav new file mode 100755 index 00000000..401fe3fe Binary files /dev/null and b/tests/TestFiles/Includes/dummy_subdir.wav differ diff --git a/tests/TestFiles/Regions/dummy.1.wav b/tests/TestFiles/Regions/dummy.1.wav old mode 100644 new mode 100755 index e69de29b..401fe3fe Binary files a/tests/TestFiles/Regions/dummy.1.wav and b/tests/TestFiles/Regions/dummy.1.wav differ diff --git a/tests/TestFiles/Regions/dummy.2.wav b/tests/TestFiles/Regions/dummy.2.wav old mode 100644 new mode 100755 index e69de29b..401fe3fe Binary files a/tests/TestFiles/Regions/dummy.2.wav and b/tests/TestFiles/Regions/dummy.2.wav differ diff --git a/tests/TestFiles/Regions/dummy.wav b/tests/TestFiles/Regions/dummy.wav old mode 100644 new mode 100755 index e69de29b..401fe3fe Binary files a/tests/TestFiles/Regions/dummy.wav and b/tests/TestFiles/Regions/dummy.wav differ diff --git a/tests/TestFiles/closedhat.wav b/tests/TestFiles/closedhat.wav new file mode 100755 index 00000000..d31835e5 Binary files /dev/null and b/tests/TestFiles/closedhat.wav differ diff --git a/tests/TestFiles/kick.wav b/tests/TestFiles/kick.wav new file mode 100755 index 00000000..d31835e5 Binary files /dev/null and b/tests/TestFiles/kick.wav differ diff --git a/tests/TestFiles/snare.wav b/tests/TestFiles/snare.wav new file mode 100755 index 00000000..d31835e5 Binary files /dev/null and b/tests/TestFiles/snare.wav differ