Indroduction
1. I'm homeless and can't implement this code in DSP kit. I offer it for free.
2. Project detects fundamental frequency (fundFreq), or pitch, performing DFT grid around fundFreq detected by FFT. Indeed it should be embedded in a project executing, in part, in DSP kit.
2. Project should have two parts. One, executing in DSP kit detects fundFreq (see DFT_grid.m) and other, executing in PC's processor, has the graphics.
3. Graphics part represents musical note as rectangular with height representing note's interval from base by some unit e.g. cent of semitone. Wide represents note's duration. Color represents sound's volume. At a specific speed, the rectangle (Quad) travels to the left.
4. At the left side of window a pointer moves up and down. Its point's height from base represents voice's pitch.
4. At the left side of window a pointer moves up and down. Its point's height from base represents voice's pitch.
5. Another vertical scale with zero at its middle, upper half representing
one semitone, and lower also one semitone, is micrometer. Zero
represents the note rectangular's upper edge.
6. Third vertical scale - not shown in graphics - indicates the volume of the sound.
7. A speed regulator is a
must, as well a horizontal scroll bar for the user can go back.
9. I got assistance from Mr. Dougbinks in learning how to make 2D graphics using OpenGL.
______________________________________________
#include <GLFW/glfw3.h>
#include <gl/GL.h>
#include <iostream>
void render_loop(float a, float b, float x, int lineHeight2, int lineHeight1)
{
glClearColor(0.2f, 0.2f, 1.0f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(a + x, 0.0f);
glVertex2f(b + x, 0.0f);
glVertex2f(b + x, 700.0f);
glVertex2f(a + x, 700.0f);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(0, 0.0f);
glVertex2f(200, 0.0f);
glVertex2f(200, 900.0f);
glVertex2f(0, 900.0f);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2i(100, lineHeight2);
glVertex2i(200, lineHeight2);
glColor3f(1.0, 0.0, 1.0);
glVertex2i(0, lineHeight1);
glVertex2i(100, lineHeight1);
glColor3f(0.0, 0.0, 0.0);
glVertex2i(100, 0);
glVertex2i(100, 800);
glColor3f(0.0, 0.0, 0.0);
glVertex2i(0, 400);
glVertex2i(100, 400);
glEnd();
}
/* program entry */
int main(int argc, char* argv[])
{
GLFWwindow* window;
if (!glfwInit())
{
std::cout << "Failed to initialize GLFW\n";
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(1800, 800, "LearnSinging", NULL, NULL);
glfwSetWindowPos(window, 10, 40);
if (!window)
{
std::cout << "Failed to open GLFW window\n";
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// set up view
glViewport(0, 0, 1800, 800);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// see https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml
glOrtho(0.0, 800.0, 0.0, 800.0, 0.0, 1.0); // this creates a canvas
// you can do 2D drawing
// Main loop
float x = 0.0f;
/*If screen's frequency is 60 hz, that is 60 iterations/second, then
speedFactor = 1 means
speed = 1 pixel / iteration, or 60 pixels/second.
In general speedFactor = speed/screen's frequency.
For example if you prefer whole note = 1 sec representing by 90 pixels,
it means speed = 90 pixels/sec, which needs speedFactor = 1.5.*/
float speedFactor = 1.3f;
float a{ 200.0f };
float b{ 750.0f };
int lineHeight2{ 500 };
int lineHeight1{ 500 };
int lastTime{ 0 };
while (!glfwWindowShouldClose(window))
{
if (glfwGetTime() >= lastTime)
{
lineHeight2 = rand() % 100 + 650;
lineHeight1 = ((lineHeight2 - 700) * 5) + 400;
lastTime = lastTime + 1;
}
x = x - speedFactor;
// Draw gears
render_loop(a, b, x, lineHeight2, lineHeight1);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}
// Terminate GLFW
glfwTerminate();
// Exit program
exit(EXIT_SUCCESS);
}