The goal is to get a 200ms decaying delay of an audio signal while preserving the sharpness of attacks to mimick human perception of sound. The paper I'm following convolves a 200ms half-Hanning window with each frequency band to simulate it.

I'm using numpy.hanning() since there's no half-Hanning and have tried either setting the first half of the hanning window to 0, the first half to 1, or chopping it off and only using the second half. I'm also normalizing the window to keep scales the same.

Since I don't really know, which one of these would be the "correct" half-Hanning?

The chopping off version, which seems the most likely to me, works but is offshifted 100 ms to the left. Should I just shift it 100ms to the right and call it good?

dataMasked = np.zeros(data.shape)
for i in xrange(freqs.size): # Loop through each frequency band
    winSize = round(0.4/(length/bins.size)) #Calc win size
    hann = np.hanning(winSize)
    halfPoint = np.argmax(hann)
    hann = hann[halfPoint:] #Chop at half
    hann = normHann(hann)
    dataMasked[i,:] = np.convolve(data[i,:],hann,mode='same')

Here's the plot of what I'm getting (blue is raw loudness curve, while green is adjusted).

a Loudness Plot

The paper I'm following shows this:

a Paper Loudness Plot



Using the second half only (chopping) is the correct way. Note that setting the first half to zero is actually the same thing, up to a constant delay. The 100ms delay you observe might be due to the use of the "same" flag for the numpy convolution. It seems to me that the right truncation for this application would be to use numpy.convolve(signal, window, 'full')[:len(signal)] - without the kind of centering that 'same' does.

As you have noticed, the peaks in the smoothed envelope function do not exactly coincide with the peaks in the original envelope and there is no magic trick to make them coincide (the delay will depend on the sharpness of the attack) - so the resulting curve is not ideal for very accurate beat detection and chopping.

  • $\begingroup$ Thanks, the segmentation function is based on finding peaks in the spectral flux, and seeking back to local minima in the loudness function (corresponding to the quietest moment before the beginning of the new segment) which should be robust enough if the sharpness of attacks is preserved. Not doing beat detection currently. $\endgroup$ – Newmu Feb 22 '13 at 8:54

Your Answer

