_       _       
  (_) ___ | |_ ____
  | |/ _ \| __|_  /
  | | (_) | |_ / / 
 _/ |\___/ \__/___|
|__/               

Soundz (versions 0.1 - 0.4) for Dublin Maker 2022

Soundz v0.4

//
// soundz.c - v0.4 - Written by Ted Burke - last updated 23-July-2022
//
//   sudo apt install freeglut3-dev
//
//   gcc -o soundz soundz.c -lGL -lGLU -lglut -lpthread -lm
//   ./soundz
//

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>
#include <pthread.h>
#include <GL/freeglut.h>

int g_h=1080, g_w=1920;
unsigned char p[1080*1920*4] = {0};

pthread_t g_audio_thread_ID;
volatile int g_recording = 1;
volatile double g_intensity = 0;
double g_sensitivity = 2.0;

int g_colour = 1;
int g_colour_max = 2;
int g_mapping = 1;
int g_mapping_max = 2;

int g_debug = 1;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBegin(GL_POLYGON);
    glColor3f(g_intensity, 0, 0); glVertex3f(-0.6, -0.75, 0.5);
    glColor3f(0, g_intensity, 0); glVertex3f(0.6, -0.75, 0);
    glColor3f(0, 0, g_intensity); glVertex3f(0, 0.75, 0);
    glEnd();

    // Render fractal to pixel buffer
    int x, y, n, m[2];
    complex double z, zz, c;
    c = -g_intensity + -0.5*I;
    for (y=0 ; y<g_h/2 ; ++y) for (x=0 ; x<g_w ; ++x)
    {
        z = 0.005 * (x-g_w/2.0 + I*(y-g_h/2.0));
        for (n=0 ; n<10 ; ++n)
        {
            if (g_mapping == 1)
            {
                zz = z*z;
                z = zz + c;
            }
            else if (g_mapping == 2)
            {
                zz = z*z;
                z = (zz + c)/(zz-c);
            }

            if (cabs(z) > 4.0) break;
        }
        m[0] = 4*(y*g_w+x);
        m[1] = 4*((g_h-1-y)*g_w+g_w-x);

        n *= 25;

        for(int i=0 ; i<2 ; ++i)
        {
            if (g_colour == 1)
            {
                p[m[i]+0] = n; p[m[i]+1] = n; p[m[i]+2] = n; p[m[i]+3] = 255;
            }
            else if (g_colour == 2)
            {
                double a = carg(z);
                p[m[i]+0] = n * (1 - (a > 0)*sin(a)*sin(a));
                a = carg(z*cexp(I*2.0*M_PI/3.0));
                p[m[i]+1] = 255 * (1 - (a > 0)*sin(a)*sin(a));
                a = carg(z*cexp(I*4.0*M_PI/3.0));
                p[m[i]+2] = 255 * (1 - (a > 0)*sin(a)*sin(a));
                p[m[i]+3] = 255;
            }
        }
    }

    glWindowPos2i(0, 0);
    glDrawPixels(g_w, g_h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)p);

    glFlush();

    glutSwapBuffers();
    glutPostRedisplay();
}

void key_press(unsigned char key, int x, int y)
{
    if (key == 'q' || key == 'Q') glutLeaveMainLoop();
    if (key == 'F') glutFullScreen();
    if (key == 'f')
    {
        glutReshapeWindow(800, 600);
        glutPositionWindow(100, 100);
    }
    if (key == 'c') {g_colour++; if (g_colour > g_colour_max) g_colour = 1;}
    if (key == 'm') {g_mapping++; if (g_mapping > g_mapping_max) g_mapping = 1;}
}

void special_key_press(int key, int x, int y)
{
    if (key == GLUT_KEY_F1) /* do whatever */;
    if (key == GLUT_KEY_UP) /* do whatever */;
    if (key == GLUT_KEY_DOWN) /* do whatever */;
    if (key == GLUT_KEY_LEFT) /* do whatever */;
    if (key == GLUT_KEY_RIGHT) /* do whatever */;
}

