Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER for Video Editing/Mangling

Reply
 
Thread Tools Display Modes
Old 03-24-2022, 10:37 AM   #1
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,295
Default Decorative Oscilloscope with Bars instead of Dots

I have to believe this has been done before, but couldn't be bothered to search, so I did it myself. I "borrowed" the gfx_line code from a post by wwwmaze.

Added a parameter to rectify the waveform up/leftward or down/rightward. It won't impact mode 2 because that's already rectified in its own way.

I also replaced the "blitter filter" parameter with "blitter blend mode". It currently supports 3 modes. 0 is normal, 1 is subtract, and 3 is difference. No they are not the same, but yes they are similar. Honestly, if I was trying to do anything actually interesting with that blitter persist thing, I'd probably use my better blitter feedback preset after this.

Edit - Added mode 3, which is an actual radial thing, basically like mode 1 except wrapped around a circle with radius set by the new last parameter. Did not update the gif though.



Hope somebody can find it useful. Please do reply with any questions, comments, concerns, or complaints.

Code:
//Decorative Oscilloscope with Bars instead of Dots (requires JSFX video sample peeker)
//@gmem=jsfx_to_video
//@param 1:mode "mode" 0 0 3 0 1
//@param 2:rect "rectify" 0 -1 1 0 1
//@param 3:dotcount "point count" 1200 10 5000 400 10
//@param 4:dotsize "point size" 4 2 40 20 1
//@param 5:gain_db "gain (dB)" -6 -80 12 -12 1
//@param 6:zoom_amt "blitter zoom" .27 -.5 1 .1 0.01
//@param 7:fadespeed "blitter persist" .8 0 1 .1 0.01
//@param 8:blend_mode "blitter blend mode" 0 0 2 1 1
//@param 9:fg_r "foreground R" 1 0 1 .5 .02
//@param 10:fg_g "foreground G" 1 0 1 .5 .02
//@param 11:fg_b "foreground B" 1 0 1 .5 .02
//@param 12:bg_r "background R" 0 0 1 .5 .02
//@param 13:bg_g "background G" 0 0 1 .5 .02
//@param 14:bg_b "background B" 0 0 1 .5 .02
//@param 15:cx "center X" .5 0 1 .5 .01
//@param 16:cy "center Y" .5 0 1 .5 .01
//@param 17:radius "radius (mode 3)" .5 0 1 .5 .01

mode != 3 ? rect *= -1;
radius *= 0.5;


function gfx_line(x,y,x2,y2,t) local(i,n,dx,dy,dxn,dyn) (
  dx=(x2-x); dy=(y2-y);
  n=abs(dx)+abs(dy);
  dxn=dx/n; dyn=dy/n;
  i=0;
  loop(n,
    gfx_fillrect(x+i*dxn,y+i*dyn,t,t);
    i+=1;
  );
  gfx_fillrect(x2,y2,1,1);
);

oldCS=colorspace;
colorspace='YV12';
last_frame && fadespeed > 0 ? (
  xo = project_w*zoom_amt*.25;
  yo = project_h*zoom_amt*.25;
  blend_mode == 0 ? gfx_mode = 0;
  blend_mode == 1 ? (gfx_a *= -1; gfx_mode = 1;);
  blend_mode == 2 ? gfx_mode = 19;

  xo < 0 ? gfx_blit(last_frame,0);
  gfx_blit(last_frame,0,0,0,project_w,project_h,xo,yo,project_w-xo*2,project_h-yo*2);
);
blend_mode == 1 ? gfx_a *= -1;
colorspace=oldCS;
gfx_set(bg_r,bg_g,bg_b,last_frame ? (1-fadespeed) : 1);
gfx_a>.001 ? gfx_fillrect(0,0,project_w,project_h);

bufplaypos = gmem[0];
bufwritecursor = gmem[1];
bufsrate = gmem[2];
bufstart = gmem[3];
bufend = gmem[4];
nch = gmem[5];
gain = 10^(gain_db*(1/20));

dt=max(bufplaypos - project_time,0);
dt*bufsrate < dotcount ? underrun_cnt+=1;
rdpos = bufwritecursor - ((dt*bufsrate - dotcount)|0)*nch;
rdpos < bufstart ? rdpos += bufend-bufstart;

gfx_set(fg_r,fg_g,fg_b,1);

