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

foo_wave_seekbar

Reply #1625
I based my seeking off the stock DUI seekbar, which on all the files I tested jumped in one-minute steps. (it's a jump-to-conclusions-mat!)

Reith: The improvements that may cause your behaviour is either:
  • "only use RGBA8 textures instead of RGBA32F or RGB10A2"
  • "draw each channel in Direct3D 9 as a single triangle instead of a pair of triangles"
I'd have to test the code and see what happens, but I fear it may be related to which GPU you have. What GPU do you have?
Stay sane, exile.

foo_wave_seekbar

Reply #1626
i see the same issue using the code Reith linked to. i have an AMD 6850.

foo_wave_seekbar

Reply #1627
I have an NVIDIA GTX 760.

foo_wave_seekbar

Reply #1628
Ah, looking at the code the problem stands out like a sore thumb:

Code: [Select]
float RMSfactor( float2 tc, float border )
{
    // alpha 1 indicates biased texture
    float4 minmaxrms = tex.Sample(sTex, tc.x);
...
}

His code is missing the unbias code present in the original shaders, which makes it fail on non-float texture formats as those have a [0..255] or [0..4095] range.
The proper statements should be along the lines of:
Code: [Select]
    float4 minmaxrms = tex.Sample(sTex, tc.x);
    minmaxrms.rgb -= 0.5 * minmaxrms.a;
    minmaxrms.rgb *= 1.0 + minmaxrms.a;

Full effect: Removed, see fixed code in later post.
Stay sane, exile.

foo_wave_seekbar

Reply #1629
minmaxrms.rgb *= 1.0 + minmaxrms.a;


is that + a typo? it doesn't look right at all??

)



edited to include screenshots

foo_wave_seekbar

Reply #1630
The desired range is -1.0 to +1.0 which floating point textures hold natively.
A normalized 8-bit texture holds values from 0.0 to +1.0.
The reason it's there is to implement a branch by having some terms that conditionally do nothing.

Alpha is 0.0 in textures that already have the proper range, and 1.0 in textures that need adjustment.

Code: [Select]
f( c,a) = ( c - 0.5*a) * (1+a)

// floating [-1,1] a=0
f(-1,0) = (-1 - 0.5*0) * (1+0) = -1
f( 1,0) = ( 1 - 0.5*0) * (1+0) =  1

// biased [0,1] a=1
f( 0,1) = ( 0 - 0.5*1) * (1+1) = -0.5*2 = -1
f( 1,1) = ( 1 - 0.5*1) * (1+1) =  0.5*2 =  1

It's semantically equivalent to a conditional bias and scale:
Code: [Select]
if (a == 1) {
  c = (c - 0.5) * 2;
}
Stay sane, exile.

foo_wave_seekbar

Reply #1631
I may of course have screwed up some other logic in my less-tested 8-bit code path, or the effect may have some other assumptions in it.
Since 0.2.41, the only path there is is the A=1 8-bit biased path, so most of this hackery can be replaced with a static expression, unless I see a need to change it in the future.
Stay sane, exile.

foo_wave_seekbar

Reply #1632
i'm not going to pretend i understood any of that...

but i will just say i tested your code in version 0.40 of the component and the + is most definitely required. it does look pretty much the same as my .41 screenshot with the modification i posted.

anyway, thanks for the updates.

foo_wave_seekbar

Reply #1633
Ah, I didn't read the deranged code enough to spot the mutated unbias a few lines below.
It seems like the author has conflated unbiasing the input texture (which should always be done) with application of track/album gain.

Below should be an accurate rendition, in which I removed the double-work and removed the *1.8 factor in the RG computation I couldn't derive from anything.
Code: [Select]
Texture1D tex : WAVEFORMDATA;

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;

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 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 )
{
    // alpha 1 indicates biased texture
    float4 minmaxrms = tex.Sample(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); //use track gain
    } else if (replayGain.r != -1000) {
        minmaxrms.rgb *= pow(10,(replayGain.r) / 20); //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);
    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;

    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 = 2.5 * dx;
    float positionWidth = 2.5 * 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;
}

technique Render9
{
    pass
    {
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();
    }
}
Stay sane, exile.

foo_wave_seekbar

Reply #1634
Thanks, guys. It obviously looks a lot better, but some quiet tracks appear smaller now - is there a way to make it scale the waveform until the loudest part touches the inside edges like before?

EDIT: On second thought, I have no idea if that's what it was actually doing. Was it just the *1.8 factor you mentioned? Either way, it works now, which is all that matters.

foo_wave_seekbar

Reply #1635
The only thing that 0.2.41 changed regarding this is that it changed the fallback chain of RGBA16F -> RGB10A2 -> RGBA8 into just RGBA8 across the board as more precision than that isn't really needed for effects.

The effect-visible change of this change is that effects that previously were broken for anyone that lacked floating point textures is now broken for everyone.

