Plug-ins, Hosts, Apps,
Hardware, Soundware
Developers
(Brands)
Videos Groups
Whats's in?
Banks & Patches
Download & Upload
Music Search
KVR
   
KVR Forum » DSP and Plug-in Development
Thread Read
DPO Oscilloscope MFC C++
Goto page 1, 2  Next
Erwin1975
KVRer
- profile
- pm
PostPosted: Wed Apr 04, 2012 3:48 am reply with quote
Hi all,

I am looking for a real Digital Phosphor Oscilloscope. One that simulates a real analog oscilloscope like this one:



I want to write my own oscilloscope plugin but I need some help to figure out the math to build a DPO. If someone could provide me some source code to help me out in the right direction would be great!

The goal is to share a free VST DPO plugin.

Erwin.
^ Joined: 03 Apr 2012  Member: #278029  
mystran
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Wed Apr 04, 2012 4:49 am reply with quote
Well, basically what you want to do is apply a (little bit of) blur to the previous image, draw the current waveform, and add some of the blurred previous image on top. Then show the result and use it as the "previous" image for the next frame (ie we have a feedback loop). That'll get you the fade effect.

If you want to further mimic an analog scope, you could draw the waveform as lines (or cubic splines or whatever) and vary the intensity depending on how far the points are from each other.
----
<- my plugins | my music -> @Soundcloud
^ Joined: 11 Feb 2006  Member: #97939  Location: Helsinki, Finland
antto
KVRAF
- profile
- pm
- www
PostPosted: Wed Apr 04, 2012 11:35 am reply with quote
http://www.youtube.com/watch?v=tL-Gb4q0uXw
like this?
----
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
^ Joined: 04 Sep 2006  Member: #118997  Location: 127.0.0.1
Jeff McClintock
KVRist
- profile
- pm
- www
PostPosted: Wed Apr 04, 2012 12:35 pm reply with quote
antto wrote:
http://www.youtube.com/watch?v=tL-Gb4q0uXw
like this?


Wow! Smile Love the way fast vertical transitions are drawn 'lighter' like a REAL scope.
^ Joined: 30 Jan 2005  Member: #56398  Location: New Zealand
antto
KVRAF
- profile
- pm
- www
PostPosted: Wed Apr 04, 2012 12:50 pm reply with quote
Jeff! btw, thank you once again for synthedit ;]
i finally managed to get my head around linking a SE gui module with a frame buffer from GDI
it *DOES* occasionally crash, and i couldn't solve why, i guess i haven't put my initialization code in the right places..

for this scope, i use 1 RGB 24bit frame buffer for the memoryDC
but the actual drawing happens in a RGB-float (aka 96bit) buffer
there is no fade effects or blurs happening, on each frame i clear the screen

the magic happens in my drawing code
i have an antialiased drawdot() algo, which draws "thick" dots on the screen
then, each dot is blended with a "hacked" additive algo
the memory effect of the scope actually comes from somewhere else
on the DSP side, i got a signal buffer of 2 seconds

depending on settings (the sweep rate) only the latest samples are sent to the GUI in a small buffer, since i'm using SendStringToGui() it can't be too big
then, the GUI redraws
the memory trick is actually, in the buffer, the oldest samples are drawn with darker color, fading to brightest color for the newest samples

the ultimate niceness was to turn the drawdot() algo into a drawline() algo with the same characteristics - thickness, and rounded ends, but that would consume lots of CPU

using these dots now, it looks very nice if the number of dots is big
----
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
^ Joined: 04 Sep 2006  Member: #118997  Location: 127.0.0.1
antto
KVRAF
- profile
- pm
- www
PostPosted: Wed Apr 04, 2012 12:56 pm reply with quote
the reason i made this scope, is more interesting
i need a scope, but i can't afford it right now

i know there are software oscilloscopes which use the soundcard.. but these are not really helpful (i could do such things in SE already)
but more importantly, i need to be able to see DC signals, but the soundcard is AC-coupled

a few years ago, i asked at this forum, if it's possible to "undo" the effect of a HP filter, and some nice gentlemen proposed such a filter, i tested it and it seemed to work
so i figured it would be very nice if this "inverse HP filter" is integrated into an oscilloscope!

and finaly - there it is
in this video, i was probing the VCO of an analog synth (x0xb0x)
----
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
^ Joined: 04 Sep 2006  Member: #118997  Location: 127.0.0.1
hibrasil
KVRist
- profile
- pm
- www
PostPosted: Wed Apr 04, 2012 2:14 pm reply with quote
this is a nice one done in vvvv

