     return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
 }
 
+// Alpha-compsite two colors, putting one on top of the other
 vec4 composite(vec4 under, vec4 over) {
     float a_out = 1. - (1. - over.a) * (1. - under.a);
     return clamp(vec4((over.rgb * over.a  + under.rgb * under.a * (1. - over.a)) / a_out, a_out), vec4(0.), vec4(1.));
 }
 
-float rounded_rect_df(vec2 center, vec2 size, float radius) {
-    return length(max(abs(gl_FragCoord.xy - center) - size, 0.0)) - radius;
+// Sawtooth wave
+float sawtooth(float x, float t_up) {
+    x = mod(x + t_up, 1.);
+    return x / t_up * step(x, t_up) +
+           (1. - x) / (1 - t_up) * (1. - step(x, t_up));
 }
 
-vec3 dataColor(ivec3 data) {
-    return vec3(data) / vec3(255.);
-}
-
-float inBox(vec2 coord, vec2 bottomLeft, vec2 topRight) {
-    vec2 a = step(bottomLeft, coord) - step(topRight, coord);
-    return a.x * a.y;
-}
-
-float smoothBox(vec2 coord, vec2 bottomLeft, vec2 topRight, float width) {
-    vec2 a = smoothstep(bottomLeft, bottomLeft + vec2(width), coord) - smoothstep(topRight - vec2(width), topRight, coord);
-    return min(a.x, a.y);
-}
-
+// Predictable randomness
 float rand(float c){
     return fract(sin(c * 12.9898) * 43758.5453);
 }

#version 130

uniform bool iLeftOnTop;
uniform bool iSelection;
uniform float iAudioHi;
uniform float iAudioLow;
uniform float iAudioMid;
uniform float iAudioLevel;
uniform float iIntensity;
uniform float iIntensityIntegral;
uniform float iTime;
uniform float iFPS;
uniform int iBins;
uniform int iLeftDeckSelector;
uniform int iLength;
uniform int iPatternIndex;
uniform int iRightDeckSelector;
uniform int iSelected;
uniform int iIndicator;
uniform sampler1D iSpectrum;
uniform sampler1D iWaveform;
uniform sampler1D iBeats;
uniform sampler2D iChannel[3];
uniform sampler2D iFrame;
uniform sampler2D iFrameLeft;
uniform sampler2D iFrameRight;
uniform sampler2D iPreview;
uniform sampler2D iStrips;
uniform sampler2D iTexture;
uniform sampler2D iText;
uniform sampler2D iName;
uniform vec2 iPosition;
uniform vec2 iResolution;
uniform vec2 iTextResolution;
uniform vec2 iNameResolution;

#define M_PI 3.1415926535897932384626433832795

vec3 rgb2hsv(vec3 c) {
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));

    return mix(y1, y2, xyz.z);
}

//
// The following is only used for UI; not for patterns
//

uniform bool iLeftOnTop;
uniform bool iSelection;
uniform int iBins;
uniform int iLeftDeckSelector;
uniform int iLength;
uniform int iPatternIndex;
uniform int iRightDeckSelector;
uniform int iSelected;
uniform int iIndicator;
uniform sampler1D iSpectrum;
uniform sampler1D iWaveform;
uniform sampler1D iBeats;
uniform sampler2D iFrameLeft;
uniform sampler2D iFrameRight;
uniform sampler2D iPreview;
uniform sampler2D iStrips;
uniform sampler2D iTexture;
uniform sampler2D iText;
uniform sampler2D iName;
uniform vec2 iPosition;
uniform vec2 iTextResolution;
uniform vec2 iNameResolution;

float rounded_rect_df(vec2 center, vec2 size, float radius) {
    return length(max(abs(gl_FragCoord.xy - center) - size, 0.0)) - radius;
}

vec3 dataColor(ivec3 data) {
    return vec3(data) / vec3(255.);
}

float inBox(vec2 coord, vec2 bottomLeft, vec2 topRight) {
    vec2 a = step(bottomLeft, coord) - step(topRight, coord);
    return a.x * a.y;
}

float smoothBox(vec2 coord, vec2 bottomLeft, vec2 topRight, float width) {
    vec2 a = smoothstep(bottomLeft, bottomLeft + vec2(width), coord) - smoothstep(topRight - vec2(width), topRight, coord);
    return min(a.x, a.y);
}
#line 0