Previous scaling by the CHANNELMAGNITUDE and TRACKMAGNITUDE semantics will continue to work as it used to.

They are float4 vectors with the X component containing the lowest signed amplitude of the channel/track, the Y component the highest signed amplitude and the Z component the highest recorded RMS value.
Stay sane, exile.

foo_wave_seekbar

Reply #1636
Where to swap channels in this code?
The front right channel is on top instead of front left channel, which is way inconvenient.

foo_wave_seekbar

Reply #1637
The effect is invoked once per channel with each channel configured in the Configure dialog.
The way you reorder channels is by clicking the channel name and using the "Move up"/"Move down" buttons to reorder them.
Stay sane, exile.

foo_wave_seekbar

Reply #1638
I know, but with this script (i don't know if its with Direct3D 9.0c at all) channels are swapped, but not with GDI or Direct2D 1.0.
So i guessed there's something wrong with this script or with Direct3D?

Edit: With other words: when i move the front right channel at the top of the list and front left below it it is displayed as front left on top and front right below in Direct3D (or this script only).

foo_wave_seekbar

Reply #1639
It would be the D3D frontend in general then as the addon have very limited ability to reorder. I'll take a look at it, probably flipped too many things getting them mirrored right.
Stay sane, exile.

foo_wave_seekbar

Reply #1640
  • Scrolling the bar seeks by a minute per notch.


Ciao Zao,

I've tested the problem and found the optimum for the seek with mouse-wheel.
It is 5 seconds per notch.
It is the best compromise between short tracks (<2min) and long tracks (>1h).
Please consider a correction of the code. Thanks.

Ciao Zao


foo_wave_seekbar

Reply #1641
I have implemented roughly the same intervals as the original seekbar for 0.2.42.  Tracks longer than around 14.5h for which the original DUI seekbar doesn't scroll-seek, I skip by 5h per wheel notch.
Code: [Select]
 1s:     0s -    21s (      21s)
 5s:    22s -  108s (    1m48s)
10s:  109s -  145s (    2m25s)
 1m:  146s -  872s (  14m32s)
 5m:  873s -  4362s ( 1h12m42s)
10m:  4363s -  8724s ( 2h25m24s)
30m:  8725s - 26174s ( 7h16m14s)
 1h: 26175s - 52349s (14h32m29s)
n/a: 52350s - \infty
Stay sane, exile.


foo_wave_seekbar

Reply #1643
I have implemented roughly the same intervals as the original seekbar for 0.2.42.  Tracks longer than around 14.5h for which the original DUI seekbar doesn't scroll-seek, I skip by 5h per wheel notch.
Code: [Select]
 1s:     0s -    21s (      21s)
 5s:    22s -  108s (    1m48s)
10s:  109s -  145s (    2m25s)
 1m:  146s -  872s (  14m32s)
 5m:  873s -  4362s ( 1h12m42s)
10m:  4363s -  8724s ( 2h25m24s)
30m:  8725s - 26174s ( 7h16m14s)
 1h: 26175s - 52349s (14h32m29s)
n/a: 52350s - \infty

I'm still getting 1min jumps for some tracks in the 2 to 3 min range with 0.2.42!?

On some other tracks it seems to work (10s jumps).

foo_wave_seekbar

Reply #1644
It seems to work as intended.

<2:25 10s
>2:25 1min

EDIT: For a track with 2:30 only two notches a 1min are needed to pass the track. Strange!
marc2003 figured out different boundaries:


eh? the default UI seekbar has variable steps which is why i suggested it. i even tested it just now....

it only steps by 1 second for tracks shorter than 30 seconds.
for anything between 0:30 and 2:32 it steps 5 seconds.
between 2:33 and 5:06> 10 seconds
5:07 to ?? > 1 minute steps...

i see there are 5 minute and 10 minute steps for really long files but i can't be bothered to figure out the boundaries for those.


EDIT2:
Steps of DUI seekbar:

Code: [Select]
1-50 1s
51-251 5s
252-507 10s
508-3000 1m
3000-? 5m


foo_wave_seekbar

Reply #1646
My measurements are based off filling a playlist with silence://X tracks and binary searching for the ones where the DUI seekbar changes behaviour. The table of measurements is correct based on my machine with a granularity of 1s.

However, this was all done with an UI of a particular size. It is possible that it varies based on factors like seekbar length, screen size, mouse configuration, player size, or moon phase.
Stay sane, exile.

foo_wave_seekbar

Reply #1647
OK, you are kidding. 

To be serious:

Improvement of the DUI seekbar algorithm:

Code: [Select]
1-50 1s
51-100 2s
101-250 5s
251-500 10s
501-1500 30s
1501-3000 1m
3001-6000 2m
6001-15000 5m
15001-30000 10m
30001-90000 30m


EDIT: Oh now I see, it depends on seekbar size. Really confusing.