[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[sc-users] FFT filtering with linear or exponential partial freq series
some FFT filter experiments for anyone who's interested in doing
something similar ....
ciao, -sciss-
/////////////////////////////////
s.boot;
~soundPath = "sounds/AlphavilleIlArrive.aif"; // should be monophonic!!
~fftSize = 4096; // evtl. mit 2048 oder 8192 (das ist der hoechste
erlaubte wert) probieren?
~filter = Buffer.alloc( s, ~fftSize, 1 );
~sound = Buffer.read( s, ~soundPath );
~fftBuf = Buffer.alloc( s, ~fftSize, 1 );
// ERSTER VERSUCH : LINEARE FILTER-FREQUENZEN
~freq = 140;
~filter.loadCollection([ Array.fill( ~fftSize.div(2), { arg i; var
freq = s.sampleRate/~fftSize * i, nextFreq = s.sampleRate/~fftSize *
(i+1); if( freq.div(~freq) < nextFreq.div(~freq), 1, 0 )}), Array.fill
( 1024, 0 )].lace );
(
x = { arg out = 0, amp = 1;
var in, chain;
in = PlayBuf.ar(1, ~sound.bufnum, BufRateScale.kr( ~sound.bufnum ),
loop: 1);
chain = FFT( ~fftBuf.bufnum, in );
chain = PV_Mul( chain, ~filter.bufnum );
Out.ar( out, amp * IFFT( chain ) );
}.play;
)
~freq = 100;
~filter.loadCollection([ Array.fill( ~fftSize.div(2), { arg i; var
freq = s.sampleRate/~fftSize * i, nextFreq = s.sampleRate/~fftSize *
(i+1); if( freq.div(~freq) < nextFreq.div(~freq), 1, 0 )}), Array.fill
( 1024, 0 )].lace );
/// NEUER VERSUCH : GEOMETRISCHE FILTER-FREQUENZEN
~baseFreq = 30;
~factor = 2.pow(1/7);
~freqs = Array.geom( 1000, ~baseFreq, ~factor; ).reject(_ >
(s.sampleRate/2));
~filterMag = Array.fill( ~fftSize.div(2), 0 );
// das spektrum wird einfach berechnet, indem die jeweils naechsten
FFT-bins gefuellt werden (gewichtet nach der tatsaechlichen lage der
frequenz). die phasen sind alle Null
~freqs.do({ arg freq; var band = freq / s.sampleRate * ~fftSize,
bandLo = band.floor.asInteger, bandHi = band.ceil.asInteger, weightHi
= band % 1.0, weightLo = 1 - weightHi; ~filterMag[ bandLo ] = min( 1,
~filterMag[ bandLo ] + weightLo ); ~filterMag[ bandHi ] = min( 1,
~filterMag[ bandHi ] + weightHi ); });
~filter.loadCollection([ ~filterMag, Array.fill( 1024, 0 )].lace );
/// 3. : MIT KOMPLEMENTAEREM SPEKTRUM (SUMME MUSS AUSGANGSKLANG
ENTSPRECHEN)
x.free;
~filterInv = Buffer.alloc( s, ~fftSize, 1 );
~fftBufInv = Buffer.alloc( s, ~fftSize, 1 );
~filterMagInv = 1 - ~filterMag;
~filterInv.loadCollection([ ~filterMagInv, Array.fill( 1024,
0 )].lace );
(
y = { arg out = 1, amp = 2, ampInv = 0.125;
var inA, chainA, inB, chainB;
inA = PlayBuf.ar(1, ~sound.bufnum, BufRateScale.kr( ~sound.bufnum ),
loop: 1);
chainA = FFT( ~fftBuf.bufnum, inA );
chainB = FFT( ~fftBufInv.bufnum, inA );
chainA = PV_Mul( chainA, ~filter.bufnum );
chainB = PV_Mul( chainB, ~filterInv.bufnum );
Out.ar( out, [ amp * IFFT( chainA ), ampInv * IFFT( chainB )]);
// Out.ar( out, (amp * (IFFT( chainA ) + IFFT( chainB ))));
}.play;
)
y.free;
~filter.free; ~filterInv.free; ~fftBuf.free; ~fftBufInv.free;
~sound.free;