Signal Processing Stack Exchange is a question and answer site for practitioners of the art and science of signal, image and video processing. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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


share|improve this question
Is this the paper you're reading? – datageist Feb 21 '13 at 20:04
Yep it is the paper, very interested in the feature engineering it did! – Newmu Feb 21 '13 at 20:15
up vote 1 down vote accepted

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.

share|improve this answer
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. – Newmu Feb 22 '13 at 8:54

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.