function getpt()
(
  l = gmem[rdpos]; r = gmem[rdpos+1];
  rect != 0 ?
    (l = sign (rect) * abs(l);
     r = sign (rect) * abs(r););
  (rdpos += nch)>=bufend ? rdpos=bufstart;
);
two_pi = 2 * $pi;
center_x = cx * project_w;
center_y = cy * project_h;
i=0;

mode==3 ? (
  loop(dotcount,
    getpt();
    ang = two_pi * i/dotcount;
    cos_ = cos(ang);
    sin_ = sin (ang);
    dist = max(0, (l+r) * gain * 0.25 + radius);
    o_x = (radius * cos_ + cx) * project_w;
    o_y = (radius * sin_ + cy) * project_h;
    xp = (cos_ * dist + cx) * project_w;
    yp = (sin_ * dist + cy) * project_h;
    gfx_line(o_x, o_y, xp, yp, dotsize);
   i += 1;
  );
) : mode==2 ? (
  loop(dotcount,
    getpt();
    ang = atan2(l,r); dist = sqrt(sqr(l)+sqr(r));
    xp = cx*project_w + ((cos(ang)*dist*gain)*project_h-dotsize)*.5;
    yp = ((cy*2+sin(ang)*dist*gain)*project_h-dotsize)*.5;
    gfx_line(center_x, center_y, xp, yp, dotsize);
  );
) : mode == 1 ? (
  loop(dotcount,
    getpt();
    yp = project_h * (cy - .5 + i / dotcount);
    xp = project_w * (cx + (l+r)*.25*gain);
    gfx_line(center_x, yp-dotsize*.5, xp, yp-dotsize*.5, dotsize);
    i+=1;
  );

) : (
  loop(dotcount,
    getpt();
    xp = project_w * (cx - 0.5 + i / dotcount);
    yp = project_h * (cy + (l+r)*.25*gain);
    gfx_line(xp-dotsize*.5,center_y, xp-dotsize*.5,yp, dotsize);
    i+=1;
  );
);

gfx_img_free(last_frame);
last_frame=gfx_img_hold(-1);

Last edited by ashcat_lt; 03-24-2022 at 04:36 PM.
ashcat_lt is online now   Reply With Quote
Old 06-08-2023, 03:38 AM   #2
Lynx_TWO
Human being with feelings
 
Lynx_TWO's Avatar
 
Join Date: Dec 2019
Location: St Petersburg FL
Posts: 999
Default Is smoother rendering so less "jumpy" possible?

Hello!

I'm finding this very useful. However, is there a way to morph the frames/smoothly slow down the visual waveform peak generation? Currently rendering video at 30 FPS, and the rendered waveform visual is naturally really "jumpy." Thanks so much for your time!
__________________
My mixes from the Cambridge multitracks library
SoundCloud link & Youtube (ThemTube?) link
My preferred adjectives are “Handsome” and “Brilliant”
Lynx_TWO is offline   Reply With Quote
Old 06-08-2023, 12:56 PM   #3
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 690
Default

Quote:
Originally Posted by Lynx_TWO View Post
Hello!

I'm finding this very useful. However, is there a way to morph the frames/smoothly slow down the visual waveform peak generation? Currently rendering video at 30 FPS, and the rendered waveform visual is naturally really "jumpy." Thanks so much for your time!
I tried averaging the values and the results is somewhat better. 2 changes:
a new averaging paramater to insert and a slightly revised get_point() function. You will need to pump up the gain too...
Code:
//@param 18:avgf "averaging factor %" 50 0 100 50 1
avgf/=100;

...

function getpt()
(
  l = avg[rdpos]*avgf+gmem[rdpos]*(1-avgf);   
  r = avg[rdpos+1]*avgf+gmem[rdpos+1]*(1-avgf);
  rect != 0 ?
    (l = sign (rect) * abs(l);
     r = sign (rect) * abs(r););
  (rdpos += nch)>=bufend ? rdpos=bufstart;
);

...

Last edited by papagirafe; 06-08-2023 at 01:07 PM. Reason: missing info
papagirafe is offline   Reply With Quote
Old 06-09-2023, 08:10 PM   #4
Lynx_TWO
Human being with feelings
 
Lynx_TWO's Avatar
 
Join Date: Dec 2019
Location: St Petersburg FL
Posts: 999
Default

