From 3b3f6d2731027a9bb8fe24bd5488c146083f57b4 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 13 Aug 2020 20:57:51 +0200 Subject: [PATCH 1/6] Set the pitch key center from sample --- src/sfizz/FilePool.cpp | 10 +++++++--- src/sfizz/FilePool.h | 1 + src/sfizz/Region.cpp | 7 ++++++- src/sfizz/Region.h | 1 + src/sfizz/Synth.cpp | 3 +++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/sfizz/FilePool.cpp b/src/sfizz/FilePool.cpp index 8b4ca8a3..9750da2c 100644 --- a/src/sfizz/FilePool.cpp +++ b/src/sfizz/FilePool.cpp @@ -216,14 +216,15 @@ absl::optional sfz::FilePool::getFileInformation(const Fil returnedValue.numChannels = reader->channels(); SF_INSTRUMENT instrumentInfo {}; + bool haveInstrumentInfo = reader->getInstrument(&instrumentInfo); FileMetadataReader mdReader; bool mdReaderOpened = mdReader.open(file); - if (!reader->getInstrument(&instrumentInfo)) { + if (!haveInstrumentInfo) { // if no instrument, then try extracting from embedded RIFF chunks (flac) if (mdReaderOpened) - mdReader.extractRiffInstrument(instrumentInfo); + haveInstrumentInfo = mdReader.extractRiffInstrument(instrumentInfo); } if (mdReaderOpened) { @@ -233,7 +234,7 @@ absl::optional sfz::FilePool::getFileInformation(const Fil } if (!fileId.isReverse()) { - if (instrumentInfo.loop_count > 0) { + if (haveInstrumentInfo && instrumentInfo.loop_count > 0) { returnedValue.hasLoop = true; returnedValue.loopBegin = instrumentInfo.loops[0].start; returnedValue.loopEnd = min(returnedValue.end, instrumentInfo.loops[0].end - 1); @@ -243,6 +244,9 @@ absl::optional sfz::FilePool::getFileInformation(const Fil // prehaps it can make use of SF_LOOP_BACKWARD? } + if (haveInstrumentInfo) + returnedValue.rootKey = clamp(instrumentInfo.basenote, 0, 127); + return returnedValue; } diff --git a/src/sfizz/FilePool.h b/src/sfizz/FilePool.h index dcef362c..f05712fd 100644 --- a/src/sfizz/FilePool.h +++ b/src/sfizz/FilePool.h @@ -56,6 +56,7 @@ struct FileInformation { bool hasLoop { false }; double sampleRate { config::defaultSampleRate }; int numChannels { 0 }; + int rootKey { 0 }; absl::optional wavetable; }; diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 7ec6619d..83417fb5 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -779,7 +779,12 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) // Performance parameters: pitch case hash("pitch_keycenter"): - setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); + if (opcode.value == "sample") + pitchKeycenterFromSample = true; + else { + pitchKeycenterFromSample = false; + setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); + } break; case hash("pitch_keytrack"): setValueFromOpcode(opcode, pitchKeytrack, Default::pitchKeytrackRange); diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 1d402bbe..61d97b27 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -382,6 +382,7 @@ struct Region { // Performance parameters: pitch uint8_t pitchKeycenter { Default::pitchKeycenter }; // pitch_keycenter + bool pitchKeycenterFromSample { false }; int pitchKeytrack { Default::pitchKeytrack }; // pitch_keytrack int pitchRandom { Default::pitchRandom }; // pitch_random int pitchVeltrack { Default::pitchVeltrack }; // pitch_veltrack diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index e63803c1..4dd86f5e 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -536,6 +536,9 @@ void sfz::Synth::finalizeSfzLoad() if (fileInformation->numChannels == 2) region->hasStereoSample = true; + if (region->pitchKeycenterFromSample) + region->pitchKeycenter = fileInformation->rootKey; + // TODO: adjust with LFO targets const auto maxOffset = [region]() { uint64_t sumOffsetCC = region->offset + region->offsetRandom; From ffb8e2c52a2bda9bfd6a3993945e8c7efc9c5c5a Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 14 Aug 2020 00:35:50 +0200 Subject: [PATCH 2/6] Add tests --- tests/FilesT.cpp | 18 ++++++++++++++++++ tests/TestFiles/root_key_38.flac | Bin 0 -> 8436 bytes tests/TestFiles/root_key_38.wav | Bin 0 -> 90 bytes tests/TestFiles/root_key_62.flac | Bin 0 -> 8436 bytes tests/TestFiles/root_key_62.wav | Bin 0 -> 90 bytes 5 files changed, 18 insertions(+) create mode 100644 tests/TestFiles/root_key_38.flac create mode 100644 tests/TestFiles/root_key_38.wav create mode 100644 tests/TestFiles/root_key_62.flac create mode 100644 tests/TestFiles/root_key_62.wav diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index d0d0b064..f4662417 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -684,3 +684,21 @@ TEST_CASE("[Files] Duplicate labels") REQUIRE(xmlMidnam.find("") != xmlMidnam.npos); REQUIRE(xmlMidnam.find("") != xmlMidnam.npos); } + +TEST_CASE("[Files] Key center from audio file") +{ + sfz::Synth synth; + synth.loadSfzString(fs::current_path() / "tests/TestFiles/sample_keycenter.sfz", R"( + pitch_keycenter=sample + sample=root_key_38.wav + sample=root_key_62.wav + sample=root_key_38.flac + sample=root_key_62.flac + )"); + + REQUIRE(synth.getNumRegions() == 4); + REQUIRE(synth.getRegionView(0)->pitchKeycenter == 38); + REQUIRE(synth.getRegionView(1)->pitchKeycenter == 62); + REQUIRE(synth.getRegionView(2)->pitchKeycenter == 38); + REQUIRE(synth.getRegionView(3)->pitchKeycenter == 62); +} diff --git a/tests/TestFiles/root_key_38.flac b/tests/TestFiles/root_key_38.flac new file mode 100644 index 0000000000000000000000000000000000000000..d8eefb36ad9420da8054eb2edc8bac8162343d5e GIT binary patch literal 8436 zcmeI&v1$S_7zgnG)ecf_2+kFPl2W*^I`xJwd1bGx-~3Y5ulVn_>;X_oY)rQm1YL>y_1>rC zo^8%d7TUhRk>1<^>wzQZm96pZ{(LeUzt~GIZ8HE~|AU)ZYFu0M6)r+qV+DP4f*}Pc zKmiI+fC3bt00k&O0SZun0u-PC1t>rP3Q&Lo6rcbFC_n)UP=EsWC~!K)X&@`#0knGt Da9${I literal 0 HcmV?d00001 diff --git a/tests/TestFiles/root_key_38.wav b/tests/TestFiles/root_key_38.wav new file mode 100644 index 0000000000000000000000000000000000000000..e7a27089c869484b53a1de2bf5911108f4c2f0ba GIT binary patch literal 90 zcmWIYbaM-0U|(DONqvt{8rWE`a-H|XL! zbn0954LZ8DUqA=%4TOIZNWL%mLio+GNj3m*uApS{Wt^;Tx3ctBs^7S}e12biMe9xP z-W~!C$^UKM5zy3xlfO}l5hrsK*E096*&ro%W+B_4$j zcal4GIXkPgdx0lCS^^(qPtGe>W8D7R>~(tKF8OJnW8mgDsLfL2yPBu0%4Cf>bnOH~ z3Q&Lo6rcbFC_n)UP=Epypa2CZKmiI+fC3bt00k&O0SZun0u-PC1^%PJ?z=b!&g46Q F_V;zmD2M<6 literal 0 HcmV?d00001 diff --git a/tests/TestFiles/root_key_62.wav b/tests/TestFiles/root_key_62.wav new file mode 100644 index 0000000000000000000000000000000000000000..658d5bd4d6d4510e649e6061feb7258c926a0d23 GIT binary patch literal 90 zcmWIYbaM-0U| Date: Fri, 14 Aug 2020 03:13:31 +0200 Subject: [PATCH 3/6] Support overriding with `key` opcode --- src/sfizz/Region.cpp | 1 + tests/FilesT.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 83417fb5..daffdb4f 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -232,6 +232,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); setRangeEndFromOpcode(opcode, keyRange, Default::keyRange); setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); + pitchKeycenterFromSample = false; break; case hash("lovel"): if (auto value = readOpcode(opcode.value, Default::midi7Range)) diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index f4662417..ef605365 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -694,11 +694,13 @@ TEST_CASE("[Files] Key center from audio file") sample=root_key_62.wav sample=root_key_38.flac sample=root_key_62.flac + key=10 sample=root_key_62.flac )"); - REQUIRE(synth.getNumRegions() == 4); + REQUIRE(synth.getNumRegions() == 5); REQUIRE(synth.getRegionView(0)->pitchKeycenter == 38); REQUIRE(synth.getRegionView(1)->pitchKeycenter == 62); REQUIRE(synth.getRegionView(2)->pitchKeycenter == 38); REQUIRE(synth.getRegionView(3)->pitchKeycenter == 62); + REQUIRE(synth.getRegionView(4)->pitchKeycenter == 10); } From fdfcee78f6b547293b33fdcd32c0710790285a1a Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Tue, 22 Sep 2020 20:33:57 +0200 Subject: [PATCH 4/6] Make sure the test files are not processed as wavetables --- tests/FilesT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index ef605365..7f56511b 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -689,7 +689,7 @@ TEST_CASE("[Files] Key center from audio file") { sfz::Synth synth; synth.loadSfzString(fs::current_path() / "tests/TestFiles/sample_keycenter.sfz", R"( - pitch_keycenter=sample + pitch_keycenter=sample oscillator=off sample=root_key_38.wav sample=root_key_62.wav sample=root_key_38.flac From c5a1d04fb74c488fe9b4dd7d616cc43371789297 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Tue, 22 Sep 2020 20:36:48 +0200 Subject: [PATCH 5/6] Make the `key` opcode not take effect on sample keycenter --- src/sfizz/Region.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index daffdb4f..83417fb5 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -232,7 +232,6 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); setRangeEndFromOpcode(opcode, keyRange, Default::keyRange); setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); - pitchKeycenterFromSample = false; break; case hash("lovel"): if (auto value = readOpcode(opcode.value, Default::midi7Range)) From bd6a5af03536f141cddf5297bd5cddb568a0ded6 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Tue, 22 Sep 2020 20:39:17 +0200 Subject: [PATCH 6/6] Update tests for new keycenter behavior --- tests/FilesT.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index 7f56511b..dbff1ba1 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -694,13 +694,15 @@ TEST_CASE("[Files] Key center from audio file") sample=root_key_62.wav sample=root_key_38.flac sample=root_key_62.flac + pitch_keycenter=10 sample=root_key_62.flac key=10 sample=root_key_62.flac )"); - REQUIRE(synth.getNumRegions() == 5); + REQUIRE(synth.getNumRegions() == 6); REQUIRE(synth.getRegionView(0)->pitchKeycenter == 38); REQUIRE(synth.getRegionView(1)->pitchKeycenter == 62); REQUIRE(synth.getRegionView(2)->pitchKeycenter == 38); REQUIRE(synth.getRegionView(3)->pitchKeycenter == 62); REQUIRE(synth.getRegionView(4)->pitchKeycenter == 10); + REQUIRE(synth.getRegionView(5)->pitchKeycenter == 62); }