Unorthodox ways of filtering and distort a sound file

Hi folks,

I am a SC beginner, and I feel that I tend to reproduce the same strategies when it’s about to filter and distort a sample based signal. (typically a sound file played throught a buffer): basically using the different UGens filters and applying the .abs, .cubed . soft (and so on) techniques of distortion. I would like to open my mind a little bit and to know if you have techniques based on a totally different principle. As an example, techniques that would use the most primitive instance of a soundfile (frames by frames, fourier analysis, wave deconstruction…) in order to process radically the spectrum and the dynamic of the sample. I know it could sounds quite general but any fresh idea would be great.

As an example, I would like to understand how I could:

1/ reverse the spectrum of a sample based signal : attenuate radically the frequencies where the energy is dense, while boosting where it is really low. Would it be possible to determinate for instance 32 band of frequencies, get the datas (as a spectrogram do) and proportionally reverse its spectral density, like a weird mirror ?

2/ applying a full wave rectification distortion?

3/ to rearrange the sample order of a signal, backwards (the last sample becomes the first sample. The second-to-last sample becomes the second sample and so on) or even on a random order?

Thanks a lot.

1 Like

i would suggest messing with different sample rates and bit depths. also, interpreting something in a different encoding will drastically change it and often add a lot of distortion, f.ex. signed pcm -> unsigned, signed pcm -> floating-point pcm.

Hi,

very different topics:

ad (1): See PV_MagDiv, imo one of the most exciting PV UGens, be careful with amplitudes! Clearly it can produce harsh noise, see the ‘zeroed’ arg.

ad (2): Rectifying is easy, e.g. with if ugen

(
SynthDef(\rectifier, { |out = 0, freq = 400, amount = 0, amp = 0.1|
	var sig = SinOsc.ar([freq, freq * 1.01], 0, amp);
	// use collect as the if ugen doesn't multichannel expand
	sig = sig.collect { |x,i| x.ceil.if(x, sig[i].abs * amount) };
	Out.ar(out, sig);
}).add;
)

// half wave rectifier
y = Synth(\rectifier)

s.scope

// full wave rectifier
y.set(\amount, 1)

y.set(\amount, 0)

// "medium" rectifying
y.set(\amount, 0.5)

y.free

ad (3): Manipulating audio data in the language is also a very interesting synthesis option. Simple reversing can be done with a negative playback rate in PlayBuf also, but there are lots of operations you cannot do in realtime.

// load soundfile
(
p = Platform.resourceDir +/+ "sounds" +/+ "a11wlk01-44_1.aiff";
b = Buffer.read(s, p);
)


// move data to SC lang
b.loadToFloatArray(action: { |b| x = b; "done".postln })


// now do what you like e.g. clump and repeat
(
y = x.clump(1000).collect { |a| a ! rrand(2, 5) }.flat.as(FloatArray);
z = x.clump(1000).collect { |a| a ! rrand(2, 5) }.flat.as(FloatArray);
)

(
// allocate new buffers
m = max(y.size, z.size);
c = Buffer.alloc(s, m, 1);
d = Buffer.alloc(s, m, 1);
)

(
// move data to server
c.loadCollection(y, action: { "L done".postln });
d.loadCollection(z, action: { "R done".postln });
)


// play
a = { PlayBuf.ar(1, [c, d], loop: 1) }.play

a.release
4 Likes

thanks for this ! excited to try

But maybe better style to use Select as it does multichannel expanding. Code is shorter, but also a bit tricky: instead of a single index to choose we have the stereo signal sig.ceil, its “left” channel decides from which of the two stereo signals (sig.abs * amount, sig) the left channel of the resulting signal should be taken, analogously for the right channel. If this sounds cryptic check the mono version first.

(
SynthDef(\rectifier_2_mono, { |out = 0, freq = 400, amount = 0, amp = 0.1|
	var sig = SinOsc.ar(freq, 0, amp);
	sig = Select.ar(sig.ceil, [sig.abs * amount, sig]);
	Out.ar(out, sig ! 2);
}).add;
)


(
SynthDef(\rectifier_2_stereo, { |out = 0, freq = 400, amount = 0, amp = 0.1|
	var sig = SinOsc.ar([freq, freq * 1.01], 0, amp);
	sig = Select.ar(sig.ceil, [sig.abs * amount, sig]);
	Out.ar(out, sig);
}).add;
)


// half wave rectifier
y = Synth(\rectifier_2_stereo)

// y = Synth(\rectifier_2_mono)


s.scope

// full wave rectifier
y.set(\amount, 1)

y.set(\amount, 0)

// "medium" rectifying
y.set(\amount, 0.5)

y.free
1 Like