03-24-2022, 10:37 AM | #1 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,295
|
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);
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika Last edited by ashcat_lt; 03-24-2022 at 04:36 PM. |
06-08-2023, 03:38 AM | #2 |
Human being with feelings
Join Date: Dec 2019
Location: St Petersburg FL
Posts: 999
|
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” |
06-08-2023, 12:56 PM | #3 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 690
|
Quote:
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 |
|
06-09-2023, 08:10 PM | #4 |
Human being with feelings
Join Date: Dec 2019
Location: St Petersburg FL
Posts: 999
|
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” |
06-09-2023, 09:13 PM | #5 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,295
|
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; ); 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.
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
06-10-2023, 04:42 AM | #6 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 690
|
Quote:
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. |
|
12-03-2023, 11:08 PM | #7 |
Human being with feelings
Join Date: Jul 2020
Posts: 14
|
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.
|
Thread Tools | |
Display Modes | |
|
|