Tuesday, February 2, 2021

Metrw-pitch graphics

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.
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.
8. To get inspired, refer to this guide (which is outdated but requires you to set up GLFW only on your project) or this one (which is updated but requires you to set up GLFW and GLAD). Run follow code after that.
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);
}