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 802669 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

foo_wave_seekbar

Reply #1850
It'd have to be a new component, as otherwise the autoupdate would clobber 0.2 installations whenever it runs.
While moderately amusing, it's not quite beneficial to keeping legacy users happy.

As work on a new version of the component won't happen until after Windows 10 ships, the situation may have changed by then. My personal guess is that pretty much no XP user will even entertain the idea of migrating, being grumpy luddites.
Stay sane, exile.

foo_wave_seekbar

Reply #1851
Hi.
Is there any chance you could implement a DPI scaling to this plugin?
Have a look at this screenshot: http://i.imgur.com/ybClXR6.png
On my Ultra HD monitor, with windows scaling set to 200%, the waveform is stretched up. This also happens on my laptop with 150% scaling.
Foobar now supports dpi scaling, so does the columns_ui. It would be nice if this plugin did that as well.
Thanks.

foo_wave_seekbar

Reply #1852
Could you please indicate what part of the waveform that you feel isn't right?

Inspecting it in an image program, there are several locations where there are single-pixel features in the horizontal direction.
All gradients are single-pixel accurate as well.

I assume that you are objecting to the many two-pixel wide features in the waveform. These are likely due to that the dataset I store for a track is 2048 data points wide. Whenever you have a horizontal resolution wider than that, there will be duplication between adjacent pixels with the current set of filters, aiming to have the least distortion of the data.

This 2048 sample limit is rather fundamental in the current incarnation of the seekbar, so I will not change that. It may be possible to adjust filtering, but you did not mention which frontend you were using.
Stay sane, exile.

foo_wave_seekbar

Reply #1853
The front end I am using is GDI. I feel that some columns (not sure how it's called) should be 1 pixel wide, but I can only see 2 pixel wide ones.
Also, the resolution of my monitor is 3840x2160

foo_wave_seekbar

Reply #1854


Note how several pixel columns are 1-wide, while most are 2-wide. This is because your window is wider than the dataset, so most pixels will be sharing data with its neigbour.

As the dataset width is set in stone, the only thing one can do in the frontend is to sample with a different filter from the dataset. All filters have drawbacks, so you'd lose sharp peaks if you went for linear filtering, etc.

(and again, it has nothing to do with DPI awareness... that's all sorted out since the D2D clusterhug)
Stay sane, exile.

foo_wave_seekbar

Reply #1855


Other then that, i abseloutly adore this plugin.


foo_wave_seekbar

Reply #1857
In the danger of sounding like a idiot, is there a way to normalize the waveform to prevent the "complete fill" of the bar? (Sure is caused by the song being loud there, but yet again in the danger of sounding like a idiot, replaygain can't fix that either. E.g setting it to -16dB for example. Has no effect on the waveform at all)

As seen here:


foo_wave_seekbar

Reply #1858
If you are using the Direct3D 9.0c frontend, you can modify the effect to take replaygain into consideration, or add a uniform scale to samples after unbias.
Stay sane, exile.

foo_wave_seekbar

Reply #1859
If you are using the Direct3D 9.0c frontend, you can modify the effect to take replaygain into consideration, or add a uniform scale to samples after unbias.


Well found a variable controlling the max texture rgb i believe, never fiddled with shaders..

Original:


Edit:

foo_wave_seekbar

Reply #1860
Seems like you didn't break it too much. Probably. 
Stay sane, exile.


foo_wave_seekbar

Reply #1862
I recommend changing that to:
Code: [Select]
minmaxrms.rgb *= 1.0 + minmaxrms.a; // first unbias
minmaxrms.rgb *= 0.6; // then diminish

or if you're feeling compact:
Code: [Select]
minmaxrms.rgb *= 0.6 * (1.0 + minmaxrms.a); // unbias and diminish


The reason is because as mentioned earlier in this thread, the addition and scale there is to convert from a biased texture format into a balanced -1.0 to 1.0 value.

Your change makes the biased and unbiased formats differ in magnitude, while mine will not. If there's one thing I wish I did different in my original code, it would be to hide this in a function and have a nice customization point for amplitude manipulation.
Stay sane, exile.

foo_wave_seekbar

Reply #1863
I recommend changing that to:
Code: [Select]
minmaxrms.rgb *= 1.0 + minmaxrms.a; // first unbias
minmaxrms.rgb *= 0.6; // then diminish

or if you're feeling compact:
Code: [Select]
minmaxrms.rgb *= 0.6 * (1.0 + minmaxrms.a); // unbias and diminish


The reason is because as mentioned earlier in this thread, the addition and scale there is to convert from a biased texture format into a balanced -1.0 to 1.0 value.

Your change makes the biased and unbiased formats differ in magnitude, while mine will not. If there's one thing I wish I did different in my original code, it would be to hide this in a function and have a nice customization point for amplitude manipulation.


Guess that works too:

Code: [Select]
minmaxrms.rgb -= 0.5 * minmaxrms.a;
minmaxrms.rgb *= 1.0 + minmaxrms.a;
minmaxrms.rgb *= 0.6;


Same as

Code: [Select]
minmaxrms.rgb -= 0.5 * minmaxrms.a;
minmaxrms.rgb *= 0.6 * (1.0 + minmaxrms.a);




foo_wave_seekbar

Reply #1865
ok, found it in Columns UI topic, so much stuff there

Waveform Seekbar code for Post #1997 :
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 -= .1 * minmaxrms.a;

      //- - - - - CHANGES THE OVERALL WAVE SIZE IN THE PANEL - - - - - - - -
      //minmaxrms.rgb *= 0.8 + minmaxrms.a;  <<<<<backup original
        minmaxrms.rgb *= 0.95 + 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);

      //- - - - - 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 = 1 * 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();
  }
}

