Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Zren/1ebe58c118193d2dd5f7 to your computer and use it in GitHub Desktop.
Save Zren/1ebe58c118193d2dd5f7 to your computer and use it in GitHub Desktop.

SoundCloud Theme for Foobar2000 Waveform Seekbar

Installation

  • Install the Waveform Seekbar for foobar2000.
  • Right click the Waveform Seekbar widget > Configure
  • Under Downmix Display choose Mix-down to mono.
  • Colors
    • Background: RGB 42, 42, 42
    • Foreground: RGB 200, 200, 200
    • Highlight: RGB 255, 128, 0
    • Selection: RGB 255, 128, 0
  • Choose the Direct3D frontend.
  • Click on Frontend Settings and paste the following script into it.
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 shadePlayed : 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);
}
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( float2 tc ) {
// alpha 1 indicates biased texture
float4 minmaxrms = tex1D(sTex, tc.x);
minmaxrms.rgb -= 0.5 * minmaxrms.a;
minmaxrms.rgb *= 0.9 + minmaxrms.a;
float below = tc.y - minmaxrms.r;
float above = tc.y - minmaxrms.g;
float factor = min(abs(below), abs(above));
bool outside = (below < 0 || above > 0);
bool inside_rms = abs(tc.y) <= minmaxrms.b;
if (outside) {
return backgroundColor;
} else {
// 1 px bgColor for every 3 pixels (2px wide bars)
if ((int)(viewportSize.x * tc.x) % 3 > 0) {
if (shadePlayed) {
// Apply selectionColor as a gradient upto the current play position or the mouse if it's more left when seeking.
// Apply selectionColor as an overlayed gradient upto the position that's more right.
float4 c = textColor;
float4 shadowColor = highlightColor - 0.2;
float fullAlphaPos = seeking ? min(cursorPos, seekPos.x) : cursorPos;
float halfAlhpaPos = seeking ? max(cursorPos, seekPos.x) : cursorPos;
if (fullAlphaPos > tc.x) {
// Apply gradient
float4 c = lerp(highlightColor, shadowColor, -tc.y);
return c;
} else if (halfAlhpaPos > tc.x) {
// Apply overlay gradient
float4 c = lerp(highlightColor, shadowColor, -tc.y);
c = lerp(c, textColor, 0.5);
return c;
} else {
return textColor;
}
} else {
return textColor;
}
} else {
return backgroundColor;
}
}
}
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 = 2.5 * dx;
float positionWidth = 2.5 * dx;
float4 c0 = evaluate(input.tc);
if (!shadePlayed) {
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();
}
}
@tripad
Copy link

tripad commented Nov 5, 2016

This is amazing! Thank you :D

@xeruf
Copy link

xeruf commented Jul 11, 2017

yei it works!
this one looks better: https://github.com/madhex/soundcloud-fb2k-waveform-seekbar but doesn't work for me :/
btw what is the use of the "Selection" color?
And would it be possible to add a padding on top and bottom?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment