From c5ab5f73490f6a5d80af2fdb1c7321cbea363227 Mon Sep 17 00:00:00 2001 From: Markus Walther Date: Sun, 31 May 2020 16:16:23 +0100 Subject: [PATCH 1/6] wip --- README.md | 2 +- examples/03demo_translate.clj | 4 ++-- examples/disco.glsl | 8 +++---- examples/implicit_fn.glsl | 6 ++--- examples/quasicrystal.glsl | 2 +- examples/raymarching1.glsl | 4 ++-- examples/redFrik.glsl | 8 +++---- examples/simple.glsl | 2 +- examples/simplecube.glsl | 2 +- examples/simpletex.glsl | 4 ++-- examples/simpletexa.glsl | 4 ++-- examples/sine_dance.glsl | 2 +- examples/spectrograph.glsl | 4 ++-- examples/vihart_braid.glsl | 8 +++---- examples/zoomwave.glsl | 2 +- src/shadertone/shader.clj | 16 ++++++++----- test/shadertone/shader_test.clj | 40 ++++++++++++++++----------------- test/shadertone/simple.glsl | 2 +- test/shadertone/tone_test.clj | 8 +++---- 19 files changed, 66 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 79f39a7..8f0fc90 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ shader. ``` uniform vec3 iResolution; // viewport resolution (in pixels) -uniform float iGlobalTime; // shader playback time (in seconds) +uniform float iTime; // shader playback time (in seconds) uniform float iChannelTime[4]; // channel playback time (in seconds) uniform vec3 iChannelResolution[4]; // channel width, height, 1 uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click diff --git a/examples/03demo_translate.clj b/examples/03demo_translate.clj index 7fea589..65bb395 100644 --- a/examples/03demo_translate.clj +++ b/examples/03demo_translate.clj @@ -5,10 +5,10 @@ ;; translate this Clojure-like code to a GLSL shader (trans/defshader simple '((uniform vec3 iResolution) - (uniform float iGlobalTime) + (uniform float iTime) (defn void main [] (setq vec2 uv (/ gl_FragCoord.xy iResolution.xy)) - (setq float b (abs (sin iGlobalTime))) + (setq float b (abs (sin iTime))) (setq gl_FragColor (vec4 uv.x uv.y b 1.0))))) ;;(print simple) diff --git a/examples/disco.glsl b/examples/disco.glsl index ce7a657..51d6778 100644 --- a/examples/disco.glsl +++ b/examples/disco.glsl @@ -18,15 +18,15 @@ void main(void) float v2 = 0.1 + 0.5*hz(800); float v3 = 0.1 + 0.5*hz(8000); vec3 col = vec3(0.0, 0.0, 0.0); - float v1x = uv.x + sin(5.0*iGlobalTime + 1.5*uv.y)*v1; - float v2x = uv.x + 0.5 + sin(3.0*iGlobalTime + 0.8*uv.y)*v1; - float v3x = uv.x - 0.5 + sin(7.0*iGlobalTime + 3.2*uv.y)*v1; + float v1x = uv.x + sin(5.0*iTime + 1.5*uv.y)*v1; + float v2x = uv.x + 0.5 + sin(3.0*iTime + 0.8*uv.y)*v1; + float v3x = uv.x - 0.5 + sin(7.0*iTime + 3.2*uv.y)*v1; col += vec3(1.0,0.0,1.0) * abs(0.066/v1x) * v1; col += vec3(1.0,1.0,0.0) * abs(0.066/v2x) * v2; col += vec3(0.0,1.0,1.0) * abs(0.066/v3x) * v3; // with a lighted disco floor pattern - float uvy2 = 0.25*iGlobalTime-uv.y; + float uvy2 = 0.25*iTime-uv.y; float a1 = max(0.0,0.25*hz(200)) * max(0.0,min(1.0,sin(10.0*uv.x)*sin(10.0*uvy2))); col += vec3(1.0,1.0,1.0) * a1; diff --git a/examples/implicit_fn.glsl b/examples/implicit_fn.glsl index 85876f4..c161faa 100644 --- a/examples/implicit_fn.glsl +++ b/examples/implicit_fn.glsl @@ -87,7 +87,7 @@ vec3 color4(vec2 rt) vec3 color5(vec2 rt) { float u = fract2(abs(fn(rt))); - float v = fract2(iGlobalTime/50); + float v = fract2(iTime/50); return texture2D(iChannel0,vec2(u,v)).xyz; } // ====================================================================== @@ -96,12 +96,12 @@ void main(void) { // select one vec2 uv = 3*getScreenUV(gl_FragCoord.xy); - //vec2 uv = 2.5*(0.1+fract2(iGlobalTime/5))*getScreenUV(gl_FragCoord.xy); // zoom! + //vec2 uv = 2.5*(0.1+fract2(iTime/5))*getScreenUV(gl_FragCoord.xy); // zoom! vec2 rt = getPolar(uv); // uncomment to spin... - //rt.y += iGlobalTime/4.0; + //rt.y += iTime/4.0; // Select one colorN routine at a time //vec3 c = vec3(uv.x,uv.y,0); // see x, y diff --git a/examples/quasicrystal.glsl b/examples/quasicrystal.glsl index 753f044..9dbb1c4 100644 --- a/examples/quasicrystal.glsl +++ b/examples/quasicrystal.glsl @@ -30,7 +30,7 @@ vec2 point(vec2 src) float wave(vec2 p, float th) { - float t = fract(iGlobalTime/tscale); + float t = fract(iTime/tscale); t *= 2.0 * PI; float sth = sin(th); float cth = cos(th); diff --git a/examples/raymarching1.glsl b/examples/raymarching1.glsl index ec6e51b..91cbae9 100644 --- a/examples/raymarching1.glsl +++ b/examples/raymarching1.glsl @@ -95,9 +95,9 @@ void main(void) vec2 window_pos = -1.0 + 2.0*(gl_FragCoord.xy/iResolution.xy); vec3 camera_up = vec3(0,1,0); vec3 camera_lookat = vec3(0,0,0); - vec3 camera_pos = vec3(5.0*cos(0.1*iGlobalTime), + vec3 camera_pos = vec3(5.0*cos(0.1*iTime), 5.0, - 5.0*sin(0.1*iGlobalTime)); + 5.0*sin(0.1*iTime)); vec3 light_pos = vec3(5.0,10.0,5.0); vec3 norm_camera_dir = normalize(camera_lookat-camera_pos); vec3 u = normalize(cross(camera_up,norm_camera_dir)); diff --git a/examples/redFrik.glsl b/examples/redFrik.glsl index e531a9f..01d9feb 100644 --- a/examples/redFrik.glsl +++ b/examples/redFrik.glsl @@ -3,16 +3,16 @@ uniform float t0; void main(void) { vec3 c = vec3(0.0); - float act = abs(cos(iGlobalTime)); + float act = abs(cos(iTime)); vec2 uv = gl_FragCoord.xy/iResolution.xy; float aspect = iResolution.x / iResolution.y; vec2 ar = vec2( (aspect < 1.0) ? 1.0/aspect : 1.0, (aspect < 1.0) ? 1.0 : 1.0/aspect); uv *= ar; - uv *= (3.0 + 2.0*sin(iGlobalTime/3.0)); + uv *= (3.0 + 2.0*sin(iTime/3.0)); for(int i = 0; i < 6; i++) { - vec2 xy = vec2(sin(iGlobalTime-11.0*abs(t0)+6.28*(i/6.0)), - cos(iGlobalTime+23.0*abs(t0)+6.28*(i/6.0))); + vec2 xy = vec2(sin(iTime-11.0*abs(t0)+6.28*(i/6.0)), + cos(iTime+23.0*abs(t0)+6.28*(i/6.0))); vec2 uv2 = uv - 2.0*ar + xy; float r = sqrt(uv2.x*uv2.x + uv2.y*uv2.y); c += (vec3(0.0,0.15*(1.0-act),0.1*(act)) * diff --git a/examples/simple.glsl b/examples/simple.glsl index 85c7d39..500c75f 100644 --- a/examples/simple.glsl +++ b/examples/simple.glsl @@ -11,6 +11,6 @@ void main(void) { float r = sqrt(uv2.x*uv2.x + uv2.y*uv2.y); gl_FragColor = vec4(uv.x, 20.0*iOvertoneVolume*(1-r), - 0.5*sin(3.0*iGlobalTime)+0.5, + 0.5*sin(3.0*iTime)+0.5, 1.0); } diff --git a/examples/simplecube.glsl b/examples/simplecube.glsl index 23f0710..3f11078 100644 --- a/examples/simplecube.glsl +++ b/examples/simplecube.glsl @@ -20,7 +20,7 @@ void main(void) { float roty = 0.0; float rotx = 0.0; if (iMouse.z <= 0.0) { - roty = iGlobalTime*0.25; + roty = iTime*0.25; } else { rotx = (mouse.y-0.5)*3.0; roty = -(mouse.x-0.5)*6.0; diff --git a/examples/simpletex.glsl b/examples/simpletex.glsl index 26a9695..39a11ac 100644 --- a/examples/simpletex.glsl +++ b/examples/simpletex.glsl @@ -6,8 +6,8 @@ uniform float iOvertoneVolume; void main(void) { vec2 uv = (gl_FragCoord.xy / iResolution.xy); - uv.x = uv.x + 0.5*sin(0.15*iGlobalTime); - uv.y = uv.y + 0.5*cos(0.03*iGlobalTime); + uv.x = uv.x + 0.5*sin(0.15*iTime); + uv.y = uv.y + 0.5*cos(0.03*iTime); vec4 c1 = texture2D(iChannel1,uv); vec4 c2 = texture2D(iChannel2,uv); vec4 c = mix(c1,c2,10.0*iOvertoneVolume); diff --git a/examples/simpletexa.glsl b/examples/simpletexa.glsl index afba4f6..d949aba 100644 --- a/examples/simpletexa.glsl +++ b/examples/simpletexa.glsl @@ -4,8 +4,8 @@ void main(void) { vec2 uv = (gl_FragCoord.xy / iResolution.xy); - uv.x = uv.x + 0.5*sin(0.15*iGlobalTime); - uv.y = uv.y + 0.5*cos(0.03*iGlobalTime); + uv.x = uv.x + 0.5*sin(0.15*iTime); + uv.y = uv.y + 0.5*cos(0.03*iTime); vec4 c1 = texture2D(iChannel0,uv); vec4 c2 = texture2D(iChannel1,uv); vec4 c = mix(c1,c2,1.0-c1.w); // alpha blend between two textures diff --git a/examples/sine_dance.glsl b/examples/sine_dance.glsl index 5b886cb..4088d45 100644 --- a/examples/sine_dance.glsl +++ b/examples/sine_dance.glsl @@ -8,7 +8,7 @@ void main(void) // equvalent to the video's spec.y, I think float spec_y = 0.01 + 5.0*iOvertoneVolume; float col = 0.0; - uv.x += sin(iGlobalTime * 6.0 + uv.y*1.5)*spec_y; + uv.x += sin(iTime * 6.0 + uv.y*1.5)*spec_y; col += abs(0.066/uv.x) * spec_y; gl_FragColor = vec4(col,col,col,1.0); } diff --git a/examples/spectrograph.glsl b/examples/spectrograph.glsl index 7e62f9f..52cecd9 100644 --- a/examples/spectrograph.glsl +++ b/examples/spectrograph.glsl @@ -50,10 +50,10 @@ void main(void) // But, we don't want the full screen to show the current FFT. We // want to only update the data under the cursor. So, we use the - // iGlobalTime input to find a particular X value for a column we + // iTime input to find a particular X value for a column we // want to update. The following creates a value that ranges from // [0,1024) over 30 seconds. - int cur_x = int(fract(iGlobalTime/SEC_PER_SCREEN)*iResolution.x); + int cur_x = int(fract(iTime/SEC_PER_SCREEN)*iResolution.x); // For the data that is NOT under the cursor, we want the older // sonogram data that we rendered into the framebuffer. get that diff --git a/examples/vihart_braid.glsl b/examples/vihart_braid.glsl index dfc84ec..10c2f97 100644 --- a/examples/vihart_braid.glsl +++ b/examples/vihart_braid.glsl @@ -1,5 +1,5 @@ uniform float v1, v2, v3; -//uniform float iGlobalTime; +//uniform float iTime; uniform float iOvertoneVolume; vec2 getScreenUV(vec2 fc) { @@ -35,9 +35,9 @@ void main(void) { vec3 c3 = get_dot(uv.x, uv.y, v3)*vec3(0.1, 0.5, 0.6); vec2 uv2 = (uv+1.0)/2.0; - uv2.y += 0.07 + 0.05*sin(iGlobalTime); - uv2.x += 0.008*sin(19.0*sin(uv2.y)*mod(iGlobalTime,8.0)); - //uv2.x += 0.004*noise1(iGlobalTime*3.0); + uv2.y += 0.07 + 0.05*sin(iTime); + uv2.x += 0.008*sin(19.0*sin(uv2.y)*mod(iTime,8.0)); + //uv2.x += 0.004*noise1(iTime*3.0); vec3 pc = 0.91*texture2D(iChannel0,uv2).rgb; vec3 c = c1 + c2 + c3 + pc; diff --git a/examples/zoomwave.glsl b/examples/zoomwave.glsl index 722a397..7340d3c 100644 --- a/examples/zoomwave.glsl +++ b/examples/zoomwave.glsl @@ -16,7 +16,7 @@ void main(void) vec2 uv = gl_FragCoord.xy/iResolution.xy; float wave = texture2D(iChannel0,vec2(uv.x,0.75)).x; wave = smoothbump(0.0,(6.0/iResolution.y), wave + uv.y - 0.5); - vec3 wc = wave*hsv2rgb(fract(iGlobalTime/2.0),0.9,0.9); + vec3 wc = wave*hsv2rgb(fract(iTime/2.0),0.9,0.9); // zoom into the previous frame float zf = -0.05; diff --git a/src/shadertone/shader.clj b/src/shadertone/shader.clj index cd7769f..b1c0132 100644 --- a/src/shadertone/shader.clj +++ b/src/shadertone/shader.clj @@ -136,9 +136,9 @@ [locals filename] (let [{:keys [tex-types]} @locals ;;file-str (slurp filename) - file-str (str "#version 120\n" + file-str (str "#version 140\n" "uniform vec3 iResolution;\n" - "uniform float iGlobalTime;\n" + "uniform float iTime;\n" "uniform float iChannelTime[4];\n" "uniform vec3 iChannelResolution[4];\n" "uniform vec4 iMouse;\n" @@ -231,9 +231,10 @@ :vertices-count vertices-count))) (def vs-shader - (str "#version 120\n" + (str "#version 140\n" + "in vec3 pos;\n" "void main(void) {\n" - " gl_Position = gl_Vertex;\n" + " gl_Position = vec4(pos, 1.0);\n" "}\n")) (defn- load-shader @@ -273,9 +274,12 @@ _ (when (== gl-link-status GL11/GL_FALSE) (println "ERROR: Linking Shaders:") (println (GL20/glGetProgramInfoLog pgm-id 10000))) + _ (except-gl-errors "@ let before EnableVertexAttribArray") + _ (GL20/glVertexAttribPointer 0, 4, GL11/GL_FLOAT, false, 16, 0) + _ (GL20/glEnableVertexAttribArray 0) _ (except-gl-errors "@ let before GetUniformLocation") i-resolution-loc (GL20/glGetUniformLocation pgm-id "iResolution") - i-global-time-loc (GL20/glGetUniformLocation pgm-id "iGlobalTime") + i-global-time-loc (GL20/glGetUniformLocation pgm-id "iTime") i-channel-time-loc (GL20/glGetUniformLocation pgm-id "iChannelTime") i-mouse-loc (GL20/glGetUniformLocation pgm-id "iMouse") i-channel0-loc (GL20/glGetUniformLocation pgm-id "iChannel0") @@ -505,7 +509,7 @@ (except-gl-errors "@ try-reload-shader useProgram2")) (let [_ (println "Reloading shader:" shader-filename) i-resolution-loc (GL20/glGetUniformLocation new-pgm-id "iResolution") - i-global-time-loc (GL20/glGetUniformLocation new-pgm-id "iGlobalTime") + i-global-time-loc (GL20/glGetUniformLocation new-pgm-id "iTime") i-channel-time-loc (GL20/glGetUniformLocation new-pgm-id "iChannelTime") i-mouse-loc (GL20/glGetUniformLocation new-pgm-id "iMouse") i-channel0-loc (GL20/glGetUniformLocation new-pgm-id "iChannel0") diff --git a/test/shadertone/shader_test.clj b/test/shadertone/shader_test.clj index 584262d..f617991 100644 --- a/test/shadertone/shader_test.clj +++ b/test/shadertone/shader_test.clj @@ -21,10 +21,10 @@ (testing "Simple program string acceptance test" (let [color (atom [1.0 0.5 0.0 1.0]) _ (s/start (atom " -uniform float iGlobalTime; +uniform float iTime; uniform vec4 iColor; void main(void) { - gl_FragColor = iColor * abs(sin(iGlobalTime)); + gl_FragColor = iColor * abs(sin(iTime)); }") :user-data { "iColor" color}) good-start (ask-user-tf "Did a pulsing orange window appear?") @@ -63,10 +63,10 @@ void main(void) { (testing "Simple fullscreen program string acceptance test" (let [color (atom [1.0 0.5 0.0 1.0]) _ (s/start-fullscreen (atom " -uniform float iGlobalTime; +uniform float iTime; uniform vec4 iColor; void main(void) { - gl_FragColor = iColor * abs(sin(iGlobalTime)); + gl_FragColor = iColor * abs(sin(iTime)); }") :user-data { "iColor" color}) good-start (ask-user-tf "Did a pulsing orange fullscreen window appear?") @@ -76,9 +76,9 @@ void main(void) { (deftest switch-str-test (testing "Test switching shaders" (let [shader-atom (atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,1.0,1.0,1.0) * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,1.0,1.0,1.0) * abs(sin(iTime)); }") _ (s/start shader-atom) good-start (ask-user-tf "Did a pulsing window appear?") @@ -88,9 +88,9 @@ void main(void) { }") good-start2 (ask-user-tf "Did a steady yellow window draw?") _ (reset! shader-atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,1.0,1.0,1.0) * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,1.0,1.0,1.0) * abs(sin(iTime)); }") good-start3 (ask-user-tf "Did the pulsing start again?") _ (s/stop)] @@ -99,22 +99,22 @@ void main(void) { (deftest error-str-test (testing "Test error handling" (let [shader-atom (atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,1.0,1.0,1.0) * noise * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,1.0,1.0,1.0) * noise * abs(sin(iTime)); }") _ (s/start shader-atom) good-start (ask-user-tf "Did an error occur? That is expected, but we should draw a black screen and not throw an exception.") _ (reset! shader-atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,1.0,1.0,1.0) * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,1.0,1.0,1.0) * abs(sin(iTime)); }") good-start2 (ask-user-tf "Did a pulsing window appear?") _ (reset! shader-atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,1.0,1.0,1.0) * noise * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,1.0,1.0,1.0) * noise * abs(sin(iTime)); }") good-start3 (ask-user-tf "Did another error occur? That is expected, but we should just keep playing the pulsing window.") _ (s/stop)] @@ -124,25 +124,25 @@ void main(void) { (testing "Test error handling with uniforms" (let [color (atom [1.0 0.5 0.0 1.0]) shader-atom (atom " -uniform float iGlobalTime; +uniform float iTime; //uniform vec4 iColor; void main(void) { - gl_FragColor = iColor * abs(sin(iGlobalTime)); + gl_FragColor = iColor * abs(sin(iTime)); }") _ (s/start shader-atom :user-data { "iColor" color}) good-start (ask-user-tf "Did an error occur? That is expected, but we should draw a black screen and not throw an exception.") _ (reset! shader-atom " -uniform float iGlobalTime; +uniform float iTime; uniform vec4 iColor; void main(void) { - gl_FragColor = iColor * abs(sin(iGlobalTime)); + gl_FragColor = iColor * abs(sin(iTime)); }") good-start2 (ask-user-tf "Did a pulsing orange window appear?") _ (reset! shader-atom " -uniform float iGlobalTime; +uniform float iTime; //uniform vec4 iColor; void main(void) { - gl_FragColor = iColor * abs(sin(iGlobalTime)); + gl_FragColor = iColor * abs(sin(iTime)); }") good-start3 (ask-user-tf "Did another error occur? That is expected, but we should just keep playing the pulsing window.") _ (s/stop)] diff --git a/test/shadertone/simple.glsl b/test/shadertone/simple.glsl index 8b8c333..c9244ac 100644 --- a/test/shadertone/simple.glsl +++ b/test/shadertone/simple.glsl @@ -1,4 +1,4 @@ void main(void) { vec2 uv = (gl_FragCoord.xy / iChannelResolution[0].xy); - gl_FragColor = texture2D(iChannel0,uv) * vec4(0.0,1.0,0.0,1.0) * abs(sin(iGlobalTime)); + gl_FragColor = texture2D(iChannel0,uv) * vec4(0.0,1.0,0.0,1.0) * abs(sin(iTime)); } diff --git a/test/shadertone/tone_test.clj b/test/shadertone/tone_test.clj index b9b4434..b2f3a44 100644 --- a/test/shadertone/tone_test.clj +++ b/test/shadertone/tone_test.clj @@ -31,9 +31,9 @@ (testing "Simple acceptance test" (let [s (simple-synth) _ (t/start (atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,0.5,0.0,1.0) * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,0.5,0.0,1.0) * abs(sin(iTime)); }")) good-start (ask-user-tf "Do you hear a siren-ish sound AND did a pulsing orange window appear?") _ (ctl s :gate 0) @@ -53,9 +53,9 @@ void main(void) { (testing "Simple acceptance test" (let [s (simple-synth) _ (t/start-fullscreen (atom " -uniform float iGlobalTime; +uniform float iTime; void main(void) { - gl_FragColor = vec4(1.0,0.5,0.0,1.0) * abs(sin(iGlobalTime)); + gl_FragColor = vec4(1.0,0.5,0.0,1.0) * abs(sin(iTime)); }")) good-start (ask-user-tf "Do you hear a siren-ish sound AND did a fullscreen pulsing orange window appear?") _ (ctl s :gate 0) From 5cf5550d0bb4f9f5b2c7e30e517b504b8734787a Mon Sep 17 00:00:00 2001 From: Markus Walther Date: Sat, 6 Jun 2020 14:21:31 +0100 Subject: [PATCH 2/6] wip: fix internal server on linux --- project.clj | 8 +++++--- src/shadertone/tone.clj | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/project.clj b/project.clj index 754f147..2811f05 100644 --- a/project.clj +++ b/project.clj @@ -4,10 +4,12 @@ :license {:name "MIT License" :url "https://github.com/overtone/shadertone/blob/master/LICENSE"} :dependencies [;; 1.6.0 causes error with *warn-on-reflection*. 1.7.0-RC1 works - [org.clojure/clojure "1.5.1"] + [org.clojure/clojure "1.10.1"] [hello_lwjgl/lwjgl "2.9.1"] - [overtone "0.9.1"] - [watchtower "0.1.1"]] + [overtone "0.10.7-SNAPSHOT"] + [watchtower "0.1.1"] + + [org.apache.commons/commons-math3 "3.6.1"]] :main ^{:skip-aot true} shadertone.core ;; add per WARNING: JVM argument TieredStopAtLevel=1 is active... :jvm-opts ^:replace [] diff --git a/src/shadertone/tone.clj b/src/shadertone/tone.clj index 0e7efaa..62998d9 100644 --- a/src/shadertone/tone.clj +++ b/src/shadertone/tone.clj @@ -94,6 +94,25 @@ (defonce fft-bus-synth (bus-freqs->buf [:after (foundation-monitor-group)] 0 fft-buf)) + + + +(def apache-fft + (org.apache.commons.math3.transform.FastFourierTransformer. org.apache.commons.math3.transform.DftNormalization/STANDARD)) + +(defn afft + [samples] + (let [n (count samples) + samples (into-array Double/TYPE samples)] + (->> samples + (#(.transform apache-fft % org.apache.commons.math3.transform.TransformType/FORWARD)) + (take (/ n 2)) + rest + (map #(* (/ 2.0 n) (.abs %))) + vec))) + +(afft (into-array Double/TYPE [0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1])) + ;; user-fn for shader display of waveform and fft (defn tone-fftwave-fn "The shader display will call this routine on every draw. Update From 272eb47c9870d45439d16acce0e4a7a62b5647b1 Mon Sep 17 00:00:00 2001 From: Markus Walther Date: Sat, 6 Jun 2020 21:30:10 +0100 Subject: [PATCH 3/6] wip example update --- examples/spectrograph.clj | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/examples/spectrograph.clj b/examples/spectrograph.clj index 51bdb4e..9a66cbf 100644 --- a/examples/spectrograph.clj +++ b/examples/spectrograph.clj @@ -2,12 +2,23 @@ (:require [overtone.live :as o] [shadertone.tone :as t])) -(t/start "examples/spectrograph.glsl" +(o/definst external [] (o/sound-in 0)) + +(external) + +(t/start "examples/spectrum2.glsl" + :title "Shadertone Spectrograph" + :width 420 :height 236 + ;; this puts the FFT data in iChannel0 and a texture of the + ;; previous frame in iChannel1 + :textures [:overtone-audio #_:previous-frame]) + +(t/start "examples/sound.glsl" :title "Shadertone Spectrograph" - :width 1024 :height 512 + :width 420 :height 236 ;; this puts the FFT data in iChannel0 and a texture of the ;; previous frame in iChannel1 - :textures [:overtone-audio :previous-frame]) + :textures [:overtone-audio #_:previous-frame]) ;; check out live microphone input (o/definst external [] (o/sound-in 0)) @@ -26,8 +37,12 @@ ;; testing precise frequencies (o/definst sn [n 1] (o/sin-osc (* n 5.4))) -(sn 16) +(sn 79) +(sn 78) +(sn 80) +(sn 81) (sn 128) (sn 256) ;; 2764.8 (sn 2048) ;; (* 5.4 2048) = 11k appears mid-screen +(sn 1024) ;; (* 5.4 2048) = 11k appears mid-screen (o/stop) From 0e8c0c4059c573b2c2a5e62f2bfa6c158241f4dd Mon Sep 17 00:00:00 2001 From: Markus Walther Date: Sat, 6 Jun 2020 21:47:37 +0100 Subject: [PATCH 4/6] getting pretty close --- src/shadertone/tone.clj | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/shadertone/tone.clj b/src/shadertone/tone.clj index 62998d9..d200429 100644 --- a/src/shadertone/tone.clj +++ b/src/shadertone/tone.clj @@ -26,23 +26,26 @@ ;; Grab Waveform & FFT data and send it to the iChannel[0] texture. ;; data capture fns cribbed from overtone/gui/scope.clj (defonce WAVE-BUF-SIZE 4096) ; stick to powers of 2 for fft and GL +(defonce FFT-BUF-SIZE (* 1 WAVE-BUF-SIZE)) ; stick to powers of 2 for fft and GL (defonce WAVE-BUF-SIZE-2X (* 2 WAVE-BUF-SIZE)) +(defonce FFT-BUF-SIZE-2X (* 2 WAVE-BUF-SIZE)) (defonce FFTWAVE-BUF-SIZE (* 2 WAVE-BUF-SIZE)) (defonce init-wave-array (float-array (repeat WAVE-BUF-SIZE 0.0))) -(defonce init-fft-array (float-array (repeat WAVE-BUF-SIZE 0.0))) +(defonce init-fft-array (float-array (repeat FFT-BUF-SIZE 0.0))) ;; synths pour data into these bufs (defonce wave-buf (buffer WAVE-BUF-SIZE)) -(defonce fft-buf (buffer WAVE-BUF-SIZE)) +(defonce fft-buf (buffer FFT-BUF-SIZE)) ;; on request from ogl, stuff wave-buf & fft-buf into fftwave-float-buf ;; and use that FloatBuffer for texturing (defonce fftwave-tex-id (atom 0)) (defonce fftwave-tex-num (atom 0)) (defonce fftwave-float-buf (-> ^FloatBuffer (BufferUtils/createFloatBuffer FFTWAVE-BUF-SIZE) - (.put ^floats init-fft-array) + (.put ^floats init-wave-array) (.put ^floats init-wave-array) (.flip))) (defonce wave-bus-synth (bus->buf [:after (foundation-monitor-group)] 0 wave-buf)) +;(defonce fft-bus-synth (bus->buf [:after (foundation-monitor-group)] 0 fft-buf)) (defn- ensure-internal-server! "Throws an exception if the server isn't internal - wave relies on @@ -72,23 +75,35 @@ ;; ;; http://www.physik.uni-wuerzburg.de/~praktiku/Anleitung/Fremde/ANO14.pdf (defsynth bus-freqs->buf - [in-bus 0 scope-buf 1 fft-buf-size WAVE-BUF-SIZE-2X rate 2] + [in-bus 0 scope-buf 1 fft-buf-size FFT-BUF-SIZE-2X rate 2] (let [phase (- 1 (* rate (reciprocal fft-buf-size))) fft-buf (local-buf fft-buf-size 1) ;; drop DC & nyquist samples n-samples (* 0.5 (- (buf-samples:ir fft-buf) 2)) signal (in in-bus 1) ;; found 0.5 window gave less periodic noise - freqs (fft fft-buf signal 0.5 HANN) + chain (fft fft-buf signal 0.5 HANN) + chain (pv-mag-smear chain 10) ;; indexer = 2, 4, 6, ..., N-4, N-2 indexer (+ n-samples 2 (* (lf-saw (/ rate (buf-dur:ir fft-buf)) phase) ;; what are limits to this rate? n-samples)) indexer (round indexer 2) ;; always point to the real sample ;; convert real,imag pairs to magnitude + s0 (buf-rd 1 fft-buf indexer 1 1) + ;s0 (* 0.00285 s0) s1 (buf-rd 1 fft-buf (+ 1 indexer) 1 1) ; kibit keep - lin-mag (sqrt (+ (* s0 s0) (* s1 s1)))] + lin-mag (sqrt (+ (* s0 s0) (* s1 s1))) + lin-mag (pow 10.0 (/ (* 10.0 (log2 s0 #_lin-mag)) 33.22)) + + ;lin-mag (buf-rd 1 fft-buf indexer 1 1) + ;s0 (* 0.00285 s0) +; lin-mag (+ 0 (* 0.02 (ampdb s0))) + ; dbify + ;lin-mag (pow 10.0 (/ (* 10.0 (log2 lin-mag)) 33.22)) + ;log-mag ;(* 2 (pow n-samples (lf-saw (/ rate (buf-dur:ir fft-buf)) phase 0.5 0.5))) + ] (record-buf lin-mag scope-buf))) (defonce fft-bus-synth From 8545fac418575fa2547112da829058ef113d0ec8 Mon Sep 17 00:00:00 2001 From: Markus Walther Date: Sat, 6 Jun 2020 21:53:27 +0100 Subject: [PATCH 5/6] got it but too loud --- src/shadertone/tone.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shadertone/tone.clj b/src/shadertone/tone.clj index d200429..12dcaaa 100644 --- a/src/shadertone/tone.clj +++ b/src/shadertone/tone.clj @@ -79,7 +79,7 @@ (let [phase (- 1 (* rate (reciprocal fft-buf-size))) fft-buf (local-buf fft-buf-size 1) ;; drop DC & nyquist samples - n-samples (* 0.5 (- (buf-samples:ir fft-buf) 2)) + n-samples (* 0.25 (- (buf-samples:ir fft-buf) 2)) signal (in in-bus 1) ;; found 0.5 window gave less periodic noise chain (fft fft-buf signal 0.5 HANN) From 86012996a9ac4036b494f3894309cbe8a15ec486 Mon Sep 17 00:00:00 2001 From: Markus Walther Date: Sun, 7 Jun 2020 00:01:38 +0100 Subject: [PATCH 6/6] wip: fix fft --- src/shadertone/tone.clj | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/shadertone/tone.clj b/src/shadertone/tone.clj index 12dcaaa..180e3cc 100644 --- a/src/shadertone/tone.clj +++ b/src/shadertone/tone.clj @@ -83,7 +83,7 @@ signal (in in-bus 1) ;; found 0.5 window gave less periodic noise chain (fft fft-buf signal 0.5 HANN) - chain (pv-mag-smear chain 10) + chain (pv-mag-smear chain 7) ;; indexer = 2, 4, 6, ..., N-4, N-2 indexer (+ n-samples 2 (* (lf-saw (/ rate (buf-dur:ir fft-buf)) phase) ;; what are limits to this rate? @@ -92,10 +92,14 @@ ;; convert real,imag pairs to magnitude s0 (buf-rd 1 fft-buf indexer 1 1) - ;s0 (* 0.00285 s0) - s1 (buf-rd 1 fft-buf (+ 1 indexer) 1 1) ; kibit keep - lin-mag (sqrt (+ (* s0 s0) (* s1 s1))) - lin-mag (pow 10.0 (/ (* 10.0 (log2 s0 #_lin-mag)) 33.22)) + s0 (* 0.03 s0) + lin-mag s0 +; s0 (* 0.285 s0) +; s0 (+ 0 (* 0.02 (ampdb s0))) +; s1 (buf-rd 1 fft-buf (+ 1 indexer) 1 1) ; kibit keep +; s1 (* 0.0285 s1) +; lin-mag (sqrt (+ (* s0 s0) (* s1 s1))) + lin-mag (pow 10.0 (/ (log10 lin-mag) 3.322)) ;lin-mag (buf-rd 1 fft-buf indexer 1 1) ;s0 (* 0.00285 s0)