diff options
author | Christoph Helma <helma@in-silico.ch> | 2018-02-23 15:31:53 +0100 |
---|---|---|
committer | Christoph Helma <helma@in-silico.ch> | 2018-02-23 15:31:53 +0100 |
commit | cc569501de2559624cf4ee39d064881fbc6e8c25 (patch) | |
tree | 30ab41cf2c747017af361fdfe10482864d21165f /sv.c | |
parent | cbe481d6cb93cc87188d1f791296ba7e74a21b9b (diff) |
initial video recording
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 193 |
1 files changed, 60 insertions, 133 deletions
@@ -16,14 +16,13 @@ #define MIDICHK(stmt, msg) if((stmt) < 0) {puts("ERROR: "#msg); exit(1);} -int width = 1920; -int height = 1080; +int width = 1918; +int height = 1078; GLFWwindow* window; GLuint vertex; GLuint fragment; GLuint shaderProgram; GLuint backbuffer; -int bars; typedef struct Shad { GLuint id; @@ -37,26 +36,22 @@ Shader shader; typedef struct Img { GLuint id; char path[40]; - float ratio; int new; } Image; Image images[8]; -typedef struct Param { - float value; - int new; -} Parameter; +float params[4]; -Parameter params[4]; +int recording = 1; 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"); + 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"); } void screenshot() { @@ -149,21 +144,30 @@ void createShader() { glUseProgram(shader.id); }; +void imageUniforms(int i) { + glUniform1i(glGetUniformLocation(shader.id, "images")+i,i); + //glUniform1f(glGetUniformLocation(shader.id, "ratios")+i,images[i].ratio); +} + +void resize_callback(GLFWwindow* window, int w, int h) { + width = w; + height = h; + glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height); +} + void createWindow() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - window = glfwCreateWindow(width,height, "", glfwGetPrimaryMonitor(), NULL); + //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 imageUniforms(int i) { - glUniform1i(glGetUniformLocation(shader.id, "images")+i,i); - glUniform1f(glGetUniformLocation(shader.id, "ratios")+i,images[i].ratio); -} - void readImage(int i) { images[i].new = 1; @@ -172,7 +176,7 @@ void readImage(int i) { stbi_set_flip_vertically_on_load(1); unsigned char* pixels = stbi_load(images[i].path, &w, &h, &comp, STBI_rgb_alpha); - images[i].ratio = (float) w/h; + //images[i].ratio = (float) w/h; imageUniforms(i); glActiveTexture(GL_TEXTURE0+i); @@ -184,6 +188,8 @@ void readImage(int i) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); stbi_image_free(pixels); } @@ -192,27 +198,20 @@ void updateImages(int force) { for (int i = 0; i<8; i++) { if (images[i].new || force) { readImage(i); - printf("%s\n",images[i].path); images[i].new = 0; } } } -void updateParams(int force) { - glUniform1i(glGetUniformLocation(shader.id, "bars"), bars); +void updateParams() { for (int i = 0; i<4; i++) { - if (params[i].new || force) { - glUniform1f(glGetUniformLocation(shader.id, "params")+i, params[i].value); - params[i].new = 0; - } + glUniform1f(glGetUniformLocation(shader.id, "params")+i, params[i]); } } int ticks =0; int running = 0; -int idx[2] = {0,1}; -float vel[2] = {0,0}; -int program; +int program=0; void *readMidi() { midi_open(); @@ -221,113 +220,23 @@ void *readMidi() { snd_seq_event_input(seq_handle, &ev); if (ev->type == SND_SEQ_EVENT_NOTEON) { int note = ev->data.note.note; - int v = ev->data.note.velocity; - int i,j; - if (note < 48) { - i = 0; - j = note-36; - } - else { - i = 1; - j = note-48; - } - // only white keys - if (j == 0) { - idx[i] = 0; vel[i] = (float)v/127.0; - } - else if (j == 2) { - idx[i] = 1; vel[i] = (float)v/127.0; - } - else if (j == 4) { - idx[i] = 2; vel[i] = (float)v/127.0; - } - else if (j == 5) { - idx[i] = 3; vel[i] = (float)v/127.0; - } - else if (j == 7) { - idx[i] = 4; vel[i] = (float)v/127.0; - } - else if (j == 9) { - idx[i] = 5; vel[i] = (float)v/127.0; - } - else if (j == 11) { - idx[i] = 6; vel[i] = (float)v/127.0; - } - else if (j == 12) { - idx[i] = 7; vel[i] = (float)v/127.0; - } - - } - else if (ev->type == SND_SEQ_EVENT_NOTEOFF) { - int note = ev->data.note.note; - int i,j; - if (note < 48) { - i = 0; - j = note-36; - } - else { - i = 1; - j = note-48; - } - // only white keys - if (j == 0) { - idx[i] = 0; vel[i] = 0; - } - else if (j == 2) { - idx[i] = 1; vel[i] = 0; - } - else if (j == 4) { - idx[i] = 2; vel[i] = 0; - } - else if (j == 5) { - idx[i] = 3; vel[i] = 0; - } - else if (j == 7) { - idx[i] = 4; vel[i] = 0; - } - else if (j == 9) { - idx[i] = 5; vel[i] = 0; - } - else if (j == 11) { - idx[i] = 6; vel[i] = 0; - } - else if (j == 12) { - idx[i] = 7; vel[i] = 0; - } + if (note >= 36) program = note-36; } else if(ev->type == SND_SEQ_EVENT_CONTROLLER) { int p = ev->data.control.param; int v = ev->data.control.value; - if (p < 4) { - params[p].value = (float)v/127; - params[p].new = 1; - } - /* - printf("[%d] Control: %2x val(%2x)\n", ev->time.tick, - ev->data.control.param, - ev->data.control.value); - */ + if (p < 4) params[p] = (float)v/127.0; } - else if(ev->type == SND_SEQ_EVENT_PGMCHANGE) { - program = ev->data.control.value; - } - else if(ev->type == SND_SEQ_EVENT_SONGPOS) { + 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) { + else if(ev->type == SND_SEQ_EVENT_CLOCK) if (running == 1) ticks++; - } - //else - //printf("[%d] Unknown: Unhandled Event Received\n", ev->time.tick); } } @@ -355,36 +264,54 @@ int main(int argc, char **argv) { 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); 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(¤t_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, "time"),glfwGetTime()); + glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime()); glUniform1f(glGetUniformLocation(shader.id, "ticks"),(float)ticks); glUniform1i(glGetUniformLocation(shader.id, "program"),program); - for (int i = 0; i<2; i++) { - glUniform1i(glGetUniformLocation(shader.id, "idx")+i,idx[i]); - glUniform1f(glGetUniformLocation(shader.id, "vel")+i,vel[i]); - } if (shader.new) { createShader(); glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height); // important!! - for (int i = 0; i<4; i++) { imageUniforms(i); } - updateParams(1); + for (int i = 0; i<8; i++) { imageUniforms(i); } + updateParams(); shader.new = 0; } - updateImages(0); - updateParams(0); + updateParams(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glfwSwapBuffers(window); + if (recording) { + unsigned char buffer[width*height*4]; + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + fwrite(buffer, sizeof(int)*width*height, 1, ffmpeg); + } glfwPollEvents(); } - //pthread_cancel(stdin_t); + if (recording) pclose(ffmpeg); pthread_cancel(midiin_t); pthread_cancel(frag_t); glfwDestroyWindow(window); |