diff --git a/src/sfizz/FileId.cpp b/src/sfizz/FileId.cpp index 8355ab70..13dca994 100644 --- a/src/sfizz/FileId.cpp +++ b/src/sfizz/FileId.cpp @@ -10,15 +10,17 @@ size_t std::hash::operator()(const sfz::FileId &id) const { - uint64_t h = ::hash(id.filename); - h = ::hash(id.reverse ? "!" : "", h); + uint64_t h = ::hash(id.filename()); + h = ::hash(id.isReverse() ? "!" : "", h); return h; } std::ostream &operator<<(std::ostream &os, const sfz::FileId &fileId) { - os << fileId.filename; - if (fileId.reverse) + os << fileId.filename(); + if (fileId.isReverse()) os << " (reverse)"; return os; } + +const std::string sfz::FileId::emptyFilename; diff --git a/src/sfizz/FileId.h b/src/sfizz/FileId.h index 7193bdd0..df97f1fd 100644 --- a/src/sfizz/FileId.h +++ b/src/sfizz/FileId.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include namespace sfz { @@ -14,9 +15,6 @@ namespace sfz { * @brief Sample file identifier within a file pool. */ struct FileId { - std::string filename; - bool reverse = false; - /** * @brief Construct a null identifier. */ @@ -30,11 +28,46 @@ struct FileId { * @param filename * @param reverse */ - FileId(std::string filename, bool reverse = false) - : filename(std::move(filename)), reverse(reverse) + explicit FileId(std::string filename, bool reverse = false) + : filenameBuffer(new std::string(std::move(filename))), + reverse(reverse) { } + /** + * @brief Make an identifier which is a clone of the callee, except with the + * reverse flag passed as parameter. + * + * @param reverse + */ + FileId reversed(bool reverse = true) + { + FileId id; + id.filenameBuffer = filenameBuffer; + id.reverse = reverse; + return id; + } + + /** + * @brief Get the file name of this identifier. + * + * @return file name + */ + const std::string &filename() const noexcept + { + return filenameBuffer ? *filenameBuffer : emptyFilename; + } + + /** + * @brief Get whether the identified file is reversed. + * + * @return bool + */ + bool isReverse() const noexcept + { + return reverse; + } + /** * @brief Check equality with another identifier. * @@ -42,7 +75,7 @@ struct FileId { */ bool operator==(const FileId &other) const { - return reverse == other.reverse && filename == other.filename; + return reverse == other.reverse && filename() == other.filename(); } /** @@ -54,6 +87,11 @@ struct FileId { { return !operator==(other); } + +private: + std::shared_ptr filenameBuffer; + bool reverse = false; + static const std::string emptyFilename; }; } diff --git a/src/sfizz/FilePool.cpp b/src/sfizz/FilePool.cpp index f9f38ae7..b8e9ade4 100644 --- a/src/sfizz/FilePool.cpp +++ b/src/sfizz/FilePool.cpp @@ -190,9 +190,18 @@ bool sfz::FilePool::checkSample(std::string& filename) const noexcept #endif } +bool sfz::FilePool::checkSampleId(FileId& fileId) const noexcept +{ + std::string filename = fileId.filename(); + bool result = checkSample(filename); + if (result) + fileId = FileId(std::move(filename), fileId.isReverse()); + return result; +} + absl::optional sfz::FilePool::getFileInformation(const FileId& fileId) noexcept { - const fs::path file { rootDirectory / fileId.filename }; + const fs::path file { rootDirectory / fileId.filename() }; if (!fs::exists(file)) return {}; @@ -208,7 +217,7 @@ absl::optional sfz::FilePool::getFileInformation(const Fil returnedValue.sampleRate = static_cast(sndFile.samplerate()); returnedValue.numChannels = sndFile.channels(); - if (!fileId.reverse) { + if (!fileId.isReverse()) { SF_INSTRUMENT instrumentInfo; sndFile.command(SFC_GET_INSTRUMENT, &instrumentInfo, sizeof(instrumentInfo)); if (instrumentInfo.loop_count > 0) { @@ -229,7 +238,7 @@ bool sfz::FilePool::preloadFile(const FileId& fileId, uint32_t maxOffset) noexce if (!fileInformation) return false; - const fs::path file { rootDirectory / fileId.filename }; + const fs::path file { rootDirectory / fileId.filename() }; SndfileHandle sndFile(file.string().c_str()); // FIXME: Large offsets will require large preloading; is this OK in practice? Apparently sforzando does the same @@ -244,12 +253,12 @@ bool sfz::FilePool::preloadFile(const FileId& fileId, uint32_t maxOffset) noexce const auto existingFile = preloadedFiles.find(fileId); if (existingFile != preloadedFiles.end()) { if (framesToLoad > existingFile->second.preloadedData->getNumFrames()) { - preloadedFiles[fileId].preloadedData = readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.reverse); + preloadedFiles[fileId].preloadedData = readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.isReverse()); } } else { fileInformation->sampleRate = static_cast(oversamplingFactor) * static_cast(sndFile.samplerate()); FileDataHandle handle { - readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.reverse), + readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.isReverse()), *fileInformation }; preloadedFiles.insert_or_assign(fileId, handle); @@ -263,7 +272,7 @@ absl::optional sfz::FilePool::loadFile(const FileId& fileId if (!fileInformation) return {}; - const fs::path file { rootDirectory / fileId.filename }; + const fs::path file { rootDirectory / fileId.filename() }; SndfileHandle sndFile(file.string().c_str()); // FIXME: Large offsets will require large preloading; is this OK in practice? Apparently sforzando does the same @@ -274,7 +283,7 @@ absl::optional sfz::FilePool::loadFile(const FileId& fileId } else { fileInformation->sampleRate = static_cast(oversamplingFactor) * static_cast(sndFile.samplerate()); FileDataHandle handle { - readFromFile(sndFile, frames, oversamplingFactor, fileId.reverse), + readFromFile(sndFile, frames, oversamplingFactor, fileId.isReverse()), *fileInformation }; loadedFiles.insert_or_assign(fileId, handle); @@ -322,9 +331,9 @@ void sfz::FilePool::setPreloadSize(uint32_t preloadSize) noexcept for (auto& preloadedFile : preloadedFiles) { const auto numFrames = preloadedFile.second.preloadedData->getNumFrames() / static_cast(oversamplingFactor); const auto maxOffset = numFrames > this->preloadSize ? static_cast(numFrames) - this->preloadSize : 0; - fs::path file { rootDirectory / preloadedFile.first.filename }; + fs::path file { rootDirectory / preloadedFile.first.filename() }; SndfileHandle sndFile(file.string().c_str()); - preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, oversamplingFactor, preloadedFile.first.reverse); + preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, oversamplingFactor, preloadedFile.first.isReverse()); } this->preloadSize = preloadSize; } @@ -372,7 +381,7 @@ void sfz::FilePool::loadingThread() noexcept const auto loadStartTime = std::chrono::high_resolution_clock::now(); const auto waitDuration = loadStartTime - promise->creationTime; - const fs::path file { rootDirectory / promise->fileId.filename }; + const fs::path file { rootDirectory / promise->fileId.filename() }; SndfileHandle sndFile(file.string().c_str()); if (sndFile.error() != 0) { DBG("[sfizz] libsndfile errored for " << promise->fileId << " with message " << sndFile.strError()); @@ -380,10 +389,10 @@ void sfz::FilePool::loadingThread() noexcept continue; } const auto frames = static_cast(sndFile.frames()); - streamFromFile(sndFile, frames, oversamplingFactor, promise->fileId.reverse, promise->fileData, &promise->availableFrames); + streamFromFile(sndFile, frames, oversamplingFactor, promise->fileId.isReverse(), promise->fileData, &promise->availableFrames); promise->dataStatus = FilePromise::DataStatus::Ready; const auto loadDuration = std::chrono::high_resolution_clock::now() - loadStartTime; - logger.logFileTime(waitDuration, loadDuration, frames, promise->fileId.filename); + logger.logFileTime(waitDuration, loadDuration, frames, promise->fileId.filename()); threadsLoading--; @@ -451,9 +460,9 @@ void sfz::FilePool::setOversamplingFactor(sfz::Oversampling factor) noexcept for (auto& preloadedFile : preloadedFiles) { const auto numFrames = preloadedFile.second.preloadedData->getNumFrames() / static_cast(this->oversamplingFactor); const uint32_t maxOffset = numFrames > this->preloadSize ? static_cast(numFrames) - this->preloadSize : 0; - fs::path file { rootDirectory / preloadedFile.first.filename }; + fs::path file { rootDirectory / preloadedFile.first.filename() }; SndfileHandle sndFile(file.string().c_str()); - preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, factor, preloadedFile.first.reverse); + preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, factor, preloadedFile.first.isReverse()); preloadedFile.second.information.sampleRate *= samplerateChange; } diff --git a/src/sfizz/FilePool.h b/src/sfizz/FilePool.h index 631dd6f6..7f5e15d9 100644 --- a/src/sfizz/FilePool.h +++ b/src/sfizz/FilePool.h @@ -189,6 +189,15 @@ public: */ bool checkSample(std::string& filename) const noexcept; + /** + * @brief Check that the sample exists. If not, try to find it in a case insensitive way. + * + * @param fileId the sample file identifier; may be updated by the method + * @return true if the sample exists or was updated properly + * @return false if no sample was found even with a case insensitive search + */ + bool checkSampleId(FileId& fileId) const noexcept; + /** * @brief Clear all preloaded files. * diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 0c6d954c..117a6d26 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -41,14 +41,17 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) if (trimmedSample.empty()) break; + std::string filename; if (trimmedSample[0] == '*') - sampleId.filename = std::string(trimmedSample); + filename = std::string(trimmedSample); else - sampleId.filename = absl::StrCat(defaultPath, absl::StrReplaceAll(trimmedSample, { { "\\", "/" } })); + filename = absl::StrCat(defaultPath, absl::StrReplaceAll(trimmedSample, { { "\\", "/" } })); + + sampleId = FileId(std::move(filename), sampleId.isReverse()); } break; case hash("direction"): - sampleId.reverse = opcode.value == "reverse"; + sampleId = sampleId.reversed(opcode.value == "reverse"); break; case hash("delay"): setValueFromOpcode(opcode, delay, Default::delayRange); diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 0ab2dd82..17180bca 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -58,7 +58,7 @@ struct Region { * @return true * @return false */ - bool isGenerator() const noexcept { return sampleId.filename.size() > 0 ? sampleId.filename[0] == '*' : false; } + bool isGenerator() const noexcept { return sampleId.filename().size() > 0 ? sampleId.filename()[0] == '*' : false; } /** * @brief Is stereo (has stereo sample or is unison oscillator)? * diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 2783718c..d16fc87e 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -350,7 +350,7 @@ bool sfz::Synth::loadSfzFile(const fs::path& file) auto region = currentRegion->get(); if (!region->oscillator && !region->isGenerator()) { - if (!resources.filePool.checkSample(region->sampleId.filename)) { + if (!resources.filePool.checkSampleId(region->sampleId)) { removeCurrentRegion(); continue; } @@ -391,12 +391,12 @@ bool sfz::Synth::loadSfzFile(const fs::path& file) removeCurrentRegion(); } else if (region->oscillator && !region->isGenerator()) { - if (!resources.filePool.checkSample(region->sampleId.filename)) { + if (!resources.filePool.checkSampleId(region->sampleId)) { removeCurrentRegion(); continue; } - if (!resources.wavePool.createFileWave(resources.filePool, region->sampleId.filename)) { + if (!resources.wavePool.createFileWave(resources.filePool, std::string(region->sampleId.filename()))) { removeCurrentRegion(); continue; } diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 68650ef0..7eea837a 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -40,7 +40,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value, if (region->isGenerator()) { const WavetableMulti* wave = nullptr; - switch (hash(region->sampleId.filename)) { + switch (hash(region->sampleId.filename())) { default: case hash("*silence"): break; @@ -64,7 +64,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value, } setupOscillatorUnison(); } else if (region->oscillator) { - const WavetableMulti* wave = resources.wavePool.getFileWave(region->sampleId.filename); + const WavetableMulti* wave = resources.wavePool.getFileWave(region->sampleId.filename()); for (WavetableOscillator& osc : waveOscillators) { osc.setWavetable(wave); osc.setPhase(region->getPhase()); @@ -529,7 +529,7 @@ void sfz::Voice::fillWithGenerator(AudioSpan buffer) noexcept const auto leftSpan = buffer.getSpan(0); const auto rightSpan = buffer.getSpan(1); - if (region->sampleId.filename == "*noise") { + if (region->sampleId.filename() == "*noise") { absl::c_generate(leftSpan, [&](){ return noiseDist(Random::randomGenerator); }); absl::c_generate(rightSpan, [&](){ return noiseDist(Random::randomGenerator); }); } else { diff --git a/src/sfizz/Wavetables.cpp b/src/sfizz/Wavetables.cpp index 617d3901..c1a4448b 100644 --- a/src/sfizz/Wavetables.cpp +++ b/src/sfizz/Wavetables.cpp @@ -365,7 +365,7 @@ bool WavetablePool::createFileWave(FilePool& filePool, const std::string& filena if (_fileWaves.contains(filename)) return true; - auto fileHandle = filePool.loadFile(filename); + auto fileHandle = filePool.loadFile(FileId(filename)); if (!fileHandle) return false; diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index e6c2394e..2f22dea5 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -19,7 +19,7 @@ TEST_CASE("[Files] Single region (regions_one.sfz)") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_one.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav"); } @@ -28,9 +28,9 @@ TEST_CASE("[Files] Multiple regions (regions_many.sfz)") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_many.sfz"); REQUIRE(synth.getNumRegions() == 3); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "dummy.1.wav"); - REQUIRE(synth.getRegionView(2)->sampleId.filename == "dummy.2.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy.1.wav"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == "dummy.2.wav"); } TEST_CASE("[Files] Basic opcodes (regions_opcodes.sfz)") @@ -54,8 +54,8 @@ TEST_CASE("[Files] (regions_bad.sfz)") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_bad.sfz"); REQUIRE(synth.getNumRegions() == 2); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "dummy.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy.wav"); } TEST_CASE("[Files] Local include") @@ -63,7 +63,7 @@ TEST_CASE("[Files] Local include") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_local.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav"); } TEST_CASE("[Files] Multiple includes") @@ -71,8 +71,8 @@ TEST_CASE("[Files] Multiple includes") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/multiple_includes.sfz"); REQUIRE(synth.getNumRegions() == 2); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "dummy2.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy2.wav"); } TEST_CASE("[Files] Multiple includes with comments") @@ -80,8 +80,8 @@ TEST_CASE("[Files] Multiple includes with comments") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/multiple_includes_with_comments.sfz"); REQUIRE(synth.getNumRegions() == 2); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "dummy2.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy2.wav"); } TEST_CASE("[Files] Subdir include") @@ -89,7 +89,7 @@ TEST_CASE("[Files] Subdir include") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_subdir.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy_subdir.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_subdir.wav"); } TEST_CASE("[Files] Subdir include Win") @@ -97,7 +97,7 @@ TEST_CASE("[Files] Subdir include Win") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_subdir_win.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy_subdir.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_subdir.wav"); } TEST_CASE("[Files] Recursive include (with include guard)") @@ -107,8 +107,8 @@ TEST_CASE("[Files] Recursive include (with include guard)") parser.setRecursiveIncludeGuardEnabled(true); synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_recursive.sfz"); REQUIRE(synth.getNumRegions() == 2); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy_recursive2.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "dummy_recursive1.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_recursive2.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy_recursive1.wav"); } TEST_CASE("[Files] Include loops (with include guard)") @@ -118,8 +118,8 @@ TEST_CASE("[Files] Include loops (with include guard)") parser.setRecursiveIncludeGuardEnabled(true); synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_loop.sfz"); REQUIRE(synth.getNumRegions() == 2); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy_loop2.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "dummy_loop1.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_loop2.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy_loop1.wav"); } TEST_CASE("[Files] Define test") @@ -205,28 +205,28 @@ TEST_CASE("[Files] Full hierarchy with antislashes") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/basic_hierarchy.sfz"); REQUIRE(synth.getNumRegions() == 8); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "Regions/dummy.1.wav"); - REQUIRE(synth.getRegionView(2)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(3)->sampleId.filename == "Regions/dummy.1.wav"); - REQUIRE(synth.getRegionView(4)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(5)->sampleId.filename == "Regions/dummy.1.wav"); - REQUIRE(synth.getRegionView(6)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(7)->sampleId.filename == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(3)->sampleId.filename() == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(4)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(5)->sampleId.filename() == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(6)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(7)->sampleId.filename() == "Regions/dummy.1.wav"); } { sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/basic_hierarchy_antislash.sfz"); REQUIRE(synth.getNumRegions() == 8); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "Regions/dummy.1.wav"); - REQUIRE(synth.getRegionView(2)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(3)->sampleId.filename == "Regions/dummy.1.wav"); - REQUIRE(synth.getRegionView(4)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(5)->sampleId.filename == "Regions/dummy.1.wav"); - REQUIRE(synth.getRegionView(6)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(7)->sampleId.filename == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(3)->sampleId.filename() == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(4)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(5)->sampleId.filename() == "Regions/dummy.1.wav"); + REQUIRE(synth.getRegionView(6)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(7)->sampleId.filename() == "Regions/dummy.1.wav"); } } @@ -245,10 +245,10 @@ TEST_CASE("[Files] Pizz basic") REQUIRE(synth.getRegionView(1)->randRange == sfz::Range(0.25, 0.5)); REQUIRE(synth.getRegionView(2)->randRange == sfz::Range(0.5, 0.75)); REQUIRE(synth.getRegionView(3)->randRange == sfz::Range(0.75, 1.0)); - REQUIRE(synth.getRegionView(0)->sampleId.filename == R"(../Samples/pizz/a0_vl4_rr1.wav)"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == R"(../Samples/pizz/a0_vl4_rr2.wav)"); - REQUIRE(synth.getRegionView(2)->sampleId.filename == R"(../Samples/pizz/a0_vl4_rr3.wav)"); - REQUIRE(synth.getRegionView(3)->sampleId.filename == R"(../Samples/pizz/a0_vl4_rr4.wav)"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr1.wav)"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr2.wav)"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr3.wav)"); + REQUIRE(synth.getRegionView(3)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr4.wav)"); } TEST_CASE("[Files] Channels (channels.sfz)") @@ -256,9 +256,9 @@ TEST_CASE("[Files] Channels (channels.sfz)") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/channels.sfz"); REQUIRE(synth.getNumRegions() == 2); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "mono_sample.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "mono_sample.wav"); REQUIRE(!synth.getRegionView(0)->isStereo()); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "stereo_sample.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "stereo_sample.wav"); REQUIRE(synth.getRegionView(1)->isStereo()); } @@ -268,32 +268,32 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)") synth.loadSfzFile(fs::current_path() / "tests/TestFiles/channels_multi.sfz"); REQUIRE(synth.getNumRegions() == 6); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "*sine"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "*sine"); REQUIRE(!synth.getRegionView(0)->isStereo()); REQUIRE(synth.getRegionView(0)->isGenerator()); REQUIRE(!synth.getRegionView(0)->oscillator); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "*sine"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "*sine"); REQUIRE(synth.getRegionView(1)->isStereo()); REQUIRE(synth.getRegionView(1)->isGenerator()); REQUIRE(!synth.getRegionView(1)->oscillator); - REQUIRE(synth.getRegionView(2)->sampleId.filename == "ramp_wave.wav"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == "ramp_wave.wav"); REQUIRE(!synth.getRegionView(2)->isStereo()); REQUIRE(!synth.getRegionView(2)->isGenerator()); REQUIRE(synth.getRegionView(2)->oscillator); - REQUIRE(synth.getRegionView(3)->sampleId.filename == "ramp_wave.wav"); + REQUIRE(synth.getRegionView(3)->sampleId.filename() == "ramp_wave.wav"); REQUIRE(synth.getRegionView(3)->isStereo()); REQUIRE(!synth.getRegionView(3)->isGenerator()); REQUIRE(synth.getRegionView(3)->oscillator); - REQUIRE(synth.getRegionView(4)->sampleId.filename == "*sine"); + REQUIRE(synth.getRegionView(4)->sampleId.filename() == "*sine"); REQUIRE(!synth.getRegionView(4)->isStereo()); REQUIRE(synth.getRegionView(4)->isGenerator()); REQUIRE(!synth.getRegionView(4)->oscillator); - REQUIRE(synth.getRegionView(5)->sampleId.filename == "*sine"); + REQUIRE(synth.getRegionView(5)->sampleId.filename() == "*sine"); REQUIRE(!synth.getRegionView(5)->isStereo()); REQUIRE(synth.getRegionView(5)->isGenerator()); REQUIRE(!synth.getRegionView(5)->oscillator); @@ -359,7 +359,7 @@ TEST_CASE("[Files] Specific bug: relative path with backslashes") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/SpecificBugs/win_backslashes.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == R"(Xylo/Subfolder/closedhat.wav)"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(Xylo/Subfolder/closedhat.wav)"); } TEST_CASE("[Files] Default path") @@ -367,10 +367,10 @@ TEST_CASE("[Files] Default path") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path.sfz"); REQUIRE(synth.getNumRegions() == 4); - REQUIRE(synth.getRegionView(0)->sampleId.filename == R"(DefaultPath/SubPath1/sample1.wav)"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == R"(DefaultPath/SubPath2/sample2.wav)"); - REQUIRE(synth.getRegionView(2)->sampleId.filename == R"(DefaultPath/SubPath1/sample1.wav)"); - REQUIRE(synth.getRegionView(3)->sampleId.filename == R"(DefaultPath/SubPath2/sample2.wav)"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(DefaultPath/SubPath1/sample1.wav)"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == R"(DefaultPath/SubPath2/sample2.wav)"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == R"(DefaultPath/SubPath1/sample1.wav)"); + REQUIRE(synth.getRegionView(3)->sampleId.filename() == R"(DefaultPath/SubPath2/sample2.wav)"); } TEST_CASE("[Files] Default path reset when calling loadSfzFile again") @@ -380,7 +380,7 @@ TEST_CASE("[Files] Default path reset when calling loadSfzFile again") REQUIRE(synth.getNumRegions() == 4); synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path_reset.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == R"(DefaultPath/SubPath2/sample2.wav)"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(DefaultPath/SubPath2/sample2.wav)"); } TEST_CASE("[Files] Default path is ignored for generators") @@ -388,7 +388,7 @@ TEST_CASE("[Files] Default path is ignored for generators") sfz::Synth synth; synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path_generator.sfz"); REQUIRE(synth.getNumRegions() == 1); - REQUIRE(synth.getRegionView(0)->sampleId.filename == R"(*sine)"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(*sine)"); } TEST_CASE("[Files] Set CC applies properly") @@ -547,10 +547,10 @@ TEST_CASE("[Files] Case sentitiveness") sfz::Synth synth; synth.loadSfzFile(sfzFilePath); REQUIRE(synth.getNumRegions() == 4); - REQUIRE(synth.getRegionView(0)->sampleId.filename == "dummy1.wav"); - REQUIRE(synth.getRegionView(1)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(2)->sampleId.filename == "Regions/dummy.wav"); - REQUIRE(synth.getRegionView(3)->sampleId.filename == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy1.wav"); + REQUIRE(synth.getRegionView(1)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(2)->sampleId.filename() == "Regions/dummy.wav"); + REQUIRE(synth.getRegionView(3)->sampleId.filename() == "Regions/dummy.wav"); } } diff --git a/tests/RegionT.cpp b/tests/RegionT.cpp index 14176337..fa73bd51 100644 --- a/tests/RegionT.cpp +++ b/tests/RegionT.cpp @@ -18,18 +18,18 @@ TEST_CASE("[Region] Parsing opcodes") SECTION("sample") { - REQUIRE(region.sampleId.filename == ""); + REQUIRE(region.sampleId.filename() == ""); region.parseOpcode({ "sample", "dummy.wav" }); - REQUIRE(region.sampleId.filename == "dummy.wav"); + REQUIRE(region.sampleId.filename() == "dummy.wav"); } SECTION("direction") { - REQUIRE(!region.sampleId.reverse); + REQUIRE(!region.sampleId.isReverse()); region.parseOpcode({ "direction", "reverse" }); - REQUIRE(region.sampleId.reverse); + REQUIRE(region.sampleId.isReverse()); region.parseOpcode({ "direction", "forward" }); - REQUIRE(!region.sampleId.reverse); + REQUIRE(!region.sampleId.isReverse()); } SECTION("delay")