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 805759 times) previous topic - next topic
0 Members and 2 Guests are viewing this topic.

foo_wave_seekbar

Reply #1800
Up toward along with the viewport size and other stuff, you add
float4 trackmag : TRACKMAGNITUDE;

Then in the PS function, where input.tc is used, instead use input.tc / float2(1.0, max(abs(trackmag.r), abs(trackmag.g)))

When testing this in my default effect, the result was a bit airy, which I think is due to computing averages instead of min/max in my mipmaps or possibly due to it being very sensitive to spikes. Play around and see if it works satisfactory. If all else fails, introduce a bullshit factor
Stay sane, exile.

foo_wave_seekbar

Reply #1801
Thanks. Here's the code I'm trying to modify :

Code: [Select]
Texture1D tex : WAVEFORMDATA;
Texture2D seekTex < string filename = "seekbar.png"; >;

SamplerState sTex
{
Filter = MIN_MAG_MIP_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 shade_played : SHADEPLAYED;
float4 trackmag : TRACKMAGNITUDE;

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

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 grayscale( float4 color )
{
return color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
}

float4 sepia( float4 color )
{
float4 weight;
weight.r = 0.3;
weight.g = 0.59;
weight.b = 0.11;
weight.a = 0;

float4 adjust;
adjust.r = 0.098039215686275;
adjust.g = -0.050980392156863;
adjust.b = -0.26274509803922;
adjust.a = 0;

float intensity = dot(color, weight);
color = intensity + adjust;
return saturate(color);
}

float4 contrast( float4 color, float strength )
{
return saturate((color - 0.5) * strength + 0.5);
}

float4 played( float pos, float2 tc, float4 fg, float4 bg, float alpha)
{
float4 c = bg;
if (pos > tc.x)
{
#if 0
c = contrast(c, fg.r * 2);
c = lerp(c, sepia©, fg.g);
c = lerp(c, grayscale©, fg.b);
#else
c = grayscale©;
//c = sepia©;
#endif
}
return c;
}

float4 evaluate( float2 tc, float border )
{
// alpha 1 indicates biased texture
float4 minmaxrms = tex.Sample(sTex, tc.x);
//minmaxrms.rgb *= pow(10,(replayGain.g) / 20) * 2; //use track gain
minmaxrms.rgb -= 0.5 * minmaxrms.a;
minmaxrms.rgb *= 1.0 + 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.0 - 0.5 * saturate(factorRms / border / 2)): 1.0;
factor = insideWave ? (factor * saturate(factorWave / border / 2)) : 0.0;

float4 wave = lerp(backgroundColor, textColor, factor);

return saturate(wave);
}

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, 2.5 * dy);
if (shade_played)
c0 = played(cursorPos, input.tc, highlightColor, c0, 0.3);
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();
}
}
I've added the float4 trackmag : TRACKMAGNITUDE; in the right place.
Then there are 8 occurrences of input.tc

Occurrences 1 to 4 are these :
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);


Occurrences 5 to 8 are these :
float4 c0 = evaluate(input.tc, 2.5 * dy);
if (shade_played)
c0 = played(cursorPos, input.tc, highlightColor, c0, 0.3);
c0 = bar(cursorPos, input.tc, selectionColor, c0, positionWidth, cursorVisible);
c0 = bar(seekPos, input.tc, selectionColor, c0, seekWidth, seeking );
return c0;


I've tried replacing occurrences 5 to 8 since they were in the PS function, but the result wasn't convincing. I was expecting at least all waveforms to have the same max magnitude, but it wasn't the case : I saw no difference vs. the previous, unmodified code.

Can somebody help here ? 

foo_wave_seekbar

Reply #1802
Either change the VS or the PS, and if you do the PS, avoid messing with things that are unrelated to waveform height like bars.

In any way, from what I gathered from the contents of the parameters, their values seem to be around 0.9-0.999 on most my tracks. You probably won't get a better metric  unless something a bit more "intelligent" is provided from the application.
Stay sane, exile.

foo_wave_seekbar

Reply #1803
I don't know how to change the VS (occurrences 1-4) since I don't know what input.tc.x (or input.tc.y) is... so if I just replace it with input.tc / float2(1.0, max(abs(trackmag.r), abs(trackmag.g))).x it doesn't work. 
I warned you that I'm not familiar with coding so please assume that I'm really not at ALL.
You're trying to give me interesting clues that I can't get instead of providing the code. That would be useful if I understood the tiniest bit about the code, which I simply DON'T.
Thanks for your understanding.

About the PS, I've tried changing occurrence 5 only, occurrence 6 only, and occurrences 5 and 6. It's always pretty much the same result, and it's nowhere near the 0.9-0.999 range (which would be enough for me).
FYI occurrence 6 seems to have no incidence at all. Occurrence 5... well, replacing input.tc with input.tc / float2(1.0, max(abs(trackmag.r), abs(trackmag.g))) makes it slightly... worse (smaller waveforms, and their relative magnitudes are always the same). I don't get it.

