0
$\begingroup$

I have an audio clip and I copy a 256-point part satarting at 10th second. Then I create a 256-point frame on the original clip. At every itreation, I calculate the DFT of the frame, multiply it with the DFT of the interval I copied, take the mean of the result and append it to a list and shift the frame 1 point right. When I graph the means, I know I should get the maximum value of convolution when the copied interval's DFT is multiplied with itself. And this is supposed to show that convolution can be used as a similarity metric. However, when I apply the explained procedure, I can't get a peak that is distinguishable from any other value. What I have done is as follows:

    import numpy as np
    import scipy.io.wavfile
    import matplotlib.pyplot as plt
    
    rate1, data1 = scipy.io.wavfile.read('Africa.wav')
    
    data1 = np.array(data1, dtype=np.float64)
    
    interval_1 = data1[rate1 * 10: rate1 * 10 + 256]
    
    dft_1 = np.fft.fft(interval_1)
    
    cv = []
    
    for i in range(data1.size - 256):
        dft = np.fft.fft(data1[i: i + 256])
        Y = np.multiply(dft, dft_1)
        Y = np.abs(Y)
        Y = np.mean(Y)
        cv.append(Y)
    
    cv = np.array(cv)
    
    plt.figure()
    plt.title("Convolution with 256 point sample at 10th second")
    plt.xlabel("Samples")
    plt.ylabel("Amplitude")
    plt.plot(cv)
    plt.show()

I get the following graph:

enter image description here

$\endgroup$
0
$\begingroup$

The fft product alone is not the convolution, but the frequency domain of the convolution. To complete the operation the OP must also take the inverse FFT to get a circular convolution result.

$$CONV = \text{ifft}(\text{fft}(a) \text{fft}(b))$$

However, similarity would be determined using correlation not convolution. To do this, simply complex conjugate one of the FFT results as follows:

$$XCORR = \text{ifft}(\text{fft}(a) \text{fft}^*(b))$$

The above is the cross-correlation function (using circular convolution). The result is the correlation of $a$ and $b$ at repeated circular shifts in time.

| improve this answer | |
$\endgroup$
  • $\begingroup$ when I use dft_1's conjugate, use ifft and remove the np.abs() so that I'm calculating xcorr, I am getting a very similar graph. Is taking the mean wrong? $\endgroup$ – Rookie Jun 25 at 15:58
  • $\begingroup$ And can you look at this question dsp.stackexchange.com/questions/54970/… . It is stated that sum of multiplication of dfts can be used for similarity. $\endgroup$ – Rookie Jun 25 at 16:04
  • 1
    $\begingroup$ @Rookie Test your approach using the same sequence (auto correlation) to see if you are doing things correctly. $\endgroup$ – Dan Boschen Jun 25 at 16:34
  • 1
    $\begingroup$ @Rookie whether in the time or frequency domain, you are going to have to apply this in a "sliding window" kind of way, is this understood? We are not talking about doing this "multiplication" just once. Is that clear? $\endgroup$ – A_A Jun 26 at 10:16
  • 1
    $\begingroup$ D.B. I may have not put my comment at the right place. I was refering to the OP. It is not an objection to your response. Purely going by the description provided (looking for small segment in a bigger stream), whether performed in the time or frequency domain, the correlation would have to be applied in a sliding window way. That was the message. @Rookie,I agree that you seem to be occupied with some "average".Please, don't.There is no averaging here. Just a sum that will shoot to a high value when the segments allign.Try to do the same by applying plain simple correlation first. $\endgroup$ – A_A Jun 26 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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