title: How to implement overlap add method?
body: <p>I implemented my filter, where <strong>overlap add method</strong> to prevent circular convultion is used.<br>
  input - file with noise, output should be filtered file.<br>
  <strong>My result:</strong> out is slightly modified, frequencies aren`t cut</p>
  
  <p>My guess is that I wrongly multiply in the frequency domain input signal on the filter kernel
  (My intention is to cut off frequencies that aren't in range [300,3700]). How multiplication should be done?</p>
  
  <p>I construct kernel using blackmanwindow - is my understanding correct? ( I compute amount of frequency per one sample of filter, then go through samples and see if it is in range I want to cut off I calculate frequency using formula for Blackman window.)</p>
  
  <p>I just started learning DSP.</p>
  
  <p>Here is my implementation (what is wrong with it???):</p>
  
  <pre><code>void DeleteFrequencies(char* fileWithNoise, char* resultFile, const int bufferSize, int lowestFrequency, int highestFrequency, int sampleRate )
  {
  
  
      // |1|. files
          std::fstream in;
          std::fstream out;
  
  in.open (fileWithNoise, std::ios::in | std::ios::binary);
  out.open(resultFile, std::ios::out | std::ios::binary);
  
  // |2|. Filter kernel design. I shall use blackman window
      // fundamental params
  const int filterKernelLength = 200; // 512
  const int filterMaxFrequency = sampleRate / 2; // 8000 / 2
  const int frequencyPerSamle = filterMaxFrequency / filterKernelLength;
  double *RealFilterResp = new double [bufferSize / 2];
  double *ImmFilterResp = new double [bufferSize / 2];
      // coefficients for Blackman window
  const double a0 = 0.42659;
  const double a1 = 0.49656;
  const double a2 = 0.076849;
      // construct filter kernel
  for (int i = 0 ; i &lt; bufferSize / 2; ++i)
  {
      if ( i &gt;= filterKernelLength ) // padd filter kernel with zeroes
      {
          RealFilterResp[i] = 0;
          ImmFilterResp[i] = 0;
      }
      else if (i * frequencyPerSamle &lt; lowestFrequency || i * frequencyPerSamle &gt; highestFrequency)
      {
          // apply blackman window (to eleminate frequencies &lt; 300 hz and &gt; 3700 hz)
          RealFilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
          ImmFilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
      }
      else
      {
          RealFilterResp[i] = 1;
          ImmFilterResp[i] = 1;
      }
  }
  
  // |3|. overlap add method
      // calculate parameters for overlap add method (we use it to prevent circular convultion)
  const int FFT_length = pow (2.0 ,(int)(log(bufferSize + filterKernelLength - 1.0)/log(2.0)) + 1.0);
  double *OLAP = new double[bufferSize / 2 ]; // holds the overlapping samples from segment to segment
  memset(OLAP,0, bufferSize / 2 * sizeof (double));
  
  double *RealX = new  double[bufferSize];
  memset(RealX, 0, bufferSize * sizeof(double)); 
  double *ImmX = new  double[bufferSize];
  memset(ImmX, 0, bufferSize * sizeof(double)); 
  
  
  short* audioDataBuffer = new short[bufferSize];
  memset(audioDataBuffer, 0 , sizeof(short) * bufferSize);
  
      // start reading from file by chunks of bufferSize
  while (in.good())
  {
      // get proper chunk of data
      FillBufferFromFile(audioDataBuffer, bufferSize, in); // read chunk from file
      ShortArrayToDoubleArray(audioDataBuffer, RealX, bufferSize); // fill RealPart
  
  
      ForwardRealFFT(RealX, ImmX, bufferSize); // go to frequency domain
  
      // perform convultion as multiplication in frequency domain
      for (int j = 0; j &lt; bufferSize / 2; ++j)
      {
          double tmp = RealX[j] * RealFilterResp[j] - ImmX[j] * ImmFilterResp[j];
          ImmX[j] = RealX[j] * ImmFilterResp[j] + ImmX[j] * RealFilterResp[j];
          RealX[j] = tmp;
      }
  
      // Inverse FFT
      ReverseRealFFT(RealX, ImmX, bufferSize); // go to time domain
  
      // add last segment overlap to this segment
      for (int j = 0; j &lt; filterKernelLength - 2; ++j )
      {
          RealX[j] += OLAP[j];
      }
  
      // save samples that will overlap the next segment
      for (int j = bufferSize/2 + 1; j &lt; bufferSize; ++j )
      {
          OLAP[j - bufferSize/2 - 1] = audioDataBuffer[j];
      }
  
      // write results
  
      DoubleArrayToShortArray(RealX, audioDataBuffer, bufferSize);
      FillFileFromBuffer(audioDataBuffer, bufferSize, out);
  }
  
  /*ReverseRealFFT(RealX, ImmX, bufferSize
  );
  DoubleArrayToShortArray(RealX, audioDataBuffer, bufferSize);*/
  delete [] audioDataBuffer;
  delete [] RealFilterResp;
  delete [] ImmFilterResp;
  delete [] OLAP;
  delete [] RealX;
  delete [] ImmX;
  in.close();
  out.close();
  </code></pre>
  
  <p>}</p>