diff --git a/src/common/dsp/SurgeVoice.cpp b/src/common/dsp/SurgeVoice.cpp index 8a393c2a472..1bc9d912741 100644 --- a/src/common/dsp/SurgeVoice.cpp +++ b/src/common/dsp/SurgeVoice.cpp @@ -82,7 +82,13 @@ float SurgeVoiceState::getPitch(SurgeStorage *storage) { shift = channel; } - res += 12 * shift; + if (storage->isStandardTuning) + res += 12 * shift; + else + { + auto ct = storage->currentScale.tones[storage->currentScale.count - 1].cents; + res += ct / 100 * shift; + } } return res; diff --git a/src/surge-testrunner/UnitTestsTUN.cpp b/src/surge-testrunner/UnitTestsTUN.cpp index 6322128833f..89e4ea8cf6a 100644 --- a/src/surge-testrunner/UnitTestsTUN.cpp +++ b/src/surge-testrunner/UnitTestsTUN.cpp @@ -7,6 +7,7 @@ #include "Player.h" #include "catch2/catch2.hpp" +#include "Tunings.h" #include "UnitTestUtilities.h" @@ -568,7 +569,7 @@ TEST_CASE("An Octave is an Octave", "[tun]") } } -TEST_CASE("Channel to Octave Mapping") +TEST_CASE("Channel to Octave Mapping", "[tun]") { SECTION("When disabled and no tuning applied, channel 2 is the same as channel 1") { @@ -644,6 +645,63 @@ TEST_CASE("Channel to Octave Mapping") REQUIRE(f2 == Approx(f1 * 2).margin(0.1)); } } + + SECTION("ED2-7 Confirm that it still doubles with short scale") + { + auto surge = surgeOnSine(); + surge->storage.mapChannelToOctave = true; + auto scale = Tunings::evenDivisionOfSpanByM(2, 7); + surge->storage.retuneToScale(scale); + + for (int i = 0; i < 10; ++i) + surge->process(); + auto f0 = frequencyForNote(surge, 60, 2, 0, 0); + auto f1 = frequencyForNote(surge, 60, 2, 0, 1); + auto f2 = frequencyForNote(surge, 60, 2, 0, 2); + auto f15 = frequencyForNote(surge, 60, 2, 0, 15); + auto f14 = frequencyForNote(surge, 60, 2, 0, 14); + + auto fr = Tunings::MIDI_0_FREQ * 32; + REQUIRE(f0 == Approx(fr).margin(1)); + REQUIRE(f1 == Approx(fr * 2).margin(1)); + REQUIRE(f2 == Approx(fr * 4).margin(1)); + REQUIRE(f15 == Approx(fr / 2).margin(1)); + REQUIRE(f14 == Approx(fr / 4).margin(1)); + } + + SECTION("ED3-7 Triples Frequency") + { + auto surge = surgeOnSine(); + surge->storage.mapChannelToOctave = true; + auto scale = Tunings::evenDivisionOfSpanByM(3, 7); + surge->storage.retuneToScale(scale); + + for (int i = 0; i < 10; ++i) + surge->process(); + auto f0 = frequencyForNote(surge, 60, 2, 0, 0); + auto f1 = frequencyForNote(surge, 60, 2, 0, 1); + + auto fr = Tunings::MIDI_0_FREQ * 32; + REQUIRE(f0 == Approx(fr).margin(1)); + REQUIRE(f1 == Approx(fr * 3).margin(1)); + } + + SECTION("ED4-7 Quads Frequency") + { + auto surge = surgeOnSine(); + surge->storage.mapChannelToOctave = true; + auto scale = Tunings::evenDivisionOfSpanByM(4, 7); + surge->storage.retuneToScale(scale); + + for (int i = 0; i < 10; ++i) + surge->process(); + auto f0 = frequencyForNote(surge, 60, 2, 0, 0); + auto f1 = frequencyForNote(surge, 60, 2, 0, 1); + + auto fr = Tunings::MIDI_0_FREQ * 32; + REQUIRE(f0 == Approx(fr).margin(1)); + REQUIRE(f1 == Approx(fr * 4).margin(1)); + } } TEST_CASE("Non-Monotonic Tunings", "[tun]") @@ -1274,4 +1332,4 @@ TEST_CASE("NoteToPitch Invalid Ranges", "[tun]") REQUIRE(ro == ru); } } -} \ No newline at end of file +}