http://vimeo.com/38741613
^ Joined: 23 Jun 2002  Member: #3139  Location: York, UK
mystran
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Thu Apr 05, 2012 12:23 am reply with quote
antto wrote:
Jeff! btw, thank you once again for synthedit ;]
i finally managed to get my head around linking a SE gui module with a frame buffer from GDI
it *DOES* occasionally crash, and i couldn't solve why, i guess i haven't put my initialization code in the right places..

for this scope, i use 1 RGB 24bit frame buffer for the memoryDC
but the actual drawing happens in a RGB-float (aka 96bit) buffer
there is no fade effects or blurs happening, on each frame i clear the screen


There's probably no need to do the drawing in RGB. You could just use a single float gray-scale buffer, then colorize it when converting to output format.

As for fade feedback, that's useful if you want a longer glow-time (to reduce flicker) than a single frame without having to draw things several times.

edit: oh forgot to say, it looks very nice .. I've been meaning to do something similar for my PicoScope which has fairly crappy software was far as looking nice goes.
----
<- my plugins | my music -> @Soundcloud
^ Joined: 11 Feb 2006  Member: #97939  Location: Helsinki, Finland
Erwin1975
KVRer
- profile
- pm
PostPosted: Thu Apr 05, 2012 4:14 am reply with quote
Hi Antto,

Yes, exactly like that. Very nice!

So you draw a anti-aliased line with a anti-aliased dot instead of a anti-aliasing line drawing algo?

I have tried the WU anti-aliasing line drawing algo but the lines are to thick.

How do you calculate the thickness and brightness of the vertical lines?
^ Joined: 03 Apr 2012  Member: #278029  
mystran
KVRAF
- profile
- pm
- e-mail
- www
PostPosted: Thu Apr 05, 2012 4:28 am reply with quote
Erwin1975 wrote:

I have tried the WU anti-aliasing line drawing algo but the lines are to thick.


Anti-aliased lines are always going to be approximately as thick as what WU gives you simply because of the averaging (eg filtering) inherent in anti-aliasing. The only way you can give an impression of thinner lines is to draw them with less intensity.
----
<- my plugins | my music -> @Soundcloud
^ Joined: 11 Feb 2006  Member: #97939  Location: Helsinki, Finland
antto
KVRAF
- profile
- pm
- www
PostPosted: Thu Apr 05, 2012 4:31 am reply with quote
no, it's just a drawdot() algo
i could write a drawline() algo with the same characteristics, but it will kill the cpu ;]

the algo started as an anti-aliased drawdot(float x, float y, float z, float size) which i used in my first experiments with 96-bit color buffer
it looked like this:
so, the antialiasing happens around the edges of the dot, the inside is solid color, and the size and position can be fractional (float) size specifically goes from 0 to uhm, untill the cpu burns?

for the scope, i modifyied that algo, so the innner part of the dot is not just solid, but fades out like a radial gradient, and the "z" parameter is fixed to 1.0, since it's no longer 3D

mystran, yes i had the idea about using just a grayscale buffer and then colorizing at the end, but this scope has to be double channel (aka 2 colors for the 2 traces) and then, there will be some other stuff displayed on top of that in other colors..
----
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
^ Joined: 04 Sep 2006  Member: #118997  Location: 127.0.0.1
Erwin1975
KVRer
- profile
- pm
PostPosted: Thu Apr 05, 2012 4:39 am reply with quote
Hi Antto,