void reshape_window(int width, int height)
{
    g_w = width;
    g_h = height;
    fprintf(stderr, "w=%d, h=%d\n", g_w, g_h);
}

void* audio_thread(void* param)
{
    int i, m, n;
    const int N = 128; 
    int16_t buf[N];

    double *pintensity = (double *) param;
    double intensity;

    fprintf(stderr, "Audio_thread is running\n");

    FILE *p_in = popen("parec --latency=256", "r");
    if (!p_in) fprintf(stderr, "Error opening input pipe\n");

    while (g_recording)
    {
        fread(buf, 2, N, p_in);
        intensity = 0;
        for (m=0 ; m<N ; ++m) intensity += abs(buf[m]);
        intensity /= N;
        intensity /= 32768.0;
        *pintensity = g_sensitivity * intensity;
        //fprintf(stderr, "%lf\n", intensity);
    }

    fprintf(stderr, "Closing audio input pipe\n");
    pclose(p_in);

    return NULL;
}

void onexit()
{
    g_recording = 0;
    fprintf(stderr, "Waiting for audio_thread to terminate\n");
    pthread_join(g_audio_thread_ID, NULL);
    fprintf(stderr, "Joined audio_thread\nExiting program\n");    
}

int main(int argc, char** argv)
{
    GLint win;

    // Initialise pixel buffer
    int x, y, n;
    for (y=0 ; y<g_h ; ++y) for (x=0 ; x<g_w ; ++x)
    {
        n = 4*(y*g_w+x);
        p[n+0] = 255;
        p[n+1] = 0;
        p[n+2] = 0;
        p[n+3] = 255;
    }

    // Initialise glut
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    // Create glut window
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    win = glutCreateWindow("soundz");

    // Register callback functions
    glutDisplayFunc(display);
    glutSpecialFunc(special_key_press);
    glutKeyboardFunc(key_press);
    glutReshapeFunc(reshape_window);
    //glutFullScreen();

    // Print OpenGL version
    fprintf(stderr, "%s\n", glGetString(GL_VERSION));

    // Launch audio thread
    pthread_create(&g_audio_thread_ID, NULL, &audio_thread, (void *) &g_intensity);

    // Register function to clean up after glut main loop exits
    atexit(onexit);

    // Enter glut main loop
    glutMainLoop();

    return 0;
}

Soundz v0.3

//
// soundz.c - v0.3 - Written by Ted Burke - last updated 23-July-2022
//
//   sudo apt install freeglut3-dev
//
//   gcc -o soundz soundz.c -lGL -lGLU -lglut -lpthread -lm
//   ./soundz
//

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>
#include <pthread.h>
#include <GL/freeglut.h>

int g_h=1080, g_w=1920;
unsigned char p[1080*1920*4] = {0};

pthread_t g_audio_thread_ID;
volatile int g_recording = 1;
volatile double g_intensity = 0;

int g_debug = 1;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBegin(GL_POLYGON);
    glColor3f(g_intensity, 0, 0); glVertex3f(-0.6, -0.75, 0.5);
    glColor3f(0, g_intensity, 0); glVertex3f(0.6, -0.75, 0);
    glColor3f(0, 0, g_intensity); glVertex3f(0, 0.75, 0);
    glEnd();

    // Render fractal to pixel buffer
    int x, y, n, m;
    complex double z, zz, c;
    c = -g_intensity + -0.5*I;
    for (y=0 ; y<g_h ; ++y) for (x=0 ; x<g_w ; ++x)
    {
        z = 0.005 * (x-g_w/2.0 + I*(y-g_h/2.0));
        for (n=0 ; n<10 ; ++n)
        {
            zz = z*z;
            z = (zz + c)/(zz-c);
            if (cabs(z) > 4.0) break;
        }
        m = 4*(y*g_w+x);
        n *= 25;
        //p[m+0] = n; p[m+1] = n; p[m+2] = n;
        double a = carg(z);
        p[m+0] = n * (1 - (a > 0)*sin(a)*sin(a));
        a = carg(z*cexp(I*2.0*M_PI/3.0));
        p[m+1] = 255 * (1 - (a > 0)*sin(a)*sin(a));
        a = carg(z*cexp(I*4.0*M_PI/3.0));
        p[m+2] = 255 * (1 - (a > 0)*sin(a)*sin(a));
        p[m+3] = 255;// * ((x/100)%2);      
    }

    glWindowPos2i(0, 0);
    glDrawPixels(g_w, g_h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)p);

    glFlush();

    glutSwapBuffers();
    glutPostRedisplay();
}

