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

foo_wave_seekbar

Reply #1150
That fails if he wants his HDD to be indexed by the media library but not scanned by the seekbar.


When "Analyse tracks not in the media library" is unchecked - it disables all signature creation even if invoked manually. Manually right clicking on a song in playlist > Utilities > Extract Seekbar Signature - does not build the seekbar signature if "Analyse tracks not in the media library" is unchecked.

I don't use the media library at all.

Thanks.

foo_wave_seekbar

Reply #1151
That's working as intended. If it's unchecked, all scanning, whether it's user-initiated or automatic is ignored on tracks that are not in the Media Library.
Stay sane, exile.

 

foo_wave_seekbar

Reply #1152
Hi! I just registered to share my seekbar setup. I wanted to make something that looks like soundcloud's seekbar.
I found a post from 2010 from the user Anomalous, and edited his code a bit so it works with seekbar 0.2.29. Here's what I got:



and here's the code from frontend settings:
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 *= 0.7 + 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.15 * saturate(factorRms / border / 2)): 1.0;
        factor = insideWave ? (factor * saturate(factorWave / border / 1)) : 0.0; //1 = max sharp
      
        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 = 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 #1153
I have a question, would it be possible to make foo_wave_seekbar not scan tracks rated 1?
I use foo_skip and tracks that is rated 1 is skipped and I usually have a large playlist, playing in random. So, sometimes a lot of skips, due to rating of 1, occur, leaving foo_wave_seekbar scanning many tracks in the background.

foo_wave_seekbar

Reply #1154
Hi, just registered to ask this:

Is it possible to cut the wave form in half? I do not mean to merge the two into a mono track. I like that already, but was wondering instead of the single track being a vertical mirror, if I could simply view the top half of this. To keep the baseline at the bottom, instead of the middle of the wave form.

If not, that's okay -- Just thought I'd ask. I tried searching through this thread but it is quite hefty and some parts quite old. Thank you!

foo_wave_seekbar

Reply #1155
If you're using the Direct3D frontend, you can kind of achieve a split in half by adding in the evaluate() function the line:
tc.y = tc.y * 0.5 + 0.5;
This will shift the waveform so that the center is along the bottom edge of that channel. It's not quite right as it discards the lower half of the track, but meh, close enough.

Historically there was an option for mirroring and halving, but it hasn't been in for many versions and can't really be retrofitted.
Stay sane, exile.

foo_wave_seekbar

Reply #1156
Hm, I'm not very good with code, but pasting that in my only evaluate function that I found, it produced an error.

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 *= 0.7 + 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.15 * saturate(factorRms / border / 2)): 1.0;
        factor = insideWave ? (factor * saturate(factorWave / border / 1)) : 0.0; //1 = max sharp
      
        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 = 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();
    }
}


I got this from an earlier post, about sound cloud something. I placed it where it has

Code: [Select]
float4 evaluate(float4 bg, float4 fg, float factor)
{
        return saturate(lerp(bg, fg, factor));
}


and it came up with the error "error: (X3004): undeclared identifier 'tc'"

foo_wave_seekbar

Reply #1157
Unless you say otherwise, I have to assume you're using the default look.
Do it at the top of RMSFactor, I guess. Heaven knows what this shader does.
Stay sane, exile.

foo_wave_seekbar

Reply #1158
ah wow, you're a genius  that worked! good job and thank you xD

foo_wave_seekbar

Reply #1159
Hi!
Would it be possible to add scrollwheel function working on top of the waveform seekbar?
I like to use scrollwheel on top of the Seekbar, but it takes up space.
Thanks!

foo_wave_seekbar

Reply #1160
I'm a little confused how to get waveform seekbar to display what I want. I've played around with a few of the configs that have been posted here, and I'm happy with how it's displayed. But not with the amplitude of the display. To be clear the problem is not with the component (that's great), the problem here is me.

As far as replay gain is concerned my music library is divided into 2:
  • Loose (individual tracks): MP3's which have been permanently MP3Gained and have no RG data for fb2k to read
  • Tracks that are part of a collection: TAK /lossyTAK  complete albums or sonatas, symphonies etc ...) These tracks have been ReplayGained by fb2k.
The player is set to play according to Album Gain. So the loose files play at their "native" volume; the Collection tracks play according to their Album Gain data.

What I want Waveform Seekbar to produce is a waveform that reflects the waveform I hear.

