Skip to content

Instantly share code, notes, and snippets.

@undu
Created April 21, 2013 20:22
Show Gist options
  • Save undu/5430936 to your computer and use it in GitHub Desktop.
Save undu/5430936 to your computer and use it in GitHub Desktop.
Seekbar I use in foobar for the foo_wave_seekbar; It displays half the wave, with a double-width seeking bar.
texture tex : WAVEFORMDATA;
sampler sTex = sampler_state {
Texture = (tex);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Clamp;
};
struct VS_IN {
float2 pos : POSITION;
float2 tc : TEXCOORD0;
};
struct PS_IN {
float4 pos : SV_POSITION;
float2 tc : TEXCOORD0;
};
float4 backgroundColor : BACKGROUNDCOLOR;
float4 highlightColor : HIGHLIGHTCOLOR;
float4 selectionColor : SELECTIONCOLOR;
float4 textColor : TEXTCOLOR;
float cursorPos : CURSORPOSITION;
bool cursorVisible : CURSORVISIBLE;
float seekPos : SEEKPOSITION;
bool seeking : SEEKING;
float4 replayGain : REPLAYGAIN; // album gain, track gain, album peak, track peak
float2 viewportSize : VIEWPORTSIZE;
bool horizontal : ORIENTATION;
bool flipped : FLIPPED;
bool shade_played : SHADEPLAYED;
PS_IN VS( VS_IN input ) {
PS_IN output = (PS_IN)0;
float2 half_pixel = float2(1,-1) / viewportSize;
output.pos = float4(input.pos - half_pixel, 0, 1);
if (horizontal) {
output.tc = float2((input.tc.x + 1.0) / 2.0, input.tc.y);
output.tc.y = output.tc.y * 0.5 + 0.5;
}
else {
output.tc = float2((-input.tc.y + 1.0) / 2.0, input.tc.x);
}
if (flipped)
output.tc.x = 1.0 - output.tc.x;
return output;
}
float4 bar(float pos, float2 tc, float4 fg, float4 bg, float width, bool show) {
float dist = abs(pos - tc.x);
float4 c = (show && dist < width)
? lerp(fg, bg, smoothstep(0, width, dist))
: bg;
return c;
}
float4 evaluate(float4 bg, float4 fg, float factor) {
return saturate(lerp(bg, fg, factor));
}
float4 played(float pos, float2 tc, float4 bg, float factor) {
float4 c = bg;
if (pos > tc.x) {
c = evaluate(backgroundColor, highlightColor, factor);
}
return c;
}
float RMSfactor(float2 tc, float border) {
float4 minmaxrms = tex1D(sTex, tc.x);
minmaxrms.rgb -= 0.5 * minmaxrms.a;
minmaxrms.rgb *= 0.7 + minmaxrms.a;
float belowWave = tc.y + border - minmaxrms.r;
float aboveWave = tc.y - border - minmaxrms.g;
float factorWave = min(abs(belowWave), abs(aboveWave));
bool insideWave = (belowWave > 0 && aboveWave < 0);
float diffRms = abs(tc.y) - border - minmaxrms.b;
float factorRms = abs(diffRms);
bool insideRms = diffRms < 0;
float factor = insideRms ? (1.1 + 0.15 * saturate(factorRms / border)): 1.0;
factor = insideWave ? (factor * saturate(factorWave / border / 1)) : 0.0; //1 = max sharp
return factor;
}
float4 PS(PS_IN input) : SV_Target {
float dx, dy;
if (horizontal) {
dx = 1/viewportSize.x;
dy = 1/viewportSize.y;
}
else {
dx = 1/viewportSize.y;
dy = 1/viewportSize.x;
}
float seekWidth = 1 * dx;
float positionWidth = 2 * dx;
float factor = RMSfactor(input.tc, 2.5 * dy);
float4 c0 = evaluate(backgroundColor, textColor, factor);
if (shade_played)
c0 = played(cursorPos, input.tc, c0, factor);
c0 = bar(cursorPos, input.tc, selectionColor, c0, positionWidth, cursorVisible);
c0 = bar(seekPos, input.tc, selectionColor, c0, seekWidth, seeking );
return c0;
}
technique10 Render10 {
pass P0 {
SetGeometryShader( 0 );
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}
technique Render9 {
pass {
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment