0
0

Awhile back I posted some comments and concerns about looking for a nice visual display for music. I got so sick of the standard pcm line displays and simple bargraphs.

After alot of fooling and screwing around I managed to create something which I consider looks pretty sharp and is pretty fast. [url=http://www.gamingbattleleague.com/beta/gplayer.gif:z5r0231t]Take a peek here[/url:z5r0231t] and let me know what you think. Its amazingly easy to add to any project, simply pass to the dll the ‘rect’ location that you want it to display, fill out some data in a structure (user defined type), and call some functions over a period of time.

If anyone is interested give me a dingle over email.

++Cire.

  • You must to post comments
0
0

I’m not a Winamp fond. If I was a winamp fond, I didn’t ever make my own player. I just said that because I think it’s easier to support for who (like me) made a player with winamp vis support, instead of using a separate dll. However, if you don’t want to make it, just don’t make it. I was never talking about doing a plugin for Winamp to be used with Winamp!

  • You must to post comments
0
0

Every time I open your program and press the + button I get an illegal operation error with GVISUAL.DLL. Here’s the details:

GPLAYER caused an invalid page fault in
module GVISUAL.DLL at 017f:00b91040.
Registers:
EAX=0064fa78 CS=017f EIP=00b91040 EFLGS=00010202
EBX=0064fa90 SS=0187 ESP=0064f8d4 EBP=00000113
ECX=00000000 DS=0187 ESI=00cb0ec0 FS=39df
EDX=00008ad0 ES=0187 EDI=00000000 GS=1caf
Bytes at CS:EIP:
80 39 00 75 03 32 c0 c3 8b 41 04 50 8b 08 ff 51
Stack dump:
00b94171 0064fa44 00008ab4 0064fa90 0064f8ec bff70187 0064fa78 00b9a4b8 ffffffff 00b92d25 00000001 00401e88 00000002 00008ab4 0064fa5c 0000000c

  • You must to post comments
0
0

oops, it’s handbags at dawn for these two :)

  • You must to post comments
0
0

[quote="Cire":2pz7sjsu]Winamp is starting to move more and more towards spyware and I’am not fond of that crap.[/quote:2pz7sjsu]

You mean the optional AOL icon in the setup? That’s only because AOL bought out Nullsoft… so NS is a subsidiary of AOL now. I mean, the AOL icon is the closest thing to spyware in the entire installation, and not even that comes close (especially considering that it [b:2pz7sjsu]is[/b:2pz7sjsu] optional–NS was much nicer than most AOL subsidiaries to do that).

  • You must to post comments
0
0

Paranoid_Android, I think I found your problem. Please ensure that you are in 32 bit color mode and try it again. After reviewing the code I see that it does throw errors if your not in 32 bit color mode.

I’am still working on an update to the player which I entend to release soon.

++Cire.

  • You must to post comments
0
0

Paranoid_Android, do u have DirectX 8 or better installed? Can you give alittle info about your system?

Graduate Bruce 2002, no I mean that everything you do via winamp somehow ends backup at NullSofts database, be it playing a CD, or a mp3 or whatever.

++Cire.

  • You must to post comments
0
0

[url=http://www.gamingbattleleague.com/beta/ddgplayer.zip:rs398dr7]Updated GPlayer[/url:rs398dr7]. Try this version Paranoid_Android see if it gives you an error. This verison works in both 16 bit color as well as 32 bit color. I also added some __asm routines to speed a few routines up. It also has better type error protection. I’am working on the final part now which is a right click interface to a config file.

As always click on the visual display to see differet views. These different views are simple flags that you set. I’am still working on a conversion lib for VB users, as well as adding fonts and perfecting many of the routines with asm and boasting the speed by taking advantage of cpu features such as MMX and SSE chipsets, don’t worry because if the chipsets is not avilable it will have a scalear version like it is now.

So far for VB users the setup is pretty simple simply call an init function passing it a set of quards for it to create a child window and draw into, after initing simply set the effects and thier variables and then simply call the render dll passing it the spectrum, (it only needs a certain number of elments from the spectrum i can’t recall how many now however), and when your finihsed simply call the shutdown function, pretty simple, u can change the effects on the fly. I have tested the vb lib pretty exensivly and with promsing outputs.

I will be releasing the C++ code, and vb libs as soon as i have it finished, which requires font handling and dialog handling to adjust visual variables. Please provide any feed back. Please keep in mind that the entire visual is variable adjusted and effects can take different variables or be turned off totally.

++Cire.

  • You must to post comments
0
0

Hmm, that is interesting, I would be interested in seing the program! 😀 What do you use for the data? Spectrum data? Or something else?? But anyway, the visual looks pretty nice, is that the only visual you have made for it or are there others?? Thanks!

  • You must to post comments
0
0

Paranoid_Android, make sure you are also playing a mp3, wav, mod, xm, it, s3m, it files. The other formats I havn’t finished yet.

++Cire.

  • You must to post comments
0
0

Hey, it works a lot better now! When you told me that it only works in 32 bit mode, I went to see what mine was set to and found out that I had it in 24 bit. But all in all I like what you’ve done with the visuals, its really interesting.

  • You must to post comments
0
0

It is done via spectrum data. I use directdraw7 and do tripple back buffering to get the job done. The source code for the visual is in C++, the downside to it is that it is single threaded, and rendered by the application, that is to say that the application calls the render function inside the visual, so thus it could be run in another thread. I am still optomizing the code for more efficent rendering and adding confuration options. There are multiple views to the visual as well some of which are not shown in that area such as stardust, and roto-zoom effects as well as wave lighting, and dancing partcles.

On a side note I have begun work on a BPM detection algorthism, and will make avilable sources as soon as i have somethign decent.

++Cire.

  • You must to post comments
0
0

Heres my computer info:

Windows 98
Pentium 2 267 mhz
128 mb ram
DirectX 9

And im opening an MP3 file. The player works fine, but when I go into visual mode I get the error with gvisual.dll.

  • You must to post comments
0
0

That sounds interesting, I’ve been looking for a decent BPM counter and I was contemplating just writing a routine myself, but when i started to write the routine I found out that it wasnt very easy to do lol. Anyways, it sounds like the visual library needs a little work, but so far it looks good.

  • You must to post comments
0
0

Cire, I don’t think making a winamp plugin it’s a stupid thing. I was talking about winamp 2.xx, forget the shit of 3.xx version. Many of our players works great with winamp 2.xx plugins, so why some of us should embed code into out player or translate your code to fit into another language? Just made a standard working thing for everyone! So you can also update it if you need… I don’t think it’s quite stupid…

  • You must to post comments
0
0

Many people have asked me for simply the effects routines so I’am gona post them here. If you need more assistance then what is posted please let me know.

To begin with I calculate a set of magic variables from the specturm. I call these bass and trebel, both are float and, I calculate them as follows.
[code:1dbj2uh4]

define TREBLE 50

define TREBLE_MAX 16

define BASS_MAX 4

float ComputeTrebleLevel()
{
float TrebleAvg;
int x;
float *spec;

TrebleAvg = 0.0;
spec = VisMod.spectrumData;

for (x = TREBLE; x < TREBLE + TREBLE_MAX; x++) 
{
    TrebleAvg += spec[x];
}

return ((float)TrebleAvg / (float)TREBLE_MAX);

}

float ComputeBaseLevel()
{
float BassAvg;
int x;
float *spec;

spec = VisMod.spectrumData;
BassAvg = 0.0;

for (x = 0; x < BASS_MAX ; x++) 
{
    BassAvg += spec[x];
}

return ((float)BassAvg / (float)BASS_MAX);

}
[/code:1dbj2uh4]

Note that the above routines could be sped up using divions of 2 and byte shifting, however they should be pretty speedy and very simple to convert to VB.

Next is the most simplic effect in the visual which i simply call StarDust and basiclly just a set of random drawn pixels, I said before that i use direct draw to handle my routines, and I have written a set of classes which interface to direct draw, lock my buffers and what not for very speedy gfx, doing most of the routines below via gdi will be pretty fast except the final ones which acutally transform and blur the images.

Anyhow heres the StarDust routine.
[code:1dbj2uh4]
void GEffects::StarDust( GScreen *sImage, float TrebleLevel )
{
int x, y, MaxX;
GColorRGBA Color = RGB( 100,100,100 );

MaxX = (int)( NUM_SPARKS * TrebleLevel );

for (int i = 0; i < MaxX; i++) {
    x = (int)(rand() % (Width-10)  )+5;
    y = (int)(rand() % (Height-10) )+5;

    sImage->GetPixelPtr( x, y ) -> Blend256( Color, 128 );
}

}
[/code:1dbj2uh4]
The above routine pretty much just blends a bunch of random pixels on the screen. The number of sparks is based on the treble level. Blend256 acutally takes the value of the new color and merges it (128 which is half) with any color that might already be there, the result is a mix of the two colors. Note that i keep the pixels at 5 in and 5 less the the width and height.

The next effect that is rendered is called Dancing stars and is somewhat similar to StarDust except that we keep track of them, and move the around a bit each render. It should be pretty easy to understand.
[code:1dbj2uh4]
void GEffects::DancingStars( GScreen *sImage, float BaseLevel )
{
int i;
int XDir;
int YDir;
int Total;

Total = (int)((float)NUM_STARS * BaseLevel );
if (Total > NUM_STARS) 
    Total = NUM_STARS;

do 
{
    XDir = (rand() % 3) - 1;
    YDir = (rand() % 3) - 1;
} while (XDir == 0 && YDir == 0);

for (i = 0; i < Total; i++) 
{
    if( (i & 7) == 7 ) 
    {
        do 
        {
            XDir = (rand() % 3) - 1;
            YDir = (rand() % 3) - 1;
        } while (XDir == 0 && YDir == 0);
    }

    GColorRGBA Color;
    Color = DStars[i].c;

    DStars[i].x += XDir;
    DStars[i].y += YDir;

    if(sImage->IsInBounds (DStars[i].x, DStars[i].y) )
        sImage->GetPixelPtr( DStars[i].x, DStars[i].y )->Blend256( Color, 128 );
}

}
[/code:1dbj2uh4]

The Structure for a dancing star is as follows:
[code:1dbj2uh4]
struct STAR
{
float x;
float y;

COLORREF c;

};
[/code:1dbj2uh4]
You will need to initialize each star to a random x,y and color. I setup a random function to return a set of nice colors that i pre calculated ahead o time. You could allow them to go off screen and if so simply randomize another one at a different location on the screen however I like just limiting them to the surface.

This article is getting pretty long so I think i’ll continue in the next post.

  • You must to post comments
0
0

I chose against using winamp plugins for visuals for 1 main reason, winamp plugins are run seperataly in thier own window, and I like to have mine within my own window in a specified area of the display screen because I want to add video support to the player as well. Full screen will also be supported via visuals. Second is i’am not fond of winamp, i don’t like giants I find that they start off on the right hand and when they become big they get outa touch with reality and start adding tons of usless crap to thier apps and move away from the main goal that they created the app. For example Winamp was created to be a stable kick butt audio player which was fast, efficent and well put together. It has since started to move away from that to well I’ll stop right here.

Some of you maybe diehard winamp fans but I’am not, so i’ll leave it at that.

[b:74lw3wuj]Paranoid_Android:[/b:74lw3wuj]
I’am looking into the problem that you are experiencing, I’ve tested it on 3 other 98 machines that I have floating around here and none of them had any problems. However I will note that it is giving me some problems on w2k, maybe when I solve it there it will work for you. Untill then I’ll keep tring and let u know when I update the application for you to gve it a another try which should be in a day or two.

++Cire.

  • You must to post comments
0
0

The next effect I apply last but is short so I’ll post it now. This routine will be VERY slow if your attempting to replicate this via GDI. I strongly suggest that you look into DirectDraw or OpenGL.

The idea is to flash the screen when base and trebel are above a certain value (i do 0.9 and 0.9). Anyhow heres the routine.
[code:cpzpzgex]
void GEffects::BassFlash( GScreen *sImage )
{
GColorRGBA *Row;

for (unsigned __int32 y = 0; y < Height; y++)
{
    Row = sImage->GetRowPtr( y );
    for (unsigned __int32 x = 0; x < Width; x++)
    {
        Row->b = GetSine(RowPtr->b);
        Row->g = GetSine(RowPtr->g);
        Row->r = GetSine(RowPtr->r);

        Row++;
    }
}

return;

}
[/code:cpzpzgex]
You will have to setup your own GetSine table which recives a number form 0 to 255, and return a base value. Mine basically inverts the numbers so that a dim green (50) becomes 255. (ie brightest it can become) and a bright 255 becomes say 50, you can play with it its a rather cool effect but if you over use it, it will become acutally hard on the eyes.

Now were getting to some of the fun effects. This next routine is responsbile for drawing lines and pixels that eminate from the center of the visual and move outwards. The amout of the line, lenght of it and the amount of movement is all based on trebel and bass levels. This routine will again be a tough nut to handle via GDI espeically in VB where you can’t do a LineDDA callback.
[code:cpzpzgex]

define MAX_Z 2.0000f

define MIN_Z 0.0001f

define Z_INC 0.0050f

void GEffects::Starfield( GScreen *sImage, float BassLevel, float TrebleLevel )
{
int i;
float zinc;

zinc = Z_INC;
zinc *= (1.0f / ((BassLevel * 6.0f) + 0.001f));
zinc +=  (TrebleLevel / 3.0f);

for (i = 0; i < NUM_STARFIELD; i++)
{
    float x;
    float y;

    if( sImage->IsInBounds( StarField[i].oldx, StarField[i].oldy ) == false )
    {
        StarField[i].oldx = HalfWidth;
        StarField[i].oldy = HalfHeight;

        StarField[i].x = max(15*BassLevel,0.15f) * ((float)(rand() % Width) - HalfWidth );
        StarField[i].y = max(15*BassLevel,0.15f) * ((float)(rand() % Height) - HalfHeight );
        StarField[i].z = MIN_Z;

        StarField[i].c = PickDrawColor();
    } else {
        StarField[i].z += zinc;
    }

    if( StarField[i].z < MIN_Z )
        StarField[i].z = MIN_Z;

    x = StarField[i].x * StarField[i].z;
    y = StarField[i].y * StarField[i].z;

    float theta;
    float radius;
    POINT A, B;

    radius  = (float) sqrt (x*x + y*y);
    theta   = (float) atan2 ((float)y, (float)x);

    x = radius * (float)cos(theta);
    y = radius * (float)sin(theta);

    A.x  = StarField[i].oldx;
    A.y  = StarField[i].oldy;
    B.x  = (sint32)x + HalfWidth;
    B.y  = (sint32)y + HalfHeight;

    uint32 ArrayLen;
    POINT *Coords;

    Coords = GetLineCoords (A.x, A.y, B.x, B.y, &ArrayLen);

    GColorRGBA Color;
    Color = Stars[i].c;

    for (sint32 j = ArrayLen - 1; j >= 0; j--)
    {
        if(sImage->IsInBounds (Coords[j].x, Coords[j].y) )
            sImage->GetPixelPtr( Coords[j].x, Coords[j].y )->Blend256( Color, 128 );
    }

    FreeLineCoords (Coords);

    StarField[i].oldx = B.x;
    StarField[i].oldy = B.y;
}

}
[/code:cpzpzgex]
As You probably notice you’ll need to also have a structure for the StarField which is like this…
[code:cpzpzgex]
struct STARFIELD
{
float x;
float y;
float z;

unsigned __int32 oldx;
unsigned __int32 oldy;

COLORREF c;

};
[/code:cpzpzgex]
You’ll have to setup a intializing to int the number of lines in the starfield that is very similiar to how I setit up when it falls outa bounds.

Next we have an effect that toppels all the effects so far. This is the cream of the crop when it comes to effects. Basically the next effect takes a set of lines that revolve around some point, which will change based on the bass. The line lenght is based on the trebel and the movement is also bass and treble adjusted. To top it off the lines are also haltone drawn. That is to say they start bright and blend to lower colors.

The structure is that of the same for dancing stars.
Here is the code
[code:cpzpzgex]
void GEffects::CommetEffect( GScreen *sImage, float BassLevel, float TrebleLevel )
{
int i;
float radius;
float theta;
float XSide, NewX;
float YSide, NewY;
sint32 OldX, OldY;
int sign;

for (i = 0; i < NUM_COMMETS; i++)
{
    OldX = (sint32)Stars[i].x;
    OldY = (sint32)Stars[i].y;

    XSide  = Stars[i].x - (float)PADestX;
    YSide  = Stars[i].y - (float)PADestY;

    sign = ((rand() % 3) - 1); // -1, 0, or 1

    radius = (float) sqrt ((XSide * XSide) + (YSide * YSide));
    theta  = (float) atan2 (YSide, XSide);

    theta += (TrebleLevel * 1 * (float)sign); //* Vars->ScreenStretch;

    NewX = radius * (float)cos(theta);
    NewX += (float)PADestX;
    NewY = radius * (float)sin(theta);
    NewY += (float)PADestY;

    Stars[i].x = NewX;
    Stars[i].y = NewY;

    if (BassLevel > 0.30f)
    {
        PADestX = rand() % Width;
        PADestY = rand() % Height;
    }

    if (Stars[i].x > (float)(Width-5 ) )
        Stars[i].x = (float)(Width-5);
    if (Stars[i].x < 5.0f)
        Stars[i].x = 5.0f;
    if (Stars[i].y > (float)(Height-5))
        Stars[i].y = (float)(Height-5);
    if (Stars[i].y < 5.0f)
        Stars[i].y = 5.0f;

    uint32 ArrayLen;
    POINT *Coords;
    sint32 x1, y1;

    x1 = (sint32)Stars[i].x;
    y1 = (sint32)Stars[i].y;

    Coords = GetLineCoords (x1, y1, OldX, OldY, &ArrayLen);

    const uint32 BaseLum   = 128;
    uint32       LumDelta  = (256 - BaseLum) / ArrayLen;
    uint32       Lum       = BaseLum;
    GColorRGBA   Color     = Stars[i].c;

    for (sint32 j = ArrayLen - 1; j >= 0; j--)
    {
        Coords[j].y -= ((480 - 460) >> 1);

        if( sImage->IsInBounds (Coords[j].x, Coords[j].y) ) {
            sImage->GetPixelPtr( Coords[j].x, Coords[j].y )->Blend256( Color, Lum );
        }

        Lum += LumDelta;
    }

    FreeLineCoords (Coords);
}

}
[/code:cpzpzgex]

I’ll post the last bits tommorow I’am kinda beat and this is taking more time to format then I thought.

For now Ill leave u with a important finally piece of code which is impossible to imulate via GDI at rapid speeds.
[code:cpzpzgex]
bool GScreen::TransformBlur( unsigned __int32 Lum, bool FastBlend )
{
GColorRGBA cur, Blend;
unsigned __int32 *p3;
unsigned __int32 y, x;
bool s;

for( y = 0; y < Height; y++ ) 
{
    p3 = lpSurrfaceBuffer + (y * Stride);

    for( x = 0; x < Width; x++ ) 
    {
        cur.rgba   = p3[0];
        s = false;

        if( y > 0 ) {
            Blend = p3[-Stride];
            if( cur.r < Blend.r || cur.g < Blend.g || cur.b < Blend.b  ) {
                s = true;
                if( FastBlend )
                    cur.BlendHalfFast( Blend );
                else
                    cur.Blend256( Blend, 175 );
            }
        }

        if( y < Height ) {
            Blend = p3[Stride];
            if( cur.r < Blend.r || cur.g < Blend.g || cur.b < Blend.b  ) {
                s = true;
                if( FastBlend )
                    cur.BlendHalfFast( Blend );
                else
                    cur.Blend256( Blend, 175 );
            }
        }

        if( x < Width ) {
            Blend = p3[1];
            if( cur.r < Blend.r || cur.g < Blend.g || cur.b < Blend.b  ) {
                s = true;
                if( FastBlend )
                    cur.BlendHalfFast( Blend );
                else
                    cur.Blend256( Blend, 175 );
            }
        }

        if( x > 0 ) {
            Blend = p3[-1];
            if( cur.r < Blend.r || cur.g < Blend.g || cur.b < Blend.b  ) {
                s = true;
                if( FastBlend )
                    cur.BlendHalfFast( Blend );
                else
                    cur.Blend256( Blend, 175 );
            }
        }

        if( s == true || cur != 0 ) {
            cur.Luminate256( Lum );
            *(p3++) = cur.rgba;
        } else {
            *(p3++);
        }
    }
}

return true;

}
[/code:cpzpzgex]
Note that I have a much better routine if others would like however it is CPU based and contains alot of assembly code.

Anyhow I’ll post the last bits tommorow and make source code aviable as soon as I have it complety optomized.

++Cire.

  • You must to post comments
0
0

[quote="Cire":3ar3bns0]Graduate Bruce 2002, no I mean that everything you do via winamp somehow ends backup at NullSofts database, be it playing a CD, or a mp3 or whatever.[/quote:3ar3bns0]

Oh, that. That’s also an option during the post-install step. “Send anonymous usage information” or something–and it’s not specific to Winamp, either. This is true of Windows Media Player 9, as well as RealOne if I remember correctly.

  • You must to post comments
0
0

Why don’t you make a winamp plugin with your code?

  • You must to post comments
0
0

That don’t make it right however. What I do on my computer is for my concern not joe blow. I’am really against all this invassion of privacy stuff. Just think if Brett decided to put in his code that everytime it was run or used it uploaded craploads of info for his personal amusement how long would it take for us to find a different sound system?

I for one will boycot Winamp, and I’am greatful for Brett for providing us with a way to easilly handle our audio needs, as for WMP its a joke even my 2.2 gig laptop feels the pressure of it. I dunno what happened but at one point in time WMP earlier versions used to fly, was efficent and well run now u need 2 super computers to run it.

++Cire.

  • You must to post comments
Showing 1 - 20 of 23 results
Your Answer

Please first to submit.