void key_press(unsigned char key, int x, int y)
{
    if (key == 'q' || key == 'Q') glutLeaveMainLoop();
    if (key == 'F') glutFullScreen();
    if (key == 'f')
    {
        glutReshapeWindow(800, 600);
        glutPositionWindow(100, 100);
    }
}

void special_key_press(int key, int x, int y)
{
    if (key == GLUT_KEY_F1) /* do whatever */;
    if (key == GLUT_KEY_UP) /* do whatever */;
    if (key == GLUT_KEY_DOWN) /* do whatever */;
    if (key == GLUT_KEY_LEFT) /* do whatever */;
    if (key == GLUT_KEY_RIGHT) /* do whatever */;
}

void reshape_window(int width, int height)
{
    g_w = width;
    g_h = height;
    fprintf(stderr, "w=%d, h=%d\n", g_w, g_h);
}

void* audio_thread(void* param)
{
    int i, m, n;
    const int N = 128; 
    int16_t buf[N];

    double *pintensity = (double *) param;
    double intensity;

    fprintf(stderr, "Audio_thread is running\n");

    FILE *p_in = popen("parec --latency=256", "r");
    if (!p_in) fprintf(stderr, "Error opening input pipe\n");

    while (g_recording)
    {
        fread(buf, 2, N, p_in);
        intensity = 0;
        for (m=0 ; m<N ; ++m) intensity += abs(buf[m]);
        intensity /= N;
        intensity /= 32768.0;
        *pintensity = 10 * intensity;
        //fprintf(stderr, "%lf\n", intensity);
    }

    fprintf(stderr, "Closing audio input pipe\n");
    pclose(p_in);

    return NULL;
}

void onexit()
{
    g_recording = 0;
    fprintf(stderr, "Waiting for audio_thread to terminate\n");
    pthread_join(g_audio_thread_ID, NULL);
    fprintf(stderr, "Joined audio_thread\nExiting program\n");    
}

int main(int argc, char** argv)
{
    GLint win;

    // Initialise pixel buffer
    int x, y, n;
    for (y=0 ; y<g_h ; ++y) for (x=0 ; x<g_w ; ++x)
    {
        n = 4*(y*g_w+x);
        p[n+0] = 255;
        p[n+1] = 0;
        p[n+2] = 0;
        p[n+3] = 255;
    }

    // Initialise glut
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    // Create glut window
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    win = glutCreateWindow("soundz");

    // Register callback functions
    glutDisplayFunc(display);
    glutSpecialFunc(special_key_press);
    glutKeyboardFunc(key_press);
    glutReshapeFunc(reshape_window);
    //glutFullScreen();

    // Print OpenGL version
    fprintf(stderr, "%s\n", glGetString(GL_VERSION));

    // Launch audio thread
    pthread_create(&g_audio_thread_ID, NULL, &audio_thread, (void *) &g_intensity);

    // Register function to clean up after glut main loop exits
    atexit(onexit);

    // Enter glut main loop
    glutMainLoop();

    return 0;
}

Soundz v0.2

//
// soundz.c - v0.2 - Written by Ted Burke - last updated 23-July-2022
//
// According to "pactl list sources short", Yeti mic is device 2 (s16le 2ch 44100Hz)
//
//   sudo apt install freeglut3-dev
//   gcc -o soundz soundz.c -lGL -lGLU -lglut -lpthread -lm
//   ./soundz.c
//
// (Note: -lGLU isn't actually required for initial example)
//
// Notes on compiling OpenGL / glut programs:
//   https://web.eecs.umich.edu/~sugih/courses/eecs487/glut-howto/
//
// OpenGL examples: https://cs.lmu.edu/~ray/notes/openglexamples/
// Learn OpenGL shaders: https://learnopengl.com/Getting-started/Shaders
//

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>
#include <pthread.h>
#include <GL/freeglut.h>
//#include <GL/glut.h>

