[chuck-users] DSP question: accumulating frequency info using FFT?

Jascha Narveson jnarveson at wesleyan.edu
Sat Oct 14 12:26:47 EDT 2017


Chuck list! Help!

I have the following idea and I’d like to hear what it sounds like:

- play a sound into an FFT
- as the FFT runs, for each bin:
- - look at the magnitude info
- - take a small fraction of this info and store it in a running total
- - let the phase pass through unchanged
- use the spectral data in the running total for the IFFT

What I was hoping for was a slow emerging smear of all the frequencies from the input sound, kind of like a weird version of some kind of “infinite sustain” reverb.  

What I’m getting is the attacks of the original sound coming through, although fading in, and covered with noise.  

I think I’m doing something wrong by not doing something with the phase, but I’m not sure what.

I’d love some advice…

cheers,

j


- - - - c o d e  e x a m p l e - - - - 

SinOsc synth => FFT fft => blackhole;
UAnaBlob blob;
IFFT ifft => dac;

synth.freq(440);
synth.gain(0.1);

// set parameters
2048 => fft.size;

// place to hold the FFT data as it comes in
complex spec[fft.size()/2];

// place to store the accumulated FFT data, preload with zeroes
complex acc[fft.size()/2];
for(0 => int i; i < acc.cap(); i++) {
  #(0, 0) => acc[i];
}

// do it!
spork ~ sawTune();
spork ~ accumulateFrequenciesViaFFT();

while (true) {
  1::second => now;
}

fun void accumulateFrequenciesViaFFT() {
  while( true )
  {
      fft.upchuck() @=> blob;
      // get the data
      blob.cvals() @=> spec;

      // for every bin...
      for(0 => int i; i < spec.cap(); i++) {
        // get the mag/phase for each bin by converting to polar
        spec[i] $ polar => polar newBin;

        // and get our running totals from acc
        acc[i] $ polar => polar accBin;

        // scale the inocming mag and add it to acc
        newBin.mag * 0.001 +=> accBin.mag;

        // let phase pass through
        newBin.phase => accBin.phase;
				/*Math.random2f(0, TWO_PI) => accBin.phase;*/

        // convert back to complex and put back in the acc array
        accBin $ complex => acc[i];
      }

      ifft.transform(acc);
      fft.size()::samp => now;
  }
}

fun void sawTune() {
  while (true) {
    Math.random2(48, 72) => int midinote;
    Math.mtof(midinote) => synth.freq;
    333::ms => now;
  }
}



More information about the chuck-users mailing list