Skip to content
Browse files
begin organizing by splitting things into files
add possibilities to have multiple play markers
add pixels -> notes conversion task by one or multiple workers
replace GLSL test code by something musically better
2.0 version is going on!
  • Loading branch information
grz0zrg committed Oct 2, 2016
1 parent f2a8411 commit 0fafec1cc796570f7851559724315c1e1077e9aa
Showing with 9,004 additions and 647 deletions.
  1. +35 −4
  2. +22 −4 css/app_fs.css
  3. +1 −1 css/wui/wui.min.css
  4. +23 −6 dist/fs.css
  5. +4,418 −286 dist/fs.js
  6. +3 −1 dist/fs.min.css
  7. +7 −7 dist/fs.min.js
  8. +29 −81 index.html
  9. +98 −255 js/app_fs.js
  10. +264 −0 js/audio.js
  11. +36 −0 js/widgets.js
  12. +69 −0 js/worker/notes_buffer.js
  13. +3,997 −0 js/wui/wui.js
  14. +2 −2 js/wui/wui.min.js
@@ -1,8 +1,39 @@
# fs
[GLSL powered HTML5 web audio spectral synthesizer](
# Fragment - GLSL driven spectral synthesizer

This is a web synthesizer which is driven by visuals generated by a fragment program written in GLSL, the first implementation (v1.0) was a quick proof of concept, i am working on the second version which will feature some powerful things which enabling people to create, share their own synthesizer, collaborate and compose.

You can read [this article]( for an explanation of the idea behind this synthesizer and for an in-depth look at the first implementation.

You can test the first version [here](

This make use of the [WUI](, [CodeMirror]( library

This was build with a not yet released live build system but the project can be built out of the box if you find a way to run a pre-processor on **js/app_fs.js** and **css/app_fs.css** files which look for the /*include filename*/ directive and include the file **filename** content.

This was built with a not yet released live build system (just a simple pre-processor looking for modifications and which executes programs when the build is finished) written with the Anubis language but the project can be built out of the box easily if you find a way to run a custom pre-processor on **js/app_fs.js** and **css/app_fs.css** files which look for the /*include filename*/ directive and include the file **filename** content.


Check ***app_fs.js*** for the entry point file (all other files are included in this file by a pre-processor).

The code is organized in a very specific way, an organization i found out and stayed with after doing multiple projects, everything is contained in a single file and all the application code is into a self-invoking function called ***FragmentSynth***, there is no app. code outside this function, since it would be a bit crazy to do all the work in a single file, a pre-processor is needed to allow different files to be included and used, to help organize the code there is different code sections for each files which are explained below.

For the entry point file, code sections are:

* ***Globals.*** : Code which override certain API behaviors.
* ***App. Includes.*** : Files needed by the application are included here.

For all the other files and the entry point file, code sections are:

* ***Fields.*** : All variables used by the file are initialized here in one go (var _first, _second etc...) and start with an underscore, an underscore is also used between each words.
* ***Functions.*** : All functions used by the file are initialized here and start with an underscore, functions name are in _camelCase.
* ***Init.*** : Initialization code, the code which will be executed when the app start.

There is an anonymous section at the start of the entry point file which is used to include all external libraries needed by the app.

These sections can be easily parsed to permit quick jump to specific code sections within a text editor.

Application variables start with an underscore, local variables does not start with an underscore.

Note: My pre-processor allow the include directive only into the entry point file because it would be completely chaotic to allow that into other files...
@@ -96,11 +96,11 @@ canvas {
.play-position-triangle {
width: 0;
height: 0;
left: -8px;
left: -10px;
position: absolute;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #90A800;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #90A800;

.code {
@@ -109,4 +109,22 @@ canvas {

.CodeMirror {
height: 100%;

.fs-load-indicator {
width: 16px;
height: 16px;

background-color: green;

position: absolute;

top: 2px;
right: 2px;

z-index: 2;

.fs-hide {
display: none;

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4,704 dist/fs.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -6,105 +6,53 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />

<link rel="shortcut icon" type="image/png" href="favicon.png" />
<title>Fragment Synthesizer by Julien Verneuil</title>

<title>Fragment - Synthesizer by Julien Verneuil</title>

<link rel="stylesheet" type="text/css" href="dist/fs.min.css"/>

<script type="x-webgl/x-vertex-shader" id="vertex-shader">
attribute vec2 position; void main() { gl_Position = vec4(position, 0, 1); }

<script type="x-webgl/x-fragment-shader" id="fragment-shader">
precision mediump float;

uniform float globalTime;
uniform vec2 resolution;

float hash( float n ) { return fract(sin(n)*753.5453123); }

float noise( in vec2 x )
vec2 p = floor(x);
vec2 f = fract(x);
f = f*f*(3.0-2.0*f);

float n = p.x + p.y*157.0;
return mix(
mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
mix( hash(n+157.0), hash(n+158.0),f.x),

float fbm(vec2 p, vec3 a)
float v = 0.0;
v += noise(p*a.x)*.5;
v += noise(p*a.y)/1.25;
v += noise(p*a.z)*.125;
return v;

vec3 drawLines( vec2 uv, vec3 fbmOffset, vec3 color1, vec3 color2 )
float timeVal = globalTime * 0.1;
vec3 finalColor = vec3( 0.0 );

for( int i=0; i < 6; ++i )
float indexAsFloat = float(i);
float amp = 100.0 + (indexAsFloat*7.0);
float period = 0.5 + (indexAsFloat+.001);
float thickness = 0.5;//mix( 0.9, 0.0, noise(uv*4.0) ) * 2.;
float t = abs( 0.9 / (sin(uv.x + fbm( uv + timeVal * period, fbmOffset)) * amp) * thickness );

finalColor += t * color2 * 0.6;

return finalColor;

void main()
vec2 uv = ( gl_FragCoord.xy / resolution.xy ) * 2.0 - 1.1;
uv.x *= resolution.x/resolution.y;
uv.xy = uv.yx;

float t = sin( globalTime ) * 0.5 + 0.5;

vec3 lineColor1 = vec3( 1, 1, 0 );
vec3 lineColor2 = vec3( cos(t * uv.x) - uv.x, t-uv.x, 0 );

vec3 finalColor = vec3(0.0);

float pulse = mix( 0.50, 0.8, t);

finalColor += drawLines( uv, vec3( 1.4, 0.0, 0.0), lineColor1, lineColor2 ) * pulse;
finalColor += drawLines( uv, vec3( 0.0, 0.8, 1.0), lineColor1, lineColor2 );

gl_FragColor = vec4( finalColor, 1.0 );
precision mediump float;

uniform float globalTime;
uniform vec2 iMouse;
uniform vec2 resolution;

#define M_PI 3.1415926535897932384626433832795
void main ()
vec2 uv = gl_FragCoord.xy / resolution.xy;
float x = (uv.x/0.09/0.5) + (globalTime/20.);
float y = (((uv.y+(sin(x)*cos(uv.y))/8000.)/globalTime)*18800./0.35) + (tan(uv.y)*10.);
if (uv.x > 0.5) y += 0.0108*(sin(x)+cos(y)*16.0);
y -= 0.01*sin(x);
if (uv.y < 0.2) y = 0.0;
if (uv.y > 0.7) y = 0.0;
x *= M_PI;
x+= iMouse.x;
gl_FragColor = vec4(tan(y)/M_PI/(48.0), tan(y)/M_PI/92.0, 0, cos(y));

<script type="text/javascript" src="dist/fs.min.js" defer></script>
<script type="text/javascript" src="dist/fs.js" defer></script>

<div id="fs_load_indicator" class="fs-load-indicator"></div>
<div id="fail" class="fail"></div>
<div id="canvas" class="canvas">
<div id="play_position_marker" class="play-position-marker">
<div class="play-position-triangle"></div>
<div id="canvas_container" class="canvas">
<div id="code" class="code"></div>
<div class="controller">
<div id="mst_slider" class="mst-slider"></div>
<div id="toolbar"></div>
<div id="play_position_slider" class="play-position-slider"></div>

0 comments on commit 0fafec1

Please sign in to comment.