Follow

Working on a thing to sonify silent colour videos.

One [vcf~] per pixel with center frequency Hz determined by hue and Q determined by saturation (just using HSV for now, nothing fancy).

One 20ms delay line per column of pixels

Input to each column's filters is a weighted sum of nearby delay lines.

Output is panned to stereo according to column's position in space

Decidedly not realtime even with OpenMP parallelism on 16 CPU threads.

(though maybe if I ported it to OpenCL and used single precision on GPU and kept video resolution low...)

Smooth droney sounds.

Maybe I can make it richer with some [hilbert~] magic (given a sinusoid, hilbert~ outputs 2 sinusoids approximately 90degrees out of phase for "most" of the spectrum, allowing you to get a [phasor~] out of it, which you can then waveshape at will - I'm thinking Chebyshev polynomial recursion to get bandlimited sawtooth waves).

· · Web · 2 · 0 · 1

@mathr I look forward to hearing (and seeing) results of this

@paul will post some WIP later

porting to OpenCL is looking desirable because it's rendering at ~20x slower than realtime...

porting to OpenCL is looking like it will be really awkward because my code is full of stateful-objects at the moment - had to add more data storage even on CPU because the delwrite~ needs to be atomic w.r.t. delread~ and I have delread~ in multiple OpenMP threads.

If I make the delay line length the same as the block size the same as the number of samples per video frame it might work out neatly with two buffers for each delay line.
.
If I structure the algorithm code right, it should still compile as C99+OpenMP, with some preprocessor magic, which should make any debugging needed much easier...

@paul ported to OpenCL and it runs 10x faster than before on my CPU, using my GPU now. still not realtime (2x slower rather than 20x slower).

@mathr Just slow down the time constant of the universe by a factor of around 2 and you're all set?

@paul aarg i had a typo, correct result is that it's now rendering at 4.1 fps instead of 1.6 fps (source video is 30fps)

@paul more WIP, think this is getting quite ok. only post processing was global gain/normalization (it outputs at around -40dBFS).

@paul

here's my code to go from a sinusoid v (which is output from a vcf~ ported from Pd) to a bandlimited sawtooth p using Pd's hilbert~.pd ported to C and Chebyshev polynomials of the second kind

```
sample b[2] = { v, v };
hilbert(b, &wave, b);
sample a = hypot(b[0], b[1]);
if (! (a > 0)) a = 1;
sample x = b[1] / a;
sample y = b[0] / a;
sample U0 = 1;
sample U1 = 2 * x;
sample w = 1;
for (int n = 2; n < 16; ++n)
{
w = -w;
w += U1 / n;
sample U2 = 2 * x * U1 - U0;
U0 = U1;
U1 = U2;
}
sample p = a * y * w;
if (isnan(p) || isinf(p)) p = 0;
```

not sure if b[0]/b[1] should be swapped, not sure if it matters - it'll just change the phase relation from +90 to -90 or vice versa...

@mathr How do you have video information direct sound then exactly? Just by volume, xceeding certain thrshholds and such. Or a complete FFT analysis with an array of values and interpretations behind?

@jayrope currently it's downscaled to 160x90 pixels. then each pixel has a delay line, vcf, and sawtooth waveshaper in a feedback loop, with the delays being read from neighbouring pixels too (like a spatial blur). the colour of each pixel in HSV space controls the filter: hue controls pitch (scaled like mtof over two octave range), saturation*value controls Q. full details in the source code:
code.mathr.co.uk/rodney/tree/6 check sonify.cl for the DSP, sonify.c for the control code, and sonify.sh for how to use it

@mathr Ah, so that's not Puredata anymore. My C skills are next to zero. Shame on that. And thank you for the pointer.

@jayrope inspired by / copy/pasta from Pd source code, but not Pd it's true. might be possible to rig up something similar with clone~, but I'm not really using Pd much at all any more, find it easier to edit text than patches....

@mathr How do you copypaste form PD in regards to C code?

@jayrope compare my code.mathr.co.uk/rodney/blob/6 vcf function with the inner loop of Pd's github.com/pure-data/pure-data (Pd has a linear interpolated table lookup for cos() which is faster but less accurate; I just use the C math library which makes it simpler but slower - lines 415,419-433 of Pd's code are implementing something like `cos(cf)` and `sin(cf)`)

the process is extracting the core mathematics/algorithms, and hardcoding it in C without any of the wrapping API layers that make it useable from a patcher system

Sign in to participate in the conversation
post.lurk.org

Welcome to post.lurk.org, an instance for discussions around cultural freedom, experimental, new media art, net and computational culture, and things like that.