0
$\begingroup$

I want to calculate the room impulse response in real-time using sine sweep method. For that, I generated a sine sweep $x$ & its amplitude modulated inverse signal $f$. Then I played that $x$ signal and simultaneously recorded this in the variable $myrecording$. Then I applied convolution on the amplitude modulated inverse signal $f$ and $myrecording$ to get the $Room Impulse Response$ as:

$$RoomImpulseResponse = myrecording * f$$

I followed the below mentioned post to find Room Impulse Response: How to use deconvolution technique to find out impulse response?

Now my concern is that after following this procedure, I'm not getting the expected results. I've also attached a graph for this. Am I making any mistake?

   from scipy.signal import max_len_seq
   import numpy as np
   import matplotlib.pyplot as plt
   import simpleaudio as sa
   import sounddevice as sd
   import scipy.signal as sig
   from scipy.signal import chirp
   from scipy.io.wavfile import write
   
   
   # x = max_len_seq(12)[0]
   myrecording = None
   
   # Sweep Parameters
   f1 = 4000
   f2 = 5000
   T = 0.1
   fs = 48000
   t = np.arange(0, T * fs) / fs
   R = np.log(f2 / f1)
   
   # ESS generation
   x = np.sin((2 * np.pi * f1 * T / R) * (np.exp(t * R / T) - 1))
   # Inverse filter
   k = np.exp(t * R / T)
   f = x[::-1] / k
   
   def play():
       play_obj = sa.play_buffer(x, 1, 2, 48000)
       play_obj.wait_done()
   
   def record():
       global myrecording
       myrecording = sd.rec(int(3.0 * 48000), samplerate=48000, channels=1).squeeze()
       write("myrecording.wav", 48000, myrecording.astype(np.int16))
       sd.wait()
   
   def chunks(lst, chunkSizeInms, samplingRate):
       """Yield successive n-sized chunks from lst."""
       chunks = []
       n = round((samplingRate / 1000) * chunkSizeInms)
       for i in range(0, len(lst), n):
           chunks.append((lst[i:i + n]).astype(np.float32))
   
       return chunks
   
   
   if __name__ == '__main__':
       t1 = threading.Thread(target=play())
       t2 = threading.Thread(target=record())
   
       # starting thread 1
       t1.start()
       # starting thread 2
       t2.start()
   
       # wait until thread 1 is completely executed
       t1.join()
       # wait until thread 2 is completely executed
       t2.join()
   
       correlation_result = list()
   
       convolution_result = np.convolve(myrecording, f, mode='full');
       peak_delay = np.argmax(np.abs(convolution_result)) / 48
       print(peak_delay)
       plt.plot(convolution_result)
       plt.title('Delay in ms (peak): T = %i ms' % peak_delay)
       plt.show()

enter image description here

$\endgroup$
5
  • $\begingroup$ Your frequency range is quite narrow (4kHz - 5kHz), you should definitely use a broader frequency range. Secondly, your sweep is very short - in order to get good results, its length should be at least expected RT60 (start with 2 seconds). I suggest to first do the recording of the sweep and run your code offline. $\endgroup$
    – jojek
    Sep 1 '21 at 10:44
  • $\begingroup$ @jojek , Could you please explain the steps which I should follow in order to make a correct RIR graph? $\endgroup$ Sep 1 '21 at 11:09
  • $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$
    – jojek
    Sep 1 '21 at 11:10
  • $\begingroup$ Room impulse response measurements are very difficult because of noise and distortion problems. For an overview of different methods and a comparison see for example: people.montefiore.uliege.be/stan/ArticleJAES.pdf $\endgroup$
    – Hilmar
    Sep 1 '21 at 11:17
  • 1
    $\begingroup$ @jojek , Thank you so much for guiding. There was an issue while playing the sine sweep. I've corrected that and it is working fine now. $\endgroup$ Sep 1 '21 at 12:26

Your Answer

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

Browse other questions tagged or ask your own question.