int g_h=1080, g_w=1920;
unsigned char p[1080*1920*4] = {0};

pthread_t g_audio_thread_ID;
volatile int g_recording = 1;
volatile double g_intensity = 0;

int g_debug = 1;

void display()
{
  glClear(GL_COLOR_BUFFER_BIT);

  glBegin(GL_POLYGON);
    glColor3f(g_intensity, 0, 0); glVertex3f(-0.6, -0.75, 0.5);
    glColor3f(0, g_intensity, 0); glVertex3f(0.6, -0.75, 0);
    glColor3f(0, 0, g_intensity); glVertex3f(0, 0.75, 0);
  glEnd();

  // Render fractal to pixel buffer
  int x, y, n, m;
  complex double z, zz, c;
  c = -g_intensity + -0.5*I;
  for (y=0 ; y<g_h ; ++y) for (x=0 ; x<g_w ; ++x)
  {
      z = 0.005 * (x-g_w/2.0 + I*(y-g_h/2.0));
      for (n=0 ; n<10 ; ++n)
      {
          zz = z*z;
          z = (zz + c)/(zz-c);
          if (cabs(z) > 4.0) break;
      }
      m = 4*(y*g_w+x);
      n *= 25;
      //p[m+0] = n; p[m+1] = n; p[m+2] = n;
      double a = carg(z);
      p[m+0] = n * (1 - (a > 0)*sin(a)*sin(a));
      a = carg(z*cexp(I*2.0*M_PI/3.0));
      p[m+1] = 255 * (1 - (a > 0)*sin(a)*sin(a));
      a = carg(z*cexp(I*4.0*M_PI/3.0));
      p[m+2] = 255 * (1 - (a > 0)*sin(a)*sin(a));
      p[m+3] = 255;// * ((x/100)%2);      
  }

  //glRasterPos2i(0, 0); // seems to be centre of window
  glWindowPos2i(0, 0);
  glDrawPixels(g_w, g_h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)p);

  glFlush();

  glutSwapBuffers();
  glutPostRedisplay();
}

void key_press(unsigned char key, int x, int y)
{
    if (key == 'q' || key == 'Q')
    {
        glutLeaveMainLoop();
    }
    if (key == 'F')
    {
        glutFullScreen();
    }
    if (key == 'f')
    {
        glutReshapeWindow(800, 600);
        glutPositionWindow(100, 100);
    }
}

void reshape_window(int width, int height)
{
    g_w = width;
    g_h = height;
    fprintf(stderr, "w=%d, h=%d\n", g_w, g_h);
}

void* audio_thread(void* param)
{
    int i, m, n;
    const int N = 128; 
    int16_t buf[N];

    double *pintensity = (double *) param;
    double intensity;

    fprintf(stderr, "Audio_thread is running\n");

    FILE *p_in = popen("parec --latency=256", "r");
    if (!p_in)
    {
        fprintf(stderr, "Error opening input pipe\n");
    }

    while (g_recording)
    {
        fread(buf, 2, N, p_in);
        intensity = 0;
        for (m=0 ; m<N ; ++m) intensity += abs(buf[m]);
        intensity /= N;
        intensity /= 32768.0;
        *pintensity = 10 * intensity; 
        //fprintf(stderr, "%lf\n", intensity);
    }

    fprintf(stderr, "Closing audio input pipe\n");
    pclose(p_in);

    return NULL;
}

void onexit()
{
  g_recording = 0;
  fprintf(stderr, "Waiting for audio_thread to terminate\n");
  pthread_join(g_audio_thread_ID, NULL);
  fprintf(stderr, "Joined audio_thread\nExiting program\n");    
}

