5 #include "linux_audio.h"
7 #include "pitchdetector.h"
12 double find_linear_pos(double freq)
14 return 12.0 * log2(freq / BASE_PITCH) - 3.0;
17 #if COMPRESS_PITCH_DISPLAY
18 // bend the scale a bit to get more precision around the interesting points
19 double magnifying_glass(double x)
21 double sigma = PITCH_COMPRESSION_SIGMA;
22 double div = 1.0 / sqrt(2.0 * sigma * sigma);
24 erf((x - find_linear_pos(notes[0].freq)) * div) +
25 erf((x - find_linear_pos(notes[1].freq)) * div) +
26 erf((x - find_linear_pos(notes[2].freq)) * div) +
27 erf((x - find_linear_pos(notes[3].freq)) * div) +
28 erf((x - find_linear_pos(notes[4].freq)) * div) +
29 erf((x - find_linear_pos(notes[5].freq)) * div);
32 // like nonlinear_func, but f(MIN_X) = MIN_X and f(MAX_X) = MAX_X
33 double normalized_magnifying_glass(double x)
35 double y = magnifying_glass(x);
36 double min_y = magnifying_glass(MIN_X);
37 double max_y = magnifying_glass(MAX_X);
38 return (y - min_y) * (MAX_X - MIN_X) / (max_y - min_y) + MIN_X;
40 #endif /* COMPRESS_PITCH_DISPLAY */
42 double find_display_pos(double freq)
44 double linear_pos = find_linear_pos(freq);
45 #if COMPRESS_PITCH_DISPLAY
46 return normalized_magnifying_glass(linear_pos);
54 PitchDetector pd(SAMPLE_RATE, FFT_LENGTH, PAD_FACTOR, OVERLAP);
55 snd_pcm_t *pcm = get_dsp_handle(SAMPLE_RATE);
57 SDL_Init(SDL_INIT_VIDEO);
58 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
59 SDL_SetVideoMode(1024, 200, 32, SDL_OPENGL);
61 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
62 glClear(GL_COLOR_BUFFER_BIT);
63 glDisable(GL_DEPTH_TEST);
67 while (SDL_PollEvent(&event)) {
70 if (event.key.keysym.sym == SDLK_ESCAPE) {
79 short buf[FFT_LENGTH / PAD_FACTOR / OVERLAP];
80 read_chunk(pcm, buf, FFT_LENGTH / PAD_FACTOR / OVERLAP);
81 std::pair<double, double> peak = pd.detect_pitch(buf);
83 glMatrixMode(GL_PROJECTION);
85 glOrtho(MIN_X, MAX_X, 1.0f, 0.0f, 0.0f, 1.0f);
87 glMatrixMode(GL_MODELVIEW);
90 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
94 glColor4f(0.0, 0.0f, 0.0f, 0.05f);
95 glVertex2f(MIN_X, 0.0f);
96 glVertex2f(MIN_X, 1.0f);
97 glVertex2f(MAX_X, 1.0f);
98 glVertex2f(MAX_X, 0.0f);
101 if (peak.second - log10(FFT_LENGTH) >= 0.0) {
102 double peak_pos = find_display_pos(peak.first);
103 double strength = peak.second / 40.0f;
105 glEnable(GL_POLYGON_SMOOTH);
106 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
107 glEnable(GL_POLYGON_SMOOTH);
110 glColor4f(0.0f, strength, 1.0 - strength, 0.2f);
111 glVertex2f(peak_pos - 0.1, 0.0f);
112 glVertex2f(peak_pos - 0.1, 1.0f);
113 glVertex2f(peak_pos + 0.1, 1.0f);
114 glVertex2f(peak_pos + 0.1, 0.0f);
117 glDisable(GL_POLYGON_SMOOTH);
120 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
123 for (int i = 0; i < 6; ++i) {
124 double pos = find_display_pos(notes[i].freq);
125 glVertex2f(pos, 0.0f);
126 glVertex2f(pos, 1.0f);
130 SDL_GL_SwapBuffers();