But how do you calculate the intensity of the dot? Horizontal lines are thick (like a analog scope) but vertical lines are darker depending the risetime of the signal.
^ Joined: 03 Apr 2012  Member: #278029  
antto
KVRAF
- profile
- pm
- www
PostPosted: Thu Apr 05, 2012 4:48 am reply with quote
in my video?
that happens when you draw _many_ dots with low intensity
since they are thick - the more dots are close to one another - the result becomes brighter (since it's based on additive blending)

so when the signal doesn't "move" much - you get many dots close together..
----
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
^ Joined: 04 Sep 2006  Member: #118997  Location: 127.0.0.1
Erwin1975
KVRer
- profile
- pm
PostPosted: Thu Apr 05, 2012 5:25 am reply with quote
Are you willing to share a piece of code (dot drawing with blend) so I can try that in my own code? I wonder how it looks like with music. Embarassed
^ Joined: 03 Apr 2012  Member: #278029  
antto
KVRAF
- profile
- pm
- www
PostPosted: Thu Apr 05, 2012 6:47 am reply with quote
warning: ugly code follows Shit!
(with my original comments)

    void setPS_AA(vx3 v, FCLR c, const float size)
    {
        if (v.z > 0.f)
        {
            // gotta figure out the bounding box for the circle
            // for a sz=1 the bounding box is 0,0 to 1,1
            // for a sz=2 it'll be a box of -1,-1 to 2,2
            // erm, if sz=1 then the worst case is 1 additional pixel, thus the box is 2x2
            // if sz is more than 1 (say 1.2) i need two additional pixels on each side i think.. making 4x4

            // if Z is 1.0 and size is 1.0 - the dot is of size 1.0
            // if Z is 2.0 and size is 1.0 - the dot is of size 0.5
            // if Z is 1.0 and size is 2.0 - the dot is of size 2.0 ... so it's size/z here too
            float rad; // radius
            int irad;
            int isz;
            int bx, by; // bounding box
            int bw, bh; // bounding box width and height

            int sx, sy;
            float fx, fy; // fractional part
            float i;
            float d = 1.f;
            v.x *= d;
            v.y *= d;
            rad = size * d; // size/z
            irad = (int)(ceilf(rad));
            v.x = v.x *  fsc + fscx;
            v.y = v.y * -fsc + fscy;
            fx = floor(v.x);
            fy = floor(v.y);
            sx = static_cast<int>(fx); // rounded center of dot (make bounding box around this)
            sy = static_cast<int>(fy);

            isz = irad/2; // (irad >> 1);
            bx = sx-isz;
            by = sy-isz;
            isz = 1+irad;
            bw = bx+isz;
            bh = by+isz;

            // clip the bounding box to screen rect (no need to draw outside the screen, right?)

            if (cliptoscreen(bx,by,bw,bh))
            {
                // if at least 1 pixel is visible - draw it
                // using sx sy for temp vars here
                sx = bx; sy = by;
                float dx, dy;
                while (sy < bh)
                {
                    // calc dy
                    dy = (float)(sy) - v.y;
                    while (sx < bw)
                    {
                        // calc dx
                        dx = (float)(sx) - v.x;
                        i = ddbc4(dx,dy,rad);
                        getdot(sx,sy)->add_mul(c,i);
                        ++sx;
                    }
                    ++sy; sx = bx;
                }
            }
// -----------------
    inline float ddbc4(const float dx, const float dy, const float Sz)
    {
        float in = 0.f;
        float ou = 1.f;
        float m = 1.f;
        if (Sz > 1.f) { in = (Sz - 1.f) * 0.5f; ou = Sz-in; }
        else { m = Sz; }
        float d = sqrt(dx*dx + dy*dy);
        if (d >= ou) { return 0.f; }
        float f = (d/ou);
        float f32 = f*f;
        f32 *= f32;
        f32 *= f32;
        f32 *= f32;
        f32 *= f32;
        f = (1.f-f32) * exp(f*-4.f);
        d = f;
        return d * m;
    }
    inline bool cliptoscreen(int &x1, int &y1, int &x2, int &y2)
    {
        x1 = max(x1,0);
        x2 = min(x2,_w1);
        y1 = max(y1,0);
        y2 = min(y2,_h1);
        int szx, szy;
        szx = x2-x1;
        szy = y2-y1;
        if (szx*szy >= 1) { return true; }
        return false;
    }

vx3 is a struct with: float x,y,z;
FCLR is a struct with float r,g,b;
the "size" parameter is the dot size in pixels at z=1.0
so with size=1 and a dot with z=0.5 - the final size on screen would be 2.0

the drawing happens here: getdot(sx,sy)->add_mul_tube(c,i);
getdot() returns a "FCLR" (pixel) from the 96-bit frame buffer
"add_mul" is the blending algo
inline void add_mul(const FCLR &x, const float &m) { R += x.R*m; G += x.G*m; B += x.B*m; }
"c" is the color (phosphorus kinda) and "i" is an intensity coeff
----
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
^ Joined: 04 Sep 2006  Member: #118997  Location: 127.0.0.1
All times are GMT - 8 Hours

Printable version
Page 1 of 2
Goto page 1, 2  Next
Display posts from previous:   
ReplyNew TopicPrevious TopicNext Topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Username: Password:  
KVR Developer Challenge 2012