PDA

View Full Version : ScopeII


ph69
01-25-2008, 09:34 AM
Hi,
While working on modular synth, I needed a scope with synchro capabilities.
Here it is

desc:MoonSynthi ScopeII alpha (press Edit for HELP)
/*
Scope with synchro and automatic gain

DONE low pass synchro
color depending on selected channel
automatic gain
display peak max/min, mean, rms value
TODO : pitch control synchro
subsample synchro
additive display (with compensation for display size and widthS)
all gfx / serialize, no slider, for small display
*/
slider1:10<1,20>Time width (ms)
slider2:0<0, 11, 1{0,1,2,3,4,5,6,7,8,9,10,11}>Sync channel
slider3:0<0, 11, 1{0,1,2,3,4,5,6,7,8,9,10,11}>View channel

//__________________________________________________ _______________
@init
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// Tables
L_BUF = srate; //1s buffer
syncBuf = 0;
viewBuf = syncBuf + L_BUF;
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// Set of colours depending on which channel you select
t_r = viewBuf + L_BUF;
t_g = t_r + 12;
t_b = t_g + 12;
x = 0;
ch = 0;
loop(12,
t_r[ch] = sqrt(0.5 + 0.5 * sin(x));
t_g[ch] = sqrt(0.5 + 0.5 * sin(x + 2*$pi/3));
t_b[ch] = sqrt(0.5 + 0.5 * sin(x + 4*$pi/3));
x += $pi/6.0;
ch += 1;
);
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// Buffer index
writePos = 0;
low = low2 = 0;

//__________________________________________________ _______________
@slider
widthS = srate * slider1 * 0.001;//width of a time frame in samples
syncCh = slider2|0;
viewCh = slider3|0;

//__________________________________________________ _______________
@sample

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// Low pass filtering of synchro signal
low = low + 0.01 * (spl(syncCh) - low);
low2 = low2 + 0.01 * (low - low2);

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// Buffering
syncBuf[writePos] = low2;
viewBuf[writePos] = spl(viewCh);

writePos += 1;
writePos >= L_BUF ?
writePos = 0;

//__________________________________________________ _______________
@gfx 100 100

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// We start 3 time frames ago (widthS).
startPos = (writePos - 3 * widthS - 1 + L_BUF) % L_BUF;
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// mean and other values over these 3 frames
v_moy = v_max = v_min = viewBuf[startPos];
v_rms = viewBuf[startPos] * viewBuf[startPos];
i = 1;
loop(3 * widthS - 1,
v = viewBuf[(startPos + i) % L_BUF];
v_moy += v;
v_rms += v * v;
v > v_max ? v_max = v;
v < v_min ? v_min = v;
i += 1;
);
v_moy /= 3 * widthS;
v_rms = sqrt(v_rms) / (3 * widthS);

peak = max(v_max, -v_min);
gain = 1 / max(peak, 0.0001); //max gain:10000

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// scanning for synchro over a time frame
av = syncBuf[startPos];
i = 0;
while(
startPos = (startPos + 1) % L_BUF;
v = syncBuf[startPos];
v > 0 && av <= 0 ?
i = widthS; // We found the 0 crossing we leave the loop
av = v;
i += 1;
i < widthS;
);

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// color
gfx_r = t_r[viewCh];
gfx_g = t_g[viewCh];
gfx_b = t_b[viewCh];
gfx_a = 1;

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// Values
gfx_x = 10; gfx_y = 10;
gfx_drawnumber(v_min, 3);
gfx_x += 10;
gfx_drawnumber(v_max, 3);
gfx_x = 10; gfx_y += gfx_texth;
gfx_drawnumber(v_moy, 3);
gfx_x += 10;
gfx_drawnumber(v_rms, 3);

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// display of view channel
h_milieu = gfx_h * 0.5;
etendue = gfx_h * 0.45;
cBuf = viewBuf; //current Buffer
gfx_x = 0; gfx_y = h_milieu - etendue * cBuf[startPos];
dx = gfx_w / widthS;
i = 1; x = dx;
loop(widthS,
gfx_lineto(x,h_milieu - etendue * gain * cBuf[(startPos + i) % L_BUF], 1);
i += 1; x += dx;
);

schwa
01-25-2008, 09:41 AM
screen shot:
http://stash.reaper.fm/oldsb/19965/108025114328-Master-track-JS-scope2.png

NICE work! I'll soon have to retire this. (http://www.stillwellaudio.com/?page_id=26)

ph69
01-25-2008, 09:49 AM
NICE work! I'll soon have to retire this. (http://www.stillwellaudio.com/?page_id=26)
Waow, your plugins are wonderfull !

schwa
01-25-2008, 09:51 AM
I love that it's resizable. I'll say it again, this is really nice work!

It would be nice to measure the wavelength in hz as well.

ph69
01-25-2008, 10:05 AM
Pitch detection is a tricky business ;)
Maybe I will have to improve the synch method, zero crossings are an easy way, but it is not efficient in many cases.

schwa
01-25-2008, 10:28 AM
Pitch detection is a tricky business ;)
Maybe I will have to improve the synch method, zero crossings are an easy way, but it is not efficient in many cases.

For these purposes you could just do
(mean number of zero crossings in window) / (window time)

for quick & dirty right?

ph69
01-27-2008, 07:34 AM
For these purposes you could just do
(mean number of zero crossings in window) / (window time)

for quick & dirty right?

I use a lot of phase modulation synthesis stuff by now and it is not the good way for this kind of signal (lots of zero crossings) ;)

wzmzw
01-27-2008, 04:10 PM
Ey!

Very good plug my friend, it is in my Reaper now, Thanks

Salut!

ph69
01-28-2008, 10:14 AM
I will add a secondary channel, I think it will be usefull.

It is tricky to improve synch beyond zero crossings, but I will do it, because I need it (FM synthesis)... But it will take me some time to find out a method that is efficient with this kind of sound, not too complicated for JS coding and not CPU intensive.

ph69
01-31-2008, 12:32 AM
Hello, I posted a new release in the "JS Modular synth" thread, it is part of the MoonSynthi package.

Two simultaneous channels, improved stability of synchro, subsample synchro and improved rendering (with some kind of shadows).

on the left the numbers are the peak maximum and minimum.
On the top right is the RMS value (including DC).
on the bottom right is the mean value.

ph69
02-01-2008, 01:17 AM
See the JS repository for the latest version ;) it is included in the MoonSynthi package.

schwa
02-01-2008, 05:13 AM
+1 for ScopeII in the Reaper installer!

wzmzw
02-02-2008, 10:15 AM
+1 for ScopeII in the Reaper installer!

+2

Salut!

ph69
02-02-2008, 01:18 PM
-1 ... I am a little paranoïd about buffers and multithreading without mutexes ;)