summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--sv.c153
1 files changed, 79 insertions, 74 deletions
diff --git a/sv.c b/sv.c
index 2c48620..a7c01cd 100644
--- a/sv.c
+++ b/sv.c
@@ -18,6 +18,8 @@
 
 int width = 1918;
 int height = 1078;
+//int width = 800;
+//int height = 640;
 GLFWwindow* window;
 GLuint vertex;
 GLuint fragment;
@@ -43,16 +45,18 @@ Image images[8];
 
 float params[4];
 
-int recording = 1;
+int record = 0;
+int recording = 0;
+int fullscreen = 0;
 
-static snd_seq_t *seq_handle;
-static int in_port;
+FILE* ffmpeg;
 
-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, "SV"), "Could not set client name");
-  MIDICHK(in_port = snd_seq_create_simple_port(seq_handle, "sv:in", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION), "Could not open port");
-}
+static snd_seq_t *midi_seq;
+static int midiin;
+
+int ticks =0;
+int running = 0;
+int program=0;
 
 void screenshot() {
   unsigned char pixels[width*height*4];
@@ -155,19 +159,6 @@ void resize_callback(GLFWwindow* window, int w, int h) {
   glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height); 
 }
 
-void createWindow() {
-  glfwInit();
-  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
-  //glfwWindowHint(GLFW_DECORATED, GL_FALSE);
-  window = glfwCreateWindow(width,height, "sv", NULL, NULL);
-  //window = glfwCreateWindow(width,height, "", glfwGetPrimaryMonitor(), NULL);
-  //glfwSetWindowSizeCallback(window, resize_callback);
-  glfwMakeContextCurrent(window);
-  glfwSetKeyCallback(window, key_callback);
-  glfwSetErrorCallback(error_callback);
-  glewInit();
-}
-
 void readImage(int i) {
 
   images[i].new = 1;
@@ -194,30 +185,15 @@ void readImage(int i) {
   stbi_image_free(pixels);
 }
 
-void updateImages(int force) {
-  for (int i = 0; i<8; i++) {
-    if (images[i].new || force) {
-      readImage(i);
-      images[i].new = 0;
-    }
-  }
-}
-
-void updateParams() {
-  for (int i = 0; i<4; i++) {
-    glUniform1f(glGetUniformLocation(shader.id, "params")+i, params[i]);
-  }
-}
-
-int ticks =0;
-int running = 0;
-int program=0;
-
 void *readMidi() {
-  midi_open();
+
+  MIDICHK(snd_seq_open(&midi_seq, "default", SND_SEQ_OPEN_INPUT, 0), "Could not open sequencer");
+  MIDICHK(snd_seq_set_client_name(midi_seq, "SV"), "Could not set client name");
+  MIDICHK(midiin = snd_seq_create_simple_port(midi_seq, "sv:in", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION), "Could not open port");
+  
   while(1) {
     snd_seq_event_t *ev = NULL;
-    snd_seq_event_input(seq_handle, &ev);
+    snd_seq_event_input(midi_seq, &ev);
     if (ev->type == SND_SEQ_EVENT_NOTEON) {
       int note = ev->data.note.note;
       if (note >= 36) program = note-36;
@@ -229,14 +205,30 @@ void *readMidi() {
     }
     else if(ev->type == SND_SEQ_EVENT_SONGPOS)
       ticks = ev->data.control.value*24;
-    else if(ev->type == SND_SEQ_EVENT_START)
+    else if(ev->type == SND_SEQ_EVENT_START) {
       running = 1;
-    else if(ev->type == SND_SEQ_EVENT_STOP)
+      if (record) {
+        time_t current_time = time(NULL);
+        char output_file[25];
+        strftime(output_file, 25, "%Y-%m-%d_%H%M%S.mp4", localtime(&current_time));
+        const char* cmd = "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s 1918x1078 -i - "
+                        "-threads 0 -preset veryfast -y -pix_fmt yuv420p -c:v libx264 -crf 18 -vf vflip output.mp4";
+
+        ffmpeg = popen(cmd, "w");
+        recording = 1;
+      }
+    }
+    else if(ev->type == SND_SEQ_EVENT_STOP) {
       running = 0;
+      if (recording) {
+        recording = 0;
+        pclose(ffmpeg);
+      }
+    }
     else if(ev->type == SND_SEQ_EVENT_CONTINUE)
       running = 1;
     else if(ev->type == SND_SEQ_EVENT_CLOCK)
-      if (running == 1) ticks++;
+      if (running) ticks++;
   }
 }
 
@@ -251,56 +243,69 @@ void *watchShader() {
 
 int main(int argc, char **argv) {
 
-  createWindow();
+  // parse options
+  int opt;
+  while ((opt = getopt(argc, argv, "rf")) != -1) {
+    switch (opt) {
+      case 'r': record = 1; fullscreen = 1; break;
+      case 'f': fullscreen = 1; break;
+    }
+  }
+
+  for (int i = optind; i<argc; i++) {
+    strncpy(images[i-optind].path, argv[i],40);
+    images[i-optind].new = 1;
+  }
+
+  // createWindow
+  glfwInit();
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+  glfwWindowHint(GLFW_DECORATED, GL_FALSE);
+  if (fullscreen) {
+    window = glfwCreateWindow(width,height, "", glfwGetPrimaryMonitor(), NULL);
+  } else {
+    window = glfwCreateWindow(width,height, "sv", NULL, NULL);
+    glfwSetWindowSizeCallback(window, resize_callback);
+  }
+  glfwMakeContextCurrent(window);
+  glfwSetKeyCallback(window, key_callback);
+  glfwSetErrorCallback(error_callback);
+  glewInit();
+
   strncpy(shader.fragment,"shader.frag",40);
   shader.new = 1;
   unsigned int VAO;
   glGenVertexArrays(1, &VAO);
   glBindVertexArray(VAO);
-  for (int i = 1; i<argc; i++) {
-    strncpy(images[i-1].path, argv[i],40);
-    images[i-1].new = 1;
-  }
+
+  glfwGetWindowSize(window, &width, &height);
   glCreateTextures(GL_TEXTURE_2D,1,&backbuffer);
   glTextureStorage2D(backbuffer,1,GL_RGBA32F,width,height);
   glBindImageTexture(0,backbuffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
-  updateImages(0);
+  for (int i = 0; i<8; i++) {
+    readImage(i);
+    images[i].new = 0;
+  }
   
   pthread_t midiin_t;
   pthread_create(&midiin_t, NULL, readMidi, NULL);
   pthread_t frag_t;
   pthread_create(&frag_t, NULL, watchShader, NULL);
 
-  FILE* ffmpeg;
-  if (recording) {
-    //char* cmd;
-  printf("%ix%i\n",width,height);
-    time_t current_time = time(NULL);
-    char output_file[25];
-    strftime(output_file, 25, "%Y-%m-%d_%H%M%S.mp4", localtime(&current_time));
-    //printf(output_file);
-  const char* cmd = "ffmpeg -r 24 -f rawvideo -pix_fmt rgba -s 1918x1078 -i - "
-                  "-threads 0 -preset veryfast -y -pix_fmt yuv420p -c:v libx264 -crf 18 -vf vflip output.mp4";
-
-    printf(cmd);
-    ffmpeg = popen(cmd, "w");
-  /*
-    sprintf(cmd,"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %ix%i -i - -threads 0 -preset fast -y -pix_fmt yuv420p -crf 21 -vf vflip %s",width,height,output_file);
-    */
-  }
-
   while (!glfwWindowShouldClose(window)) {
-    glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
-    glUniform1f(glGetUniformLocation(shader.id, "ticks"),(float)ticks);
-    glUniform1i(glGetUniformLocation(shader.id, "program"),program);
     if (shader.new) {
       createShader();
       glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height); // important!!
       for (int i = 0; i<8; i++) { imageUniforms(i); }
-      updateParams();
       shader.new = 0;
     }
-    updateParams();
+    glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
+    glUniform1f(glGetUniformLocation(shader.id, "ticks"),(float)ticks);
+    glUniform1i(glGetUniformLocation(shader.id, "program"),program);
+    for (int i = 0; i<4; i++) {
+      glUniform1f(glGetUniformLocation(shader.id, "params")+i, params[i]);
+    }
+
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     glfwSwapBuffers(window);
     if (recording) {