Here's my current config:


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;
   
    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);
    if (replayGain.g != -1000) {
        minmaxrms.rgb *= pow(10,(replayGain.g) / 20) * 2; //use track gain
    } else if (replayGain.r != -1000) {
        minmaxrms.rgb *= pow(10,(replayGain.r) / 20) * 2; //use album 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;
         
            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 = 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();
            }
    }
Any ideas how I achieve this?
EDIT: Currently the Collection tracks (via AlbumGain) are displayed so they look much louder than the no-replaygain (loose tracks).

Any help much appreciated.

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

foo_wave_seekbar

Reply #1161
By the way - add me to the list of people who'd like to specify the location of wavecache.db.

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

foo_wave_seekbar

Reply #1162
By the way - add me to the list of people who'd like to specify the location of wavecache.db.


pretty sure you can do that yourself using the command line tool mklink which is built into windows (vista and newer).

foo_wave_seekbar

Reply #1163
pretty sure you can do that yourself using the command line tool mklink which is built into windows (vista and newer).

Done. Thanks for that. Learn something new every day.

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

foo_wave_seekbar

Reply #1164
Yeah, if all you want is a single file elsewhere, a symlink will probably work, but it's nothing I've tested, so buyer beware and all that.

As for the lack of implementing movability in the component itself, it needs UI work, file move logic and of course, got intermingled with "having multiple databases all over the place".
Stay sane, exile.

foo_wave_seekbar

Reply #1165
Hi Zao,

It works fine for me, no problems with the symlink. I think it may introduce a very slight delay, but that could also be because fb2k is on an SSD and now the wavecache.db resides on a normal sata HDD.

By the way, any advice on the replay gain / display issue mentioned in post 1161?

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

foo_wave_seekbar

Reply #1166
It's most likely quite trivial to achieve based on the contents of the four components of the replaygain variable. Do some branching, scale stuff, pray.

I took a short look at it but my shader editor is so horrible, I lost the work
Stay sane, exile.

foo_wave_seekbar

Reply #1167
Does anyone know how to make the waveform a solid color?  I set the foreground color but it only affects the top and bottom edges of the waveform.

e.g.



Why is the waveform still white with shades of the foreground color?  Thanks.

foo_wave_seekbar

Reply #1168
Because the default effect interpolates from the background color outside the waveform, into the foreground color at the waveform border, and past inside. If you want a different behavior, you can always write your own effect.
Stay sane, exile.

foo_wave_seekbar

Reply #1169
Okay and how do I do that?  Thank you.

foo_wave_seekbar

Reply #1170
Hi Zao,
thank you for the nice component. it really adds some nice eyecandy.
however i have a problem. when im playing computer games with foobar in the background
the cpu usage of foobar spikes and introduces lags in the game. this happens when the track
changes to a track without a cached waveform. is there a way to make waveform generation
less priorotized? i already have only one thread running.

foo_wave_seekbar

Reply #1171
The analysis threads are running at idle CPU priority already. I am not going to open the can of worms that is going conditionally for THREAD_MODE_BACKGROUND_BEGIN/THREAD_MODE_BACKGROUND_END on Vista and up, as that's likely to cause enough stalling and priority inversion to ruin the day.
Stay sane, exile.

foo_wave_seekbar

Reply #1172
Thank you, maybe it's something different that's slowing me down. thanks for the nice plugin still

foo_wave_seekbar

Reply #1173
I created playlist with about 1300 tracks/50GBytes, all from the same HDD. Maybe half of them were previously played and thus they could have their seekbars signatures already saved. I selected all of them and choose "extract seekbar signature". I changed coligation of foobar process to just single core (3,6 Ghz AMD Phenom). Whole procedure took about 20 or 30 minutes (I don't know exactly, I haven't noticed exact time). While seekbar signatures were extracted, foobar was normally playing music from that playlist. During whole this process CPU usage varied mainly from 12 to 17% and never went above 19%. Maybe there's something wrong with your HDD configuration (in BIOS or Windows?) - like slower transfer mode set?

foo_wave_seekbar

Reply #1174
Resource usage is more complicated than a single percentage of resources consumed.

I/O is a big silent thief in performance, it has a tendency to stutter and delay things subtly, which I referred indirectly to by the THREAD_MODE_BACKGROUND_* priorities. Those affect the I/O behavior of a thread, unlike the usual priorities that are mostly just about CPU scheduling.

I'm not eager to touch I/O priority though, as it may very well end up ruining it for everyone.
Stay sane, exile.