Here's a screen cap to prove it. I don't think this is in the 0.9-0.999 range, is it ?

foo_wave_seekbar

Reply #1804
A sample of -1.0 is negative digital fullscale and corresponds by default to the lower edge of the window. A sample of 1.0 is correspondingly the positive fullscale and maps to the upper edge.

The measures I mentioned (channel magnitude, track magnitude) finds the very lowest and highest peak in the track. All it takes is a single sample at fullscale amplitude to make the magnitude hit the ceiling. The rescale is doing exactly what is intended, the problem is determining the "min" and "max" values that would result in a visually pleasing display.

I've played around a bit more with ridiculously expensive shaders now to see what I can divine out of the data by looking at more or less of it, and at best I can get some pessimistic approximations that tend to cut off the biggest peaks by looking at all the datapoints of a smoothed version of the waveform. Below can be seen a lucky example, but it still cuts off things if used to scale the waveform instead of drawing red bars.

Stay sane, exile.

foo_wave_seekbar

Reply #1805
I understand what you're saying, that's exactly what I would have done myself (if I understood shaders of course) : cut off the biggest peaks with a smoothed version of the waveform.
The purpose here is not to have something "close to reality" anymore, but rather to have something "visually pleasing" as you just said. So yes, right now we are on the same page. Yay !

So, based on your new experience with those "ridiculously expensive shaders" (lol  ), will there be at some point some code that you'll be able to share, so I could finally modify my previous code (which I like very much) into something better ?
Thanks again for your time.

PS : still on the visual side, you could choose to limit the displayed waveform amplitude to +/- 0.98 or so, so there would be one or two pixels free at the top and bottom and we wouldn't have a visual impression of clipping. Just my two cents.

foo_wave_seekbar

Reply #1806
I can implement "any" measure envisionable, the problem is that I can't envision a good programmatic measure for "cutting off some peaks, but not some others, kind of".

What you essentially want is a visual analogue of ReplayGain on a heavily downsampled sequence. I've got no idea how to approach that.
Stay sane, exile.

foo_wave_seekbar

