diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dbcfaf0..94a039d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,15 @@ project(sfizz VERSION 1.0.0 LANGUAGES CXX) # Set the highest possible standard set(CMAKE_CXX_STANDARD 14) +# Enable LTO +set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) # To override the policy in abseil and benchmark +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT ANDROID) add_compile_options(-stdlib=libc++) # Presumably need the above for linking too, maybe other options missing as well add_link_options(-stdlib=libc++) # New command on CMake master, not in 3.12 release -else() +else() add_link_options(-lstdc++fs) endif() diff --git a/sfizz/CMakeLists.txt b/sfizz/CMakeLists.txt index b040cc2a..aa12a72f 100644 --- a/sfizz/CMakeLists.txt +++ b/sfizz/CMakeLists.txt @@ -37,19 +37,22 @@ endif() set(SFIZZ_SOURCES ${SFIZZ_SOURCES} ${SFIZZ_SIMD_SOURCES}) add_library(sfizz_parser STATIC) -target_sources(sfizz_parser PUBLIC Parser.cpp Opcode.cpp) +target_sources(sfizz_parser PRIVATE Parser.cpp Opcode.cpp) target_include_directories(sfizz_parser PUBLIC .) if(UNIX) target_link_libraries(sfizz_parser PUBLIC stdc++fs) + # target_compile_options(sfizz_parser PUBLIC -fno-rtti -fno-exceptions) endif(UNIX) target_link_libraries(sfizz_parser PRIVATE absl::strings) add_library(sfizz STATIC ${SFIZZ_SOURCES}) target_link_libraries(sfizz PRIVATE sfizz_parser) target_include_directories(sfizz PUBLIC .) +find_package(Threads REQUIRED) +target_link_libraries(sfizz PRIVATE Threads::Threads) if(UNIX) target_link_libraries(sfizz PUBLIC stdc++fs atomic) - target_compile_options(sfizz PRIVATE -fno-rtti -fno-exceptions) + # target_compile_options(sfizz PUBLIC -fno-rtti -fno-exceptions) endif(UNIX) target_link_libraries(sfizz PUBLIC absl::strings) target_link_libraries(sfizz PRIVATE sndfile absl::flat_hash_map) diff --git a/sfizz/FilePool.cpp b/sfizz/FilePool.cpp index 9eaa35a2..0e1c31a2 100644 --- a/sfizz/FilePool.cpp +++ b/sfizz/FilePool.cpp @@ -45,7 +45,7 @@ std::unique_ptr> readFromFile(SndfileHandle& sndFile, int numFram sndFile.readf(tempReadBuffer->channelWriter(0), numFrames); ::readInterleaved(tempReadBuffer->getSpan(0), returnedBuffer->getSpan(0), returnedBuffer->getSpan(1)); } - return std::move(returnedBuffer); + return returnedBuffer; } absl::optional sfz::FilePool::getFileInformation(const std::string& filename, uint32_t offset) noexcept diff --git a/sfizz/FilePool.h b/sfizz/FilePool.h index dad2e0f7..fb30c353 100644 --- a/sfizz/FilePool.h +++ b/sfizz/FilePool.h @@ -38,11 +38,7 @@ namespace sfz { class FilePool { public: - FilePool() - : fileLoadingThread(std::thread(&FilePool::loadingThread, this)) - , garbageCollectionThread(std::thread(&FilePool::garbageThread, this)) - { - } + FilePool() { } ~FilePool() { @@ -75,11 +71,11 @@ private: moodycamel::BlockingReaderWriterQueue loadingQueue { config::numVoices }; void loadingThread() noexcept; void garbageThread() noexcept; - std::thread fileLoadingThread; - std::thread garbageCollectionThread; + bool quitThread { false }; + std::thread fileLoadingThread { &FilePool::loadingThread, this }; + std::thread garbageCollectionThread { &FilePool::garbageThread, this }; std::vector>> fileHandles; std::mutex fileHandleMutex; - bool quitThread { false }; absl::flat_hash_map>> preloadedData; LEAK_DETECTOR(FilePool); }; diff --git a/sfizz/Synth.cpp b/sfizz/Synth.cpp index 4f9875bc..a8f5a1ec 100644 --- a/sfizz/Synth.cpp +++ b/sfizz/Synth.cpp @@ -356,12 +356,14 @@ void sfz::Synth::noteOn(int delay, int channel, int noteNumber, uint8_t velocity } } -void sfz::Synth::noteOff(int delay, int channel, int noteNumber, uint8_t velocity) noexcept { ASSERT(noteNumber < 128); ASSERT(noteNumber >= 0); - auto replacedVelocity = velocity == 0 ? midiState.getNoteVelocity(noteNumber) : velocity; + // FIXME: Some keyboards (e.g. Casio PX5S) can send a real note-off velocity. In this case, do we have a + // way in sfz to specify that a release trigger should NOT use the note-on velocity? + // auto replacedVelocity = (velocity == 0 ? sfz::getNoteVelocity(noteNumber) : velocity); + auto replacedVelocity = midiState.getNoteVelocity(noteNumber); auto randValue = randNoteDistribution(Random::randomGenerator); for (auto& voice : voices) voice->registerNoteOff(delay, channel, noteNumber, replacedVelocity); diff --git a/sfizz/Voice.cpp b/sfizz/Voice.cpp index 8beee826..444e46b0 100644 --- a/sfizz/Voice.cpp +++ b/sfizz/Voice.cpp @@ -365,8 +365,8 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept ::add(sourcePosition, indices); //FIXME : all this casting is driving me crazy - const auto sampleEnd = static_cast(region->trueSampleEnd()) - 1; - if (region->shouldLoop() && static_cast(sampleEnd) <= source.getNumFrames()) { + const auto sampleEnd = min(static_cast(region->trueSampleEnd()), static_cast(source.getNumFrames())) - 1; + if (region->shouldLoop() && region->loopRange.getEnd() <= source.getNumFrames()) { const auto offset = sampleEnd - static_cast(region->loopRange.getStart()); for (auto* index = indices.begin(); index < indices.end(); ++index) { if (*index > sampleEnd) { diff --git a/tests/SIMDHelpersT.cpp b/tests/SIMDHelpersT.cpp index 4fd8075f..138df243 100644 --- a/tests/SIMDHelpersT.cpp +++ b/tests/SIMDHelpersT.cpp @@ -528,7 +528,7 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD)") std::array output; std::array expected { v, v + v, v + v + v, v + v + v + v, v + v + v + v + v, v + v + v + v + v + v }; linearRamp(absl::MakeSpan(output), start, v); - REQUIRE(output == expected); + REQUIRE(approxEqual(output, expected)); } TEST_CASE("[Helpers] Linear Ramp (SIMD vs scalar)")