summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--shader.frag41
-rw-r--r--sv.c69
3 files changed, 91 insertions, 21 deletions
diff --git a/Makefile b/Makefile
index d223ea2..3585885 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,2 @@
 sv: sv.c
-	gcc -lglfw  -lGL -lGLEW -lpthread -lm sv.c -o sv
+	gcc -lglfw  -lGL -lGLEW -lpthread -lm -lasound sv.c -o sv
diff --git a/shader.frag b/shader.frag
index c6cc012..0141563 100644
--- a/shader.frag
+++ b/shader.frag
@@ -4,11 +4,11 @@ precision mediump float;
 #endif
 
 uniform vec2 resolution;
-uniform float time;
+uniform float ticks;
+uniform int program;
 
 uniform sampler2D images[4];
 layout (binding = 0,rgba32f) uniform image2D backbuffer;
-//uniform image2DArray buffers;
 uniform float ratios[4];
 uniform float params[32];
 
@@ -18,25 +18,34 @@ float random (in float x) {
   return fract(sin(x)*43758.5453123)-0.5;
 }
 
-vec4 image(int i) {
+vec4 img(int i) {
 	vec2 st = gl_FragCoord.xy/resolution.xy;
   st.x *= ratios[i];
   st.x += (1-ratios[i])*0.5;
-  st.x += 0.5*time;
+  st.x += 0.5;
   return texture2D(images[i],st);
 }
 
 void main (void) {
-	vec4 img1 = mix(image(0),image(1),sin(time));
-	vec4 img2 = mix(image(2),image(3),cos(time));
-  ivec2 P = ivec2(gl_FragCoord.xy);
-  vec4 buf = imageLoad(backbuffer,P);
-  buf.rg = buf.gr;
-  //buf.b = 0.0;
-  vec4 i = mix(img1,img2,0.5);
-  //P = ivec2(gl_FragCoord.xy);
-  imageStore(backbuffer,P,i);
-  i = mix(i,buf,0.8);
-  //i = image(0);
-  fragColor = i;
+    vec4 image = img(0);
+  if (program == 0) {
+    image = img(2);
+    image.rg = image.gr;
+    image = 1.5*image;
+    }
+  /*
+  else {
+    ivec2 P = ivec2(gl_FragCoord.xy);
+    vec4 buf = imageLoad(backbuffer,P);
+    vec4 img1 = mix(img(0),img(1),sin(ticks));
+    vec4 img2 = mix(img(2),img(3),cos(ticks));
+    buf.bg = buf.gr;
+    //buf.b = 0.0;
+    vec4 i = mix(img1,img2,0.5);
+    //P = ivec2(gl_FragCoord.xy);
+    imageStore(backbuffer,P,i);
+    image = mix(i,buf,0.8);
+    }
+    */
+  fragColor = image;
 }
diff --git a/sv.c b/sv.c
index 6e37600..de792f0 100644
--- a/sv.c
+++ b/sv.c
@@ -7,12 +7,15 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <alsa/asoundlib.h>
 
 #define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h"
 #define STB_IMAGE_WRITE_IMPLEMENTATION
 #include "stb_image_write.h"
 
+#define MIDICHK(stmt, msg) if((stmt) < 0) {puts("ERROR: "#msg); exit(1);}
+
 int width = 1920;
 int height = 1080;
 GLFWwindow* window;
@@ -47,6 +50,15 @@ typedef struct Param {
 
 Parameter parameters[32];
 
+static snd_seq_t *seq_handle;
+static int in_port;
+
+void midi_open(void) {
+  MIDICHK(snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0), "Could not open sequencer");
+  MIDICHK(snd_seq_set_client_name(seq_handle, "Midi Listener"), "Could not set client name");
+  MIDICHK(in_port = snd_seq_create_simple_port(seq_handle, "listen:in", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION), "Could not open port");
+}
+
 void screenshot() {
   unsigned char pixels[width*height*4];
   time_t current_time = time(NULL);
@@ -196,6 +208,48 @@ void updateParams(int force) {
   }
 }
 
+int ticks =0;
+int running = 0;
+int note = 0;
+int vel = 0;
+
+void *readMidi() {
+  midi_open();
+  while(1) {
+    snd_seq_event_t *ev = NULL;
+    snd_seq_event_input(seq_handle, &ev);
+    if (ev->type == SND_SEQ_EVENT_NOTEON) {
+      note = ev->data.note.note;
+      vel = ev->data.note.velocity;
+    }
+    else if (ev->type == SND_SEQ_EVENT_NOTEOFF) {
+      vel = 0;
+    }
+    else if(ev->type == SND_SEQ_EVENT_CONTROLLER)
+        printf("[%d] Control:  %2x val(%2x)\n", ev->time.tick,
+                                                ev->data.control.param,
+                                                ev->data.control.value);
+    else if(ev->type == SND_SEQ_EVENT_SONGPOS) {
+      ticks = ev->data.control.value*24;
+        printf("[%d] SPP:  %i val(%i)\n", ev->time.tick,
+                                                ev->data.control.param,
+                                                ev->data.control.value);
+    }
+    else if(ev->type == SND_SEQ_EVENT_START)
+      running = 1;
+    else if(ev->type == SND_SEQ_EVENT_STOP)
+      running = 0;
+    else if(ev->type == SND_SEQ_EVENT_CONTINUE)
+      running = 1;
+    else if(ev->type == SND_SEQ_EVENT_CLOCK) {
+      if (running == 1) ticks++;
+    }
+    else
+        printf("[%d] Unknown:  Unhandled Event Received\n", ev->time.tick);
+  }
+}
+
+
 void *readStdin() {
   while (1) {
     char * str;
@@ -252,13 +306,19 @@ int main(int argc, char **argv) {
   glTextureStorage2D(backbuffer,1,GL_RGBA32F,width,height);
   glBindImageTexture(0,backbuffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   
-  pthread_t stdin_t;
-  pthread_create(&stdin_t, NULL, readStdin, NULL);
+  //pthread_t stdin_t;
+  //pthread_create(&stdin_t, NULL, readStdin, NULL);
+  pthread_t midiin_t;
+  pthread_create(&midiin_t, NULL, readMidi, NULL);
   pthread_t frag_t;
   pthread_create(&frag_t, NULL, watchShader, NULL);
 
   while (!glfwWindowShouldClose(window)) {
-    glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
+    //glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
+    //glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
+    glUniform1f(glGetUniformLocation(shader.id, "ticks"),(float)ticks);
+    //printf("%i\n",note);
+    glUniform1i(glGetUniformLocation(shader.id, "program"),note-36);
     if (shader.new) {
       createShader();
       glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height); // important!!
@@ -273,7 +333,8 @@ int main(int argc, char **argv) {
     glfwPollEvents();
   }
 
-  pthread_cancel(stdin_t);
+  //pthread_cancel(stdin_t);
+  pthread_cancel(midiin_t);
   pthread_cancel(frag_t);
   glfwDestroyWindow(window);
   glfwTerminate();