From: sgunderson@bigfoot.com <> Date: Mon, 19 Jul 2010 23:42:44 +0000 (+0200) Subject: In glpitch, stretch the x axis a bit so that we have more precision around the intere... X-Git-Url: https://git.sesse.net/?p=pitch;a=commitdiff_plain;h=8603ad0d114005cee0dab2f7facd4faebae57f5d In glpitch, stretch the x axis a bit so that we have more precision around the interesting parts. --- diff --git a/config.h b/config.h index 87f25e9..da6a691 100644 --- a/config.h +++ b/config.h @@ -15,4 +15,12 @@ #define TUNING WELL_TEMPERED_GUITAR +// Compress the x scale of the glpitch display in a nonlinear way +// so that the view is more precise around the reference frequencies. +#define COMPRESS_PITCH_DISPLAY 1 + +// Lower is more compressed. Anything over 2-3 is probably going to negate +// the entire effect. +#define PITCH_COMPRESSION_SIGMA 1.0 + #endif /* !defined(_CONFIG_H) */ diff --git a/glpitch.cpp b/glpitch.cpp index a3c3010..4aea821 100644 --- a/glpitch.cpp +++ b/glpitch.cpp @@ -9,11 +9,46 @@ #define MIN_X -40 #define MAX_X 5 -double find_pos(double freq) +double find_linear_pos(double freq) { return 12.0 * log2(freq / BASE_PITCH) - 3.0; } +#if COMPRESS_PITCH_DISPLAY +// bend the scale a bit to get more precision around the interesting points +double magnifying_glass(double x) +{ + double sigma = PITCH_COMPRESSION_SIGMA; + double div = 1.0 / sqrt(2.0 * sigma * sigma); + return + erf((x - find_linear_pos(notes[0].freq)) * div) + + erf((x - find_linear_pos(notes[1].freq)) * div) + + erf((x - find_linear_pos(notes[2].freq)) * div) + + erf((x - find_linear_pos(notes[3].freq)) * div) + + erf((x - find_linear_pos(notes[4].freq)) * div) + + erf((x - find_linear_pos(notes[5].freq)) * div); +} + +// like nonlinear_func, but f(MIN_X) = MIN_X and f(MAX_X) = MAX_X +double normalized_magnifying_glass(double x) +{ + double y = magnifying_glass(x); + double min_y = magnifying_glass(MIN_X); + double max_y = magnifying_glass(MAX_X); + return (y - min_y) * (MAX_X - MIN_X) / (max_y - min_y) + MIN_X; +} +#endif /* COMPRESS_PITCH_DISPLAY */ + +double find_display_pos(double freq) +{ + double linear_pos = find_linear_pos(freq); +#if COMPRESS_PITCH_DISPLAY + return normalized_magnifying_glass(linear_pos); +#else + return linear_pos; +#endif +} + int main(void) { PitchDetector pd(SAMPLE_RATE, FFT_LENGTH, PAD_FACTOR, OVERLAP); @@ -63,7 +98,7 @@ int main(void) glEnd(); if (peak.second - log10(FFT_LENGTH) >= 0.0) { - double peak_pos = find_pos(peak.first); + double peak_pos = find_display_pos(peak.first); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBegin(GL_QUADS); @@ -79,7 +114,7 @@ int main(void) glBegin(GL_LINES); for (int i = 0; i < 6; ++i) { - double pos = find_pos(notes[i].freq); + double pos = find_display_pos(notes[i].freq); glVertex2f(pos, 0.0f); glVertex2f(pos, 1.0f); }