Skip to content

Commit

Permalink
Fix three problems with tuning alpha (#919)
Browse files Browse the repository at this point in the history
1: The tuning file was mis-interpreting fractions to cents convrersion
2: The tuning file wrapping assumed 2/1 as a last note in one place
3: If you choose a non-scl file you pine for the fjords

This addresses those, and moves us further along #828
  • Loading branch information
baconpaul authored Jun 17, 2019
1 parent 42b70bb commit e8f992b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 44 deletions.
79 changes: 44 additions & 35 deletions src/common/SurgeStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1190,49 +1190,58 @@ float envelope_rate_linear(float x)

void SurgeStorage::retuneToScale(const Surge::Storage::Scale& s)
{
int scale0 = 48;
int scale0 = 48; // This is the 1.0 point
float value0 = 16;

for (int i = 0; i < 512; ++i)
{
int noteBase = i - 256;
int distanceFromScale0 = noteBase - scale0 - 1;
int turns = 0;
float baseValue = value0;
while (distanceFromScale0 < 0)
{
distanceFromScale0 += s.count;
baseValue /= 2;
}
while (distanceFromScale0 >= s.count)
{
distanceFromScale0 -= s.count;
baseValue *= 2;
}
#if DEBUG_SCALE
if ((i>= 254 && i <=258) || ( i >= 302 && i <= 308))
std::cout << i << " " << std::setw(5) << noteBase << " or " << i << " D0=" << std::setw(3) << distanceFromScale0
<< " PP=" << std::setw(10) << table_pitch[i]
<< " bv=" << std::setw(5) << baseValue
<< " sc=" << std::setw(10) << s.tones[distanceFromScale0].floatValue
<< " exp=" << std::setw(10) << pow( 2.0f, s.tones[distanceFromScale0].floatValue - 1.0f)
<< " sc*bv=" << std::setw(10) << pow( 2.0f, s.tones[distanceFromScale0].floatValue - 1.0f) * baseValue
<< " diff=" << std::setw(10) << pow( 2.0f, s.tones[distanceFromScale0].floatValue - 1.0f) * baseValue - table_pitch[i]
;
#endif

table_pitch[i] = pow( 2.0f, s.tones[distanceFromScale0].floatValue - 1.0f) * baseValue;
float pitches[512];
int pos0 = 256 + scale0;
pitches[pos0] = 1.0;
for (int i=0; i<512; ++i)
{
int distanceFromScale0 = i - pos0;

if( distanceFromScale0 == 0 )
{
}
else
{
int rounds = (distanceFromScale0-1) / s.count;
int thisRound = (distanceFromScale0-1) % s.count;

#if DEBUG_SCALE
if ((i>= 254 && i <=258) || ( i >= 302 && i <= 308))
std::cout << " NEWP=" << table_pitch[i] << std::endl;
#endif

if( thisRound < 0 )
{
thisRound += s.count;
rounds -= 1;
}
float mul = pow( s.tones[s.count-1].floatValue, rounds);
pitches[i] = s.tones[thisRound].floatValue + rounds * (s.tones[s.count - 1].floatValue - 1.0);
float otp = table_pitch[i];
table_pitch[i] = pow( 2.0, pitches[i] + 3 );

#if DEBUG_SCALES
if( i > 296 && i < 340 )
std::cout << "PITCH: i=" << i << " n=" << i - 256 << " r=" << rounds << " t=" << thisRound
<< " p=" << pitches[i]
<< " t=" << s.tones[thisRound].floatValue
<< " tp=" << table_pitch[i]
<< " otp=" << otp
<< " diff=" << table_pitch[i] - otp

//<< " l2p=" << log(otp)/log(2.0)
//<< " l2p-p=" << log(otp)/log(2.0) - pitches[i] - rounds - 3
<< std::endl;
#endif
}
}

for( int i=0; i<512; ++i )
{
table_pitch_inv[i] = 1.f / table_pitch[i];
table_note_omega[0][i] =
(float)sin(2 * M_PI * min(0.5, 440 * table_pitch[i] * dsamplerate_os_inv));
table_note_omega[1][i] =
(float)cos(2 * M_PI * min(0.5, 440 * table_pitch[i] * dsamplerate_os_inv));

}
}

Expand Down
15 changes: 10 additions & 5 deletions src/common/Tunings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <math.h>

/*
From: http://huygens-fokker.org/scala/scl_format.html
Expand Down Expand Up @@ -67,24 +68,28 @@ Surge::Storage::Scale Surge::Storage::readSCLFile(std::string fname)
{
t.type = Tone::kToneCents;
t.cents = atof(line.c_str());
t.floatValue = t.cents / 1200.0 + 1.0;
}
else
{
t.type = Tone::kToneRatio;
auto slashPos = line.find("/");
if (slashPos == std::string::npos)
{
t.ratio_d = atoi(line.c_str());
t.ratio_n = 1;
t.ratio_n = atoi(line.c_str());
t.ratio_d = 1;
}
else
{
t.ratio_n = atoi(line.substr(0, slashPos).c_str());
t.ratio_d = atoi(line.substr(slashPos + 1).c_str());
}
t.floatValue = 1.0 * t.ratio_n / t.ratio_d;

// 2^(cents/1200) = n/d
// cents = 1200 * log(n/d) / log(2)

t.cents = 1200 * log(1.0 * t.ratio_n/t.ratio_d) / log(2.0);
}
t.floatValue = t.cents / 1200.0 + 1.0;
res.tones.push_back(t);

break;
Expand All @@ -101,7 +106,7 @@ std::ostream& Surge::Storage::operator<<(std::ostream& os, const Surge::Storage:
os << t.cents;
else
os << t.ratio_n << " / " << t.ratio_d;
os << " (" << t.floatValue << ")";
os << " (f=" << t.floatValue << " c=" << t.cents << ")";
return os;
}

Expand Down
9 changes: 9 additions & 0 deletions src/common/gui/SurgeGUIEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2754,6 +2754,15 @@ void SurgeGUIEditor::showSettingsMenu(CRect &menuRect)
{
auto cb = [this](std::string sf)
{
std::string sfx = ".scl";
if( sf.length() >= sfx.length())
{
if( sf.compare(sf.length() - sfx.length(), sfx.length(), sfx) != 0 )
{
Surge::UserInteractions::promptError( "Please only select .scl files", "Invalid Choice" );
return;
}
}
auto sc = Surge::Storage::readSCLFile(sf);
this->synth->storage.retuneToScale(sc);
};
Expand Down
9 changes: 5 additions & 4 deletions src/headless/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ void testTuning()
{
SurgeSynthesizer* surge = Surge::Headless::createSurge(44100);

Surge::Storage::Scale s = Surge::Storage::readSCLFile("/Users/paul/dev/music/scl/05-22.scl");
//Surge::Storage::Scale s = Surge::Storage::readSCLFile("/Users/paul/dev/music/test_scl/Q4.scl" );
Surge::Storage::Scale s = Surge::Storage::readSCLFile("/Users/paul/dev/music/test_scl/12-flat.scl" );
std::cout << s;

auto n2f = [surge](int n)
Expand All @@ -108,11 +109,11 @@ void testTuning()
//auto s = Surge::Storage::readSCLFile("/Users/paul/tmp/scl/lumma_12_strangeion.scl");

std::cout << "BEFORE\n";
n2f(0); n2f(24); n2f(25); n2f(60); n2f(57); n2f(48);
//n2f(0); n2f(24); n2f(25); n2f(60); n2f(57); n2f(48);
surge->storage.retuneToScale(s);

std::cout << "AFTER\n";
n2f(0); n2f(24); n2f(25); n2f(60); n2f(57); n2f(48);
//std::cout << "AFTER\n";
//n2f(0); n2f(24); n2f(25); n2f(60); n2f(57); n2f(48);
}

void playSomeBach()
Expand Down

0 comments on commit e8f992b

Please sign in to comment.