Thank you so much! That does marginally improve the results. I did notice that in After Effects, there is an option called Audio Duration in milliseconds (video showing this is here: https://www.youtube.com/watch?v=xEBzx66d2yA), and I'm wondering if this helps give an idea of how to slow down the response in the waveform so it can move slower? There's also an option to adjust the high and lowpass of the frequency response, which but be a cool feature, but not needed in my case

Thank you so much again for your time and creating this!
__________________
My mixes from the Cambridge multitracks library
SoundCloud link & Youtube (ThemTube?) link
My preferred adjectives are “Handsome” and “Brilliant”
Lynx_TWO is offline   Reply With Quote
Old 06-09-2023, 09:13 PM   #5
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,295
Default

I've been wanting to revisit this preset for a while. I don't super like the line function, but trying to fix it led me down a rabbit hole trying to figure out rotoblit, which led to frustration and has not yet bet completely fruitful.

I do see how averaging dot by dot on this end could have a noticeably different effect from trying to smooth things on the audio side. The code above, though, doesn't seem to be actually storing anything into the avg[] buffer, so best I can tell, it's "averaging" with 0, basically just turning the whole thing down, which is probably why it wanted gain. (???)

I don't super love doing the smoothing in the getpt function, but the quick and dirty fix is, I think:

Code:
function getpt()
(
  avg[rdpos]  =  l  =  avg[rdpos] * avgf + gmem[rdpos] * (1 - avgf);   
  avg[rdpos+1] = r = avg[rdpos+1] * avgf + gmem[rdpos+1] * (1-avgf);
  rect != 0 ?
    (l = sign (rect) * abs(l);
     r = sign (rect) * abs(r););
  (rdpos += nch)>=bufend ? rdpos=bufstart;
);
Which is basically just a lowpass per dot. (I didn't try it either way, but I think this is what papa was actually trying to do)

Honestly, it's a bit more efficient to calculate something like
i_avgf = 1 - avgf;
toward the top of the code and then using that in getpt () rather than doing all those extra operations in the loop, but it'll work either way.

It freaks me out just a little that rdpos starts somewhere beyond 0 and so there will always be a sort of blank section at the beginning of that avg[] buffer. It doesn't hurt anything at all except my "OCD", and would actually be more messing around than it's worth to try fix unless we're going to split the LPF out to a separate function. That would be my preference, but I'm not doing that now.
ashcat_lt is online now   Reply With Quote
Old 06-10-2023, 04:42 AM   #6
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 690
Default

Quote:
Originally Posted by ashcat_lt View Post
I've been wanting to revisit this preset for a while. I don't super like the line function, but trying to fix it led me down a rabbit hole trying to figure out rotoblit, which led to frustration and has not yet bet completely fruitful.

I do see how averaging dot by dot on this end could have a noticeably different effect from trying to smooth things on the audio side. The code above, though, doesn't seem to be actually storing anything into the avg[] buffer, so best I can tell, it's "averaging" with 0, basically just turning the whole thing down, which is probably why it wanted gain. (???)

I don't super love doing the smoothing in the getpt function, but the quick and dirty fix is, I think:

Code:
function getpt()
(
  avg[rdpos]  =  l  =  avg[rdpos] * avgf + gmem[rdpos] * (1 - avgf);   
  avg[rdpos+1] = r = avg[rdpos+1] * avgf + gmem[rdpos+1] * (1-avgf);
  rect != 0 ?
    (l = sign (rect) * abs(l);
     r = sign (rect) * abs(r););
  (rdpos += nch)>=bufend ? rdpos=bufstart;
);
Which is basically just a lowpass per dot. (I didn't try it either way, but I think this is what papa was actually trying to do)

Honestly, it's a bit more efficient to calculate something like
i_avgf = 1 - avgf;
toward the top of the code and then using that in getpt () rather than doing all those extra operations in the loop, but it'll work either way.

It freaks me out just a little that rdpos starts somewhere beyond 0 and so there will always be a sort of blank section at the beginning of that avg[] buffer. It doesn't hurt anything at all except my "OCD", and would actually be more messing around than it's worth to try fix unless we're going to split the LPF out to a separate function. That would be my preference, but I'm not doing that now.
Hiho ashcat_lt!

Ouch! Thank for fixing the code, I was taking a 10 mins break from my tiring main project and it shows! I'm even surprised it worked at all!
I would gladly like to see a improved (optimized! ) version using a better method. This is a cool preset!

Last edited by papagirafe; 06-10-2023 at 07:43 AM.
papagirafe is offline   Reply With Quote
Old 12-03-2023, 11:08 PM   #7
bellerandre
Human being with feelings
 
Join Date: Jul 2020
Posts: 14
Default

I'd love a "smoother" version of this! The code edits don't seem to work for me, or I'm not pasting them correctly.
bellerandre is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 11:15 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.