Reply #1807
From my small experience in waveforms and the way they are displayed on-screen, here's what I could humbly suggest :
- Find the number of peaks in a given waveform (let's say the top A% of the waveform, A being configurable, e.g. 5%). Let's call that number N.
- If N < L (L being a configurable limit), then treat them as exceptions/aberrations, so cut them off (don't take them into account for displaying the waveform)
- If N >=L then display everything

Playing around with A and L should to the trick for at least 95% of the waveforms, which is what we're expecting, right ?

foo_wave_seekbar

Reply #1808
Hi,

I love the seekbar and it's worked great in the past but I've changed my audio server setup to use DLNA.
I can manually click to extract the signature but it won't do it automatically. Am I missing a setting or is this expected?
(I've tested it and it does do it automatically for tracks on my local disk.)

I'm using MiniDLNA (shouldnt matter) on my server and UPnp/DLNA Renderer plugin for foobar.

Thanks for the help

foo_wave_seekbar

Reply #1809
Never really used it, but upnp smells like HTTP transport, and there's a blacklist for automatic scans in the component.
Stay sane, exile.

foo_wave_seekbar

Reply #1810
Alright, so is there no way it can be enabled?
Since it works fine if I manually click a track to extract the signature and it seems to remember it too.

foo_wave_seekbar

Reply #1811
https://github.com/zao/foo_wave_seekbar/blo...essFile.cc#L376 is the pattern that ends up matching forbidden sources.
https://github.com/zao/foo_wave_seekbar/blo...essFile.cc#L402 later ignores that test if it's user-requested.

Remote sources in general are not of known duration, particularly as it's the primary delivery method of streams. A carte blanche accept on HTTP streams would result in rather unpleasant results, so I don't really know how to handle this.

To be honest, if you're dealing with expensive sources like networked locations, I would probably lean towards it being only for user-initiated scans.
Stay sane, exile.

foo_wave_seekbar

Reply #1812
Okay I've tried to build foo_wave_seekbar but had some trouble with the dependencies (and the lack of experience with cmake). I wanted to do a quick test to see if it would work if I just ignored that forbidden check.
Anyway, could you maybe make an option so that it still tries to extract signatures from all sources automatically? For my use case it would be fine since I don't use lastfm or anything like that with foobar anyway.
I guess it would be even better if we know what kind of transport it is but I'm not sure how to find that out.

foo_wave_seekbar

Reply #1813
I don't expect anyone to manage to build my source. It requires my CMake-ified foobar2000_sdk, -DFB2K_COMPONENTS=foo_wave_seekbar, and an XP toolset. I don't know if _my_ source is fit for building anymore, it's a bit damaged by experiments.

In any way, it's a bit of a tricky thing. Some of those protocols are banned because they're properly broken while some are just there because automatic scanning would either be expensive (transfer limits on networking) or actively harmful (CDDA making drive eat itself). I'd say it's technically a bug that the plain broken ones can be overridden at all.

People doing CDDA is the reason why the user-initiated override is there at all, as if you have control over it, you can ensure you don't scan while playing.

As for actually solving your problem, splitting the formats into "broken" and "unsuitable", and an advanced pref for overriding would probably be the way.
Stay sane, exile.

foo_wave_seekbar

Reply #1814
Is there anything I can do to help with this?

foo_wave_seekbar

Reply #1815
Minor bug:

-> playback a track
-> monitor goes into standby mode during playback
-> track playback finishes (stopped) and monitor still in standby
-> bring monitor out of standby mode

Result: Waveform seekbar showing cursor at the position where monitor went into standby

Expected: No playback cursor shown + "Shade played" section cleared


Win8.1, foobar2000 1.3.3, Waveform Seekbar 0.2.45 (Direct3D)


Can you reproduce this Zao?

foo_wave_seekbar

Reply #1816
Minor bug:

-> playback a track
-> monitor goes into standby mode during playback
-> track playback finishes (stopped) and monitor still in standby
-> bring monitor out of standby mode

Result: Waveform seekbar showing cursor at the position where monitor went into standby

Expected: No playback cursor shown + "Shade played" section cleared


Win8.1, foobar2000 1.3.3, Waveform Seekbar 0.2.45 (Direct3D)


Can you reproduce this Zao?

Haven't tried, I don't run Windows 8, nor any monitor power saving on any of my machines.

On my MBP in Windows 7, with 0.2.33, there is no strange behavior after powersave dim+off of the monitor.
I used stop-after-current to stop after the playing track.

Edit: reproduced with 0.2.45 on the same setup. Yay.
Stay sane, exile.


foo_wave_seekbar

Reply #1818
The underlying problem, considering that at some point in time it has worked correctly enough, probably not that horribly hard.
Getting the codebase and the bugfix into a releasable shape? More work.

As it stands now, even if I work off the 0.2.45 branch, my machine can't build a working seekbar without fixing up a lot of things.
Stay sane, exile.

foo_wave_seekbar

Reply #1819
Ok. No big issue.

foo_wave_seekbar

Reply #1820
The idea for this component is awesome, it's a complete must for me and I simply couldn't envision a foobar without it.

However it looks like we're coming to a dead end, because more and more things can't be fixed without a complete rework of the component.
Zao would be the logical choice for that rework, but it looks like he doesn't have any spare time for that, and we are in a sort of status quo that has been going on for several years now.
So, would there be anyone else willing to take on that challenge ?

I'm sorry to say this, but I'm getting increasingly frustrated because this component could do so many more things in a better way, and right now we can only hope for somebody to do it.
I hope you won't find my comment offensive. I have the utmost respect for Zao, but I also would like things to speed up a bit if it were possible.
It's not Zao's fault, but the development of this component besides some bug fixes is now almost non-existent. We need it to evolve in a natural way, just like foobar itself evolves, right ?

Thanks in advance.

foo_wave_seekbar

Reply #1821
wcs13: It's not dead until the title of the forum topic gets an "abandoned/clownware" label. 
I've been spending a decent amount of thought-cycles on responsiveness via analysis pre-emption, and pondering on a friendlier, more composable way of specifying looks lately. I've also done the grunt work of getting it building again fresh from the 0.2.45 branch. I should probably make a write-up of the work on a blag somewhere or something.

As for the things that are not fixed or evolved or worked around, a lot of them are hidden in this thread among tons of support traffic. Significant amounts of booze would be required to look through it all and find the things that are actual actionable things and not already fixed. There's an issue tracker on Github, but I doubt that anyone but bb10 has found it 

In order to attempt to build the component, you roughly need the following:
  • Visual Studio 2010 Professional (or Express, if you can steal ATL headers);
  • Git
  • CMake 2.10 or so;
  • Boost 1.55, probably not too modified;
  • libuv, gone in next release;
  • DirectX SDK February 2010 (note that June 2010 will not compile existing shaders);
  • Scintilla.

Do a checkout of zao/foobar2000_sdk; in the foobar2000 subdirectory, check out zao/foo_wave_seekbar. In another directory, do an out-of-source build with:
cmake ^
-DFB2K_COMPONENTS=foo_wave_seekbar ^
-DCMAKE_PREFIX_PATH=Y:\location\of\dependencies ^
-G "Visual Studio 10 2010" ^
Y:\location\of\foobar2000_sdk
Stay sane, exile.

foo_wave_seekbar

Reply #1822
I have written a humongous blog post fleshing out the things alluded to in the previous post. Have fun reading through my ramblings.

A new direction for foo_wave_seekbar
Stay sane, exile.

foo_wave_seekbar

Reply #1823
I've read your blog. Looks awesome. I still have faith.


foo_wave_seekbar

Reply #1824
If you feel overly foolish and/or are insane, there's a test build available of 0.2.45.3. It has HiDPI fixes for Direct2D, significant work scheduling changes and some ability for VIP tracks to override bulk tracks.
Please report back any installation problems, scanning problems, playback problems, hangs, hitches, stutters and other undesirables.

A glimpse of foo_wave_seekbar progress
Stay sane, exile.