foo_wave_seekbar

Reply #1866
Do you people want to know what my biggest motivation is to work on v2? Eradicating that bloody unbias code once and for all.

EVERYONE breaks it by thinking it's just there for the lulz and twiddling the coefficients.
Stay sane, exile.

foo_wave_seekbar

Reply #1867
it was not my intention to show disrespect to your work, quite the opposite. i'm sorry if my post caused troubles.

foo_wave_seekbar

Reply #1868
I think Zao is mostly frustrated because the unbias code is a fixed piece of code which has to be included in all configurations. Fixed means that is not intended to be modified. Custom processing can be applied after the unbias operation. Yet many people are not aware of this and think the constants in the unbias code are just additional tuning parameters. Zao has expressed his regret about exposing this implementation detail on several occasions.

foo_wave_seekbar

Reply #1869
Well, if it is for any comfort, i promptly included (as author recommended above) unbias and diminish line (short), instead of original minmax.rms

Thanks, Zao.


foo_wave_seekbar

Reply #1871
Cannot edit so sorry for the double post. Was using this with 0.2.40. Does not render correctly in  0.2.45.

Quote
http://pastebin.com/xjQGqEbD

foo_wave_seekbar

Reply #1872
Code: [Select]
        float4 minmaxrms = tex.Sample(sTex, tc.x);

        // === This block
        minmaxrms.rgb -= 0.5 * minmaxrms.a;
        minmaxrms.rgb *= 1.0 + minmaxrms.a;
        // ===

        // === Must be before this block
        if (replayGain.g != -1000) {
                minmaxrms.rgb *= pow(10,(replayGain.g) / 20) * 1.5; //use track gain
        } else if (replayGain.r != -1000) {
                minmaxrms.rgb *= pow(10,(replayGain.r) / 20) * 1.75; //use album gain
        }
        // ===


In the linked code, RG correction is done before the mandatory unbias, and corrupts the data.

There may of course be other snafus, but this is a core one.
Stay sane, exile.

foo_wave_seekbar

Reply #1873
@Zao

Works fine now.

Thank you very much.

foo_wave_seekbar

Reply #1874
Is it normal for it to lag a little before the song starts? http://a.uguu.se/eafumq_2015-09-13-1908-15.mp4


I think what Wolfbane tried to ask was a way to automatically scale the waveform to fill the entirety of the available space without (or with minimal) clipping, when applicable.



So for songs like the top two, all is good. Some of them however produces waveforms as the bottom three (all of them has RG tags). Those could be scaled vertically to use all space available.

I'm obviously not using the default frontend and don't remember whether it produces similar results, so I could be totally wrong and might have misunderstood Wolfbane as well. It's just something that bothered me personally but never enough to actually address the 'issue'.


(The frontend I'm using, probably taken from somewhere in this topic:)
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;
float3 track_magnitude  : 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);

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, float cursorPos )
{
// alpha 1 indicates biased texture
float4 minmaxrms = tex1D(sTex, tc.x);
minmaxrms.rgb -= 0.5 * minmaxrms.a;
minmaxrms.rgb *= 1.0 + 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;
bool played = cursorPos < tc.x;
float4 inside_color = played ? textColor : highlightColor;
float4 bgColor = backgroundColor;

float4 wave = outside
? bgColor
: inside_color
;

return saturate(wave);
}

float4 reflect_evaluate( float2 tc, float cursorPos)
{
float baseline = -1.0/3.0;
float low_unscale = 3.0/2.0;
float high_unscale = 3.0/4.0;
bool mirrored = tc.y < baseline;
if (mirrored) {
tc.y = baseline - tc.y;
tc.y = tc.y * low_unscale;
}
else {
tc.y = tc.y - baseline;
tc.y = tc.y * high_unscale;
}
float mag = max(-track_magnitude.r, track_magnitude.g);
if (mag > 0.95) {
tc.y = lerp(0, mag/0.95, tc.y);
}
float boost = mirrored ? 1.3 : 1.0;
float gradient = lerp(0.7, 1.0, tc.y);
return boost * gradient * evaluate(tc, cursorPos);
}

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 = reflect_evaluate(input.tc, cursorPos);
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();
}
}
thanks for sharing