This JSL makes a video to go with some music. Usually it would be the other way around: the music would be selected to match the video. By selecting the music first, and limiting what the video can look like a bit, I get a set of images that can be combined with the audio (using Blender in this case) to get perfect synchronization. Once again, the JSL is not cleaned up, but there are some comments sprinkled through it.
DoNotEat - YouTube
wav = "44.1KHz 16bit stereo.wav";
resolution = 120;
dim = 30;
picscale = .5;
yrot = 188;
xrot = 68;
zrot = -310;
preroll = 10;
patch = Function( {dent},
xpoints = J( dim, dim, 0 );
ypoints = J( dim, dim, 0 );
zpoints = J( dim, dim, 0 );
bottom = 0;
top = (dim / 2) - 1;
center = (dim + 1) / 2;
scale = 5;
For( row = 1, row <= dim, row++,
For( col = 1, col <= dim, col++,
ring = Interpolate( Min( row - 1, col - 1, dim - row, dim - col ), bottom, 0.001, top, Pi() );
ypoints[row, col] = scale * Sin( ring ) * (row - center) / dim;
xpoints[row, col] = scale * Sin( ring ) * (col - center) / dim;
zpoints[row, col] = Interpolate( ring, 0, .9,
.7, 1,
1.8, -.5,
Pi(), Interpolate( -dent, -1, -2, 0, -.3, 1, 1.8 )
);
)
);
points = Shape( ypoints, dim * dim, 1 ) || Shape( xpoints, dim * dim, 1 ) || Shape( zpoints, dim * dim, 1 );
Teapot << Map2( MAP2_VERTEX_3, 0, 1, N Cols( points ), Sqrt( N Rows( points ) ),
0, 1, N Cols( points ) * Sqrt( N Rows( points ) ), Sqrt( N Rows( points ) ), points );
Teapot << EvalMesh2( FILL, 0, resolution, 0, resolution );
);
nobj = 240;
obj = Associative Array();
For( dent = -nobj, dent <= nobj, dent += 1,
teapot = Scene Display List();
patch( dent / nobj );
obj[dent] = teapot;
);
scene = Scene Box( picscale * 1920 + 1, picscale * 1080 + 1 );
New Window( "Teapot",
V List Box(
scene,
Slider Box( -360, 360, xrot, buildscene(), <<setwidth( 1000 ) ),
Slider Box( -360, 360, yrot, buildscene(), <<setwidth( 1000 ) ),
Slider Box( -360, 360, zrot, buildscene(), <<setwidth( 1000 ) )
)
);
buildscene = Function( {},
scene << clear;
scene << backgroundcolor( 0, 0, 0 );
scene << perspective( 30, 1, 100 );
scene << translate( 0, 0, -30 );
scene << Enable( Lighting );
scene << Enable( Light0 );
scene << Light( Light0, AMBIENT, .01, .01, .01, 0 );
scene << Light( Light0, DIFFUSE, .6, .6, .6, 0 );
scene << Light( Light0, SPECULAR, .99, .99, .99, 0 );
scene << Enable( Light1 );
scene << Light( Light1, AMBIENT, .01, .01, .01, 0 );
scene << Light( Light1, DIFFUSE, .4, .4, .4, 0 );
scene << Light( Light1, SPECULAR, .1, .1, .1, 0 );
scene << Enable( Light2 );
scene << Light( Light2, AMBIENT, .01, .01, .01, 0 );
scene << Light( Light2, DIFFUSE, .1, .1, .1, 0 );
scene << Light( Light2, SPECULAR, .1, .1, .1, 0 );
scene << Enable( Light3 );
scene << Light( Light3, AMBIENT, .01, .01, .01, 0 );
scene << Light( Light3, DIFFUSE, .1, .1, .1, 0 );
scene << Light( Light3, SPECULAR, .1, .1, .1, 0 );
scene << Light( Light0, Position, -100, 100, 5, 0 );
scene << Light( Light1, Position, 100, 100, 50, 0 );
scene << Light( Light2, Position, -100, -100, 50, 0 );
scene << Light( Light3, Position, 100, -100, 50, 0 );
Teapot = Scene Display List( 0 );
Teapot << Enable( MAP2_VERTEX_3 );
Teapot << Enable( Auto_Normal );
Teapot << MapGrid2( resolution, 0, 1, resolution, 0, 1 );
Teapot << Enable( COLOR_MATERIAL );
Teapot << Material( Front, Specular, .5, .5, .5, 1 );
Teapot << Material( Front, Shininess, 50 );
Teapot << Disable( POLYGON_SMOOTH );
grid = 9;
ifreq = 0;
nbins = N Rows( amplFiltered ) / 2;
picker = [1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9, 10 10, 11 11, 12 12, 13 13, 14 14, 15 15, 16 16, 17 17, 18 18, 19 19, 20 20, 21 21, 22
22, 23 23, 24 24, 25 25, 26 26, 27 27, 28 28, 29 29, 30 30, 31 31, 32 32, 33 33, 34 34, 35 35, 36 36, 37 38, 39 40, 41 42, 43 44, 45 46, 47
48, 49 50, 50 54, 55 60, 61 70, 71 99, 100 200, 201 735];
freqs = [
43 44 45 46 47 48 49
42 21 22 23 24 25 26
41 20 7 8 9 10 27
40 19 6 1 2 11 28
39 18 5 4 3 12 29
38 17 16 15 14 13 30
37 36 35 34 33 32 31];
If( nbins != picker[N Rows( picker ), 2],
Throw( "bad" )
);
For( xx = -grid, xx <= grid, xx += 3,
For( yy = -grid, yy <= grid, yy += 3,
ifreq++;
mm = picker[freqs[ifreq], 0];
q = Floor( Max( -nobj, Min( nobj, (Log( Max( amplFiltered[mm] ) ) - 13) * 60 ) ) );
teapot << pushMatrix;
teapot << translate( xx, yy, 0 );
{red, green, blue} = Color To RGB( HLS Color( Interpolate( freqs[ifreq], 1, 0, 49, 1 ), .5, 1 ) );
Teapot << Color( red, green, blue );
Teapot << callList( obj[q] );
Teapot << popmatrix;
)
);
scene << rotate( yrot + 9 * Sin( zrot / 79 ), 0, 1, 0 );
scene << rotate( xrot + 9 * Sin( zrot / 61 ), 1, 0, 0 );
zrot += .25;
scene << rotate( zrot, 0, 0, 1 );
scene << ArcBall( Teapot, 10 );
scene << update;
scene << inval;
scene << updatewindow;
);
x = Load Text File( wav, blob );
x = Hex( x );
If( Pat Match( x, Hex( "RIFF" ) + Pat Arb() + Hex( "data" ), "" ),
x = Blob To Matrix( Hex To Blob( x ), "int", 2, "little", nCols = 2 );
x = (x[0, 1] + x[0, 2]) / 2;
cols = (44100 / 30);
rows = N Rows( x );
rows = Floor( rows / cols );
x = Shape( x, rows, cols );
period = cols / 44100;
binwidth = 1 / period;
maxs = J( 15, 1, 0 );
maxa = 0;
For( i = 1, i <= rows, i++,
{real, imag} = FFT( {x[i, 0]`} );
ampl = Sqrt( real :* real + imag :* imag );
time = (i - 1) * (cols / 44100);
maxa = Max( maxa, Max( ampl ) );
);
i = 1;
zrot = zrot - preroll * .25;
{real, imag} = FFT( {x[i, 0]`} );
ampl = Sqrt( real :* real + imag :* imag );
amplFiltered = ampl * 0.00001;
For( i = -preroll, i < 1, i++,
buildscene();
Wait( 0 );
pic = scene << getpicture;
pixels = pic << getpixels;
pixels = pixels[2 :: picscale * 1080 + 1, 3 :: picscale * 1920 + 2];
pic << setpixels( pixels );
pic << saveimage( "$temp\m" || Right( Char( i + preroll, 9 ), 9, "0" ) || ".png" );
amplFiltered = ampl * Interpolate( i, -preroll, 0.00001, -preroll / 5, 0.0001, 1, 1 );
);
For( i = 1, i <= rows, i++,
Print( i / rows );
{real, imag} = FFT( {x[i, 0]`} );
ampl = Sqrt( real :* real + imag :* imag );
time = (i - 1) * (cols / 44100);
amplFiltered = If( i == 1,
ampl,
selector = Greater( ampl, amplFiltered );
selector :* ampl + (1 - selector) :* ((3 * amplFiltered + ampl) / 4);
);
buildscene();
Wait( 0 );
pic = scene << getpicture;
pixels = pic << getpixels;
pixels = pixels[2 :: picscale * 1080 + 1, 3 :: picscale * 1920 + 2];
pic << setpixels( pixels );
pic << saveimage( "$temp\m" || Right( Char( i + preroll, 9 ), 9, "0" ) || ".png" );
);
For( i, i < rows + 360, i++,
amplFiltered = amplFiltered :* .95;
buildscene();
Wait( 0 );
pic = scene << getpicture;
pixels = pic << getpixels;
pixels = pixels[2 :: picscale * 1080 + 1, 3 :: picscale * 1920 + 2];
pic << setpixels( pixels );
pic << saveimage( "$temp\m" || Right( Char( i + preroll, 9 ), 9, "0" ) || ".png" );
);
,
Print( "bad file" )
);
Print( "done" );
19jun2019: finally repaired the JSL after the community change several years ago
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.