int main(int argc, char** argv)
{
  GLint win;

  // Initialise pixel buffer
  int x, y, n;
  for (y=0 ; y<g_h ; ++y) for (x=0 ; x<g_w ; ++x)
  {
      n = 4*(y*g_w+x);
      p[n+0] = 255;
      p[n+1] = 0;
      p[n+2] = 0;
      p[n+3] = 255;
  }

  // Initialise glut
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

  // Create glut window
  glutInitWindowPosition(100, 100);
  glutInitWindowSize(800, 600);
  win = glutCreateWindow("soundz");
  glutDisplayFunc(display);
  //glutSpecialFunc(key_press);
  glutKeyboardFunc(key_press);
  glutReshapeFunc(reshape_window);
  //glutFullScreen();

  // Print OpenGL version
  //fprintf(stderr, (char *)(glGetString(GL_VERSION)));
  fprintf(stderr, "%s\n", glGetString(GL_VERSION));

  // Launch audio thread
  pthread_create(&g_audio_thread_ID, NULL, &audio_thread, (void *) &g_intensity);

  // Register function to clean up after glut main loop exits
  atexit(onexit);

  // Enter glut main loop
  glutMainLoop();

  return 0;
}

Soundz v0.1

//
// soundz.c - v0.1 - Written by Ted Burke - last updated 23-July-2022
//
// According to "pactl list sources short", Yeti mic is device 2 (s16le 2ch 44100Hz)
//
//   sudo apt install freeglut3-dev
//   gcc -o soundz soundz.c -lGL -lGLU -lglut -lpthread -lm
//   ./soundz.c
//
// (Note: -lGLU isn't actually required for initial example)
//
// Notes on compiling OpenGL / glut programs:
//   https://web.eecs.umich.edu/~sugih/courses/eecs487/glut-howto/
//
// OpenGL examples: https://cs.lmu.edu/~ray/notes/openglexamples/
// Learn OpenGL shaders: https://learnopengl.com/Getting-started/Shaders
//

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <pthread.h>
#include <GL/glut.h>

pthread_t g_audio_thread_ID;
volatile int g_recording = 1;
volatile double g_intensity = 0;

int g_debug = 1;

void display()
{
  glClear(GL_COLOR_BUFFER_BIT);

  glBegin(GL_POLYGON);
    glColor3f(g_intensity, 0, 0); glVertex3f(-0.6, -0.75, 0.5);
    glColor3f(0, g_intensity, 0); glVertex3f(0.6, -0.75, 0);
    glColor3f(0, 0, g_intensity); glVertex3f(0, 0.75, 0);
  glEnd();

  glFlush();

  glutSwapBuffers();
  glutPostRedisplay();
}

void* audio_thread(void* param)
{
    int i, m, n;
    const int N = 128; 
    int16_t buf[N];

    double *pintensity = (double *) param;
    double intensity;

    fprintf(stderr, "Audio_thread is running\n");

    FILE *p_in = popen("parec --latency=256", "r");
    if (!p_in)
    {
        fprintf(stderr, "Error opening input pipe\n");
    }

    while (g_recording)
    {
        fread(buf, 2, N, p_in);
        intensity = 0;
        for (m=0 ; m<N ; ++m) intensity += abs(buf[m]);
        intensity /= N;
        intensity /= 32768.0;
        *pintensity = 10 * intensity; 
        //fprintf(stderr, "%lf\n", intensity);
    }

    fprintf(stderr, "Closing audio input pipe\n");
    pclose(p_in);

    return NULL;
}

void onexit()
{
  g_recording = 0;
  fprintf(stderr, "Waiting for audio_thread to terminate\n");
  pthread_join(g_audio_thread_ID, NULL);
  fprintf(stderr, "Joined audio_thread\nExiting program\n");    
}

int main(int argc, char** argv)
{
  GLint win;

  // Initialise glut
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

  // Create glut window
  glutInitWindowPosition(80, 80);
  glutInitWindowSize(800, 600);
  win = glutCreateWindow("soundz");
  glutDisplayFunc(display);

  // Launch audio thread
  pthread_create(&g_audio_thread_ID, NULL, &audio_thread, (void *) &g_intensity);

  // Register function to clean up after glut main loop exits
  atexit(onexit);

  // Enter glut main loop
  glutMainLoop();

  return 0;
}