Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: foo_wave_seekbar (Read 807473 times) previous topic - next topic
0 Members and 2 Guests are viewing this topic.

foo_wave_seekbar

Reply #1875
juniiflow: The way the component makes the waveforms is that it decodes the whole track and generates a set of data which the waveform image is drawn from. This takes some time and is around a second or two for a typical lossy track, simply because decoding a track at high speed can only run at like 400-1000x realtime.

In order to avoid doing this too often, the component caches the waveform data between times in a big database in the foobar2000 profile directory. You can trigger these scans manually by selecting some tracks and using the context menu to "extract seekbar signatures".

If the waveform is cached, you will get pretty much instant results.
Stay sane, exile.

foo_wave_seekbar

Reply #1876
Oh alright, thanks.
which one of these should I use to extract them? didn't really saw an extract option in configuration.
http://i.imgur.com/0ijp0nq.png

foo_wave_seekbar

Reply #1877
The context menu is the one that appears when you right-click, in this case on tracks in your playlist.
If your skin doesn't have context menus anymore, you can bind a key to it under Preferences.
http://imgur.com/kLTN97j
Stay sane, exile.

foo_wave_seekbar

Reply #1878
I took DeadSix27's seekbard shader from above and made it Zao-Rage-Proof. Thought I'd share:


(I'm using different colors than above, obviously)
Code: [Select]
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);
}
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 *= 1.0 + minmaxrms.a;

if (replayGain.g != -1000) {
          minmaxrms.rgb *= pow(10,(replayGain.g) / 20) * 2.5; //use track gain
  } else if (replayGain.r != -1000) {
          minmaxrms.rgb *= pow(10,(replayGain.r) / 20) * 2.5; //use album gain
  }

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);

//- - - - - ENABLE/DISABLE THE INSIDE WAVE - - - - - - - -
// [TO DISABLE: bool insideRms = 0;] [TO ENABLE: bool insideRms = diffRms < 0; <<<<<backup original]
//bool insideRms = diffRms < 0;
//bool insideRms = (belowWave > 0 && aboveWave < 0);
bool insideRms = (diffRms > 0 && diffRms < 0);

//- - - - - CHANGES LOOK OF INSIDE WAVE - - - - - - - -
//float factor = insideRms ? ( 1 + 0.2 * saturate(factorRms / border / 2)): 1.0; <<<<<backup original
float factor = insideRms ? ( 6 * saturate(factorRms / border / 20)): 10.0;

//- - - - - CHANGES LOOK OF OUTSIDE WAVE & PANEL BACKGROUND - - - - - - - -
//factor = insideWave ? (factor * saturate(factorWave / border / 1)) : 0.0; <<<<<backup original
factor = insideWave ? (factorRms * 6.0 + 0.8 * saturate(factorWave / border / 0.5)) : 0.0;

//return factor; <<<<<<backup original
return insideWave - saturate(factorWave);
}

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 = 3 * 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();
}
}
elevatorladylevitateme

foo_wave_seekbar

Reply #1879
<3
Stay sane, exile.


 

foo_wave_seekbar

Reply #1881
First of all thank you Zao for creating such a wonderful component!  I'm a total novice when it comes to shader coding and I was hoping someone here could help point me in the right direction.  What scripting language is being used?  Are there any simple examples that would be easy to break down and dissect? 

Thanks.
<3

foo_wave_seekbar

Reply #1882
The language used is HLSL, Microsoft's shader language for Direct3D 9. There's some documentation on MSDN about what functions there are and some on the syntax of the language.
As it's intended for 3D graphics, I am using it in a bit of a strange manner; more similiar to a full-screen post processing effect like bloom or tone mapping.

The way it works is that you have a pair of triangles covering the whole window pane. Each pixel that the triangles cover is run separately through the pixel shader (PS function in my effects).
The window has two value ranges stretched across it:
  • U goes from 0.0 on the left edge to 1.0 on the right edge. This lets us map the percentage across the window to the corresponding part of the waveform;
  • V goes from -1.0 on the lower edge to 1.0 on the upper edge. This is used to figure out how high we are, compared to the value stored in the waveform.


The simplest effect reads out the waveform sample for the corresponding part of the waveform, and checks if the current pixel is outside or inside the value, colouring it either with background colour or foreground colour.
The progress bar is drawn by figuring out if the current pixel is before, around, or after the current playback location.

It's a bit backwards compared to how you normally would draw things by putting pixels where you want them, to figuring out for all pixel locations what factors contribute to the colour for that location.
Stay sane, exile.

foo_wave_seekbar

Reply #1883
NO idea how to get it to work.  I'm sure I have all the necessary stuff installed.  I get no errors, but I also don't get anything to show up.  Couldn't find any place to turn it on in a menu.  I didn't see a step-by-step process anywhere, tried Googling it, and I'm sure as hell not going to spend another half an hour just trying to figure out how to get simple component/addition to Foobar's UI to appear on screen.  What are just the simple steps assuming someone has nothing installed to get this to show up?  Simply installing the necessary packages/files does nothing.

I'm on Windows 10 Pro 64-bit btw.  Thanks!

