<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>Hi List,<br><br>I was wondering if someone might be able to help with a performance issue I am having with ChucK in respect to the use of FFT/IFFT.<br><br>I've written a Pulsar Generator and I've added a convolution function to the pulse train of the generator.&nbsp; I found a previous thread that I've used as a basis for the convolution (see the posting below).&nbsp; The main change was to replace the following line:<br><pre><i>adc =&gt; Gain input =&gt; FFT fftx =&gt; blackhole;</i><br><br>with this one:<br><br><i>SinOsc sin =&gt; WinFuncEnv env =&gt; Pan2 pan =&gt; Gain input =&gt; FFT fftx =&gt; blackhole;</i><br></pre>At rest, the JACK DSP Load is about 2.2%.&nbsp; When I run the Pulsar Generator at a reasonable rate, the DSP Load jumps to about 3.5% or so without convolution.&nbsp; When I add the convolution function as below, it quickly jumps to a 100% usage with steady Xruns.&nbsp; The sample sizes I am using for the SndBuf statement below are somewhere between 18000 and 28000 samples.<br><br>Is there a strategy anyone could suggest to achieve greater performance of the convolution function below or are there alternative strategies for implementing convolution in general?&nbsp; I'd appreciate any advice.<br><br>+++<br><h1>[chuck-users] Daniel: Convolution (FFT version)</h1>
    <b>Perry R Cook</b> 
    <a href="mailto:chuck-users%40lists.cs.princeton.edu?Subject=Re:%20Re%3A%20%5Bchuck-users%5D%20Daniel%3A%20Convolution%20%28FFT%20version%29&amp;In-Reply-To=%3C1484f078-b1dd-48bf-b974-796b4b7a3c69%40suckerpunch-mbx-7.cs.princeton.edu%3E" title="[chuck-users] Daniel: Convolution (FFT version)">prc at CS.Princeton.EDU
       </a><br>
    <i>Tue Nov 25 19:09:31 EST 2014</i>
    <ul><li>Previous message: <a href="https://lists.cs.princeton.edu/pipermail/chuck-users/2014-November/007808.html">[chuck-users] Daniel: Convolution
</a></li><li>Next message: <a href="https://lists.cs.princeton.edu/pipermail/chuck-users/2014-November/007809.html">[chuck-users] chugins won't compile
</a></li><li> <b>Messages sorted by:</b> 
              <a href="https://lists.cs.princeton.edu/pipermail/chuck-users/2014-November/date.html#7807">[ date ]</a>
              <a href="https://lists.cs.princeton.edu/pipermail/chuck-users/2014-November/thread.html#7807">[ thread ]</a>
              <a href="https://lists.cs.princeton.edu/pipermail/chuck-users/2014-November/subject.html#7807">[ subject ]</a>
              <a href="https://lists.cs.princeton.edu/pipermail/chuck-users/2014-November/author.html#7807">[ author ]</a>
         </li></ul>
    <hr>  

<pre>FFT version.

Most efficient, lots of delay.  Could chunk up 
and factor, overlap-add for less delay.  This is
the basic idea tho.


// FFT convolution with static impulse response
// by Perry R. Cook, November 2014
// upsides:  as efficient as it could be, save for 
//           constructing a specific fft convolution chugin
// downsides: minimum delay is length of impulse response + buffers
// fix:      break into pieces and overlap add
//  Other fix:  see filter version using my FIR Filter chugin

// our fixed convolution kernal (impulse response)
SndBuf s =&gt; FFT ffth =&gt; blackhole;  
"CelloBodyShort.wav" =&gt; s.read; // whatever you like (caution of length!!)
2 =&gt; int fftSize;
while (fftSize &lt; s.samples()) 
    2 *=&gt; fftSize;           // next highest power of two
fftSize =&gt; int windowSize;   // this is windowsize, only apply to signal blocks
windowSize/2 =&gt; int hopSize; // this can any whole fraction of windowsize
2 *=&gt; fftSize;               // zero pad by 2x factor (for convolve)
// our input signal, replace adc with anything you like
adc =&gt; Gain input =&gt; FFT fftx =&gt; blackhole;  // input signal
IFFT outy =&gt; dac;            // our output
fftSize =&gt; ffth.size =&gt; fftx.size =&gt; outy.size; // sizes
Windowing.hann(windowSize) =&gt; fftx.window;
//   &lt;&lt;&lt; s.samples(), fftSize &gt;&gt;&gt;;
windowSize::samp =&gt; now;     // load impulse response into h
ffth.upchuck() @=&gt; UAnaBlob H; // spectrum of fixed impulse response
s =&lt; ffth =&lt; blackhole;      // don't need impulse resp signal anymore

complex Z[fftSize/2];
1000 =&gt; input.gain;          // fiddle with this how you like/need

while (true)  {
    fftx.upchuck() @=&gt; UAnaBlob X; // spectrum of input signal

    // multiply spectra bin by bin (complex for free!):
    for(0 =&gt; int i; i &lt; fftSize/2; i++ ) {
        fftx.cval(i) * H.cval(i) =&gt; Z[i];        
    }    
    outy.transform( Z );      // take ifft
    hopSize :: samp =&gt; now;   // and do it all again
}

Regards,<br>Mitch <br></pre><br>                                               </div></body>
</html>