title: How to generate proper pink noise and filtering by a custom peak filter in Python
body: <p>I'm dealing with the problem of filtering a pink noise with a peak filter (the final goal is to equalize an input signal). I've been designing the peak filter myself to get more familiar with 1D signal filtering. As for the pink noise, I'm using pink noise generated through the work already done in <a href="https://github.com/felixpatzelt/colorednoise/blob/master/colorednoise.py" rel="nofollow noreferrer">https://github.com/felixpatzelt/colorednoise/blob/master/colorednoise.py</a> .</p>
  
  <p>1/ I am wondering why the intensity of the power spectrogram is random when I run several times the same function with the same paramaters, is it due to the call to <code>numpy.random.normal</code> ? How would someone proceed to generate a noise in a specified range of values ?
  The two following pictures show that the power range is inconstant through different runs (cannot post images directly, sorry for the imgur links) :</p>
  
  <ul>
  <li><a href="https://imgur.com/lF0MAGV" rel="nofollow noreferrer">https://imgur.com/lF0MAGV</a></li>
  <li><a href="https://imgur.com/Yzvl8Ua" rel="nofollow noreferrer">https://imgur.com/Yzvl8Ua</a></li>
  </ul>
  
  <p>2/ Following is the definition of the peak filter I use further :</p>
  
  <pre class="lang-py prettyprint-override"><code>class PeakFilter():
      def __init__(self, center_freq, sample_rate, Q, gainDB):
          self.center_freq = center_freq
          self.sample_rate = sample_rate
          self.gainDB      = gainDB
          self.Q           = Q
  
          # derived quantities
          self.A  = 10**(self.gainDB/40)
          self.center_freq = 2*np.pi * self.center_freq / self.sample_rate
  
      def peak_transfer(self):
          b = np.array([ 1, self.A/self.Q, 1 ])
          a = np.array([ 1, 1/(self.A*self.Q), 1])
  
          # shift to center frequency
          b, a = signal.lp2lp(b, a, wo=self.center_freq)
          return b, a
  
  
  sample_rate = 44100
  fc = 1000
  Q = 1.7
  Gdb = 5
  peak_filt = PeakFilter(fc, sample_rate, Q, Gdb)
  
  b, a = peak_filt.peak_transfer()
  w, h = signal.freqs(b, a, 10000)
  freq = w*sample_rate/2/np.pi
  
  fig, ax = plt.subplots(1, 1, figsize=(8, 6))
  ax.plot(freq, 20*np.log10(abs(h)), color='blue')
  ax.set_xscale('log')
  plt.grid('true')
  plt.plot()
  </code></pre>
  
  <p>The filter response has the expected shape :</p>
  
  <p><a href="https://imgur.com/bImjymX" rel="nofollow noreferrer">https://imgur.com/bImjymX</a></p>
  
  <p>However, when I am filtering the noise by this filter with this code:</p>
  
  <pre class="lang-py prettyprint-override"><code>out = signal.filtfilt(b, a, noise)
  plt.plot(out, color='red')
  </code></pre>
  
  <p>I get the following result:</p>
  
  <p><a href="https://imgur.com/k7a4DoR" rel="nofollow noreferrer">https://imgur.com/k7a4DoR</a></p>
  
  <p>This is were I find difficult to judge if this is correct. First I do not know why the filtered noise gets this shape and such values (negative as well). Also, I would expect the filtered signal to vary in shape or intensity, with <code>Gdb</code> and <code>Q</code>, at the given center frequency, but it does not.
  There should be attenuation or boost just around this frequency (if I got it right).</p>