EDIT: Nvm, figured it out.  I needed to go into layout editing mode, create a subdivision, and add it (which in itself wasn't exactly the most straight-forward thing).  I've never done this before.

foo_wave_seekbar

Reply #1884
Nice to see that you figured it out.
I believe I've outlined in older posts in this thread somewhere, and possibly in the first post as well.
The HA wiki entry also mentions this towards the "Troubleshooting" section.
Stay sane, exile.

foo_wave_seekbar

Reply #1885
Hey all,

been using this component in D2D mode for a while now. Since DX never worked.
I have no idea what the problem is. I have an ATI 3450 card, which has pixel shader 4.1 and is definitely a DX9 card.
The DirectX runtimes are installed as well and when I check the configuration the selected frontend is "Direct3D 9.0c".
However, the graphics in the seekbar look very similar to the GDI. Clicking the "frontend button" doesn't do anything either.
Therefore I edited the seekbar.fx manually but with no result. The graphics stay the same. Any idea what the culprit could be here?

Cheers and thanks,

Stevie

foo_wave_seekbar

Reply #1886
All the configuration is stored inside the UI element instances themselves, and the initial effect comes from a DLL resource.
Any stray "seekbar.fx" files you have are probably from some early version or from some misguided theme.

As for the failure to open the frontend configuration dialog, it's probably the Scintilla control breaking due to multiple deregistration of window classes.

As for what you can try to do to diagnose/fix it, see if the thing works in a new fresh portable installation, without possibly conflicting components.
Stay sane, exile.

foo_wave_seekbar

Reply #1887
Hey Zoa! Thanks so much, it now works indeed. Did a complete re-install and that did it!

foo_wave_seekbar

Reply #1888
Found the culprit. It's the foo_uie_wsh_panel_mod. When removing it, Seekbar works also in DX mode!
The version was form 2010 by the way. I'll check for a newer one.


foo_wave_seekbar

Reply #1890
marc2003: Does that version of foo_wsh_panel_mod attempt to mitigate the Scintilla window class problem, because I don't think I do.

The core problem I and foosion ran into in the past was that Scintilla when failing to initialize multiple instances of itself, it unregisters the window class of the previous instance, breaking both.
The recommended workaround from the authors link here is to embed a manifest and use isolation-aware LoadLibrary, but I could never be arsed to get that working with foo_wave_seekbar.

Bonus fun is had from the foobar2000 order for loading components being indeterminate.
Stay sane, exile.


foo_wave_seekbar

Reply #1892
Ah, I guess it's easier if you static-link it. I've got mine as a DLL mostly due to wanting to reuse it between multiple frontends. Sadly that leads to ambitious end-users replacing the DLL.
Stay sane, exile.

foo_wave_seekbar

Reply #1893
By the way the unregister-after-failed-initialization bug was fixed in Scintilla 3.5.1.

foo_wave_seekbar

Reply #1894
Zao, is there a way to "normalize" the waveform, no matter how soft or loud the track is? I just want to have a detailed view of the waveform.

foo_wave_seekbar

Reply #1895
If you are using the current (0.2.45.*) version, there are two semantics exposed to the Direct3D9 effect that may be of use.

TRACKMAGNITUDE and CHANNELMAGNITUDE both contains the most negative peak (X), most positive peak (Y) and highest RMS value (Z).

You'd declare them much like the seek position and the other data up top.
Code: [Select]
float4 mag : TRACKMAGNITUDE;


As for something built-in that sneakily normalizes behind the back of frontends, nope, no such thing.
Stay sane, exile.

foo_wave_seekbar

Reply #1896
Thanks Zao!

I took the example from this post here https://www.hydrogenaud.io/forums/index.php...st&p=855915
Worked perfectly!

Whereas, I just realized that there is no "magnitude" in the script, however it still works. Apparently this is due to the fact, that my old script did not take ReplayGain into account

foo_wave_seekbar

Reply #1897
This may be a silly question, but is my GPU supposed to be running at full-speed (clocks to the max, like if I was in-game) while using D3D or D2D (GDI doesn't produce this)? It's a GTX 970

foo_wave_seekbar

Reply #1898
If your drivers follow the popular belief that there's two kinds of workload "lightweight 2D" and "3D", you're likely to get clocks corresponding to the latter as my component both increases timer precision and rapidly draws up to a configurable framerate cap. As for Direct2D triggering it, the underlying technology behind the MS curtains is a Direct3D.

I don't know what the detection triggers on.
Stay sane, exile.

foo_wave_seekbar

Reply #1899
If your drivers follow the popular belief that there's two kinds of workload "lightweight 2D" and "3D", you're likely to get clocks corresponding to the latter as my component both increases timer precision and rapidly draws up to a configurable framerate cap. As for Direct2D triggering it, the underlying technology behind the MS curtains is a Direct3D.

I don't know what the detection triggers on.


Oh, I see. I MAY have found a workaround. I created a profile under Manage 3D settings for nvidia's driver and particularly, there is an option called "Power management mode", which many gamers suggest as setting to "prefer maximum performance" for gaming. I changed this so that Foobar uses "Adaptive" and now it isn't clocking to the max of my GPU:



(this is as compared to having my clocks at the max: 1114/1753 and thus the temp at about 60 °C