LCAV / pyroomacoustics

Pyroomacoustics is a package for audio signal processing for indoor applications. It was developed as a fast prototyping platform for beamforming algorithms in indoor scenarios.
https://pyroomacoustics.readthedocs.io
MIT License
1.46k stars 432 forks source link

Trying to find the distance between the source and the microphones #61

Closed akhilvasvani closed 2 days ago

akhilvasvani commented 5 years ago

Hi,

I am trying to find the distance between the center of my microphone array and the source sound in a 3-D environment. I have looked through the source code, and I see it can support it. However, I am unsure of two things. The first is if the DOA methods—SRP, MUSIC, TOPS, FRIDA—themselves can support source localization in 3-d. And secondly, regardless if they can or cannot, I am trying to use the algorithms so find me the distance between the source and the center of my microphone array. Is this possible to do?

NOTE: I have put in comments safety check for a comparison sake. I would like to remove this once I figure out the problems listed above.

See my code below:

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from scipy.signal import fftconvolve
import IPython
import pyroomacoustics as pra

#Build 3-D Representation of the room
room = pra.ShoeBox([13.75,8.66,9.5], fs=16000, absorption=0.35, max_order=17)

#Add Source
 fs,signal
=wavfile.read("/Users/akhilvasvani/Downloads/cmu_us_awb_arctic/wav/arctic_b0528.wav")

room.add_source([(13.75/2),(8.66/2),(9.5/2)], signal=signal)

#Add 12-microphone array
R = np.c_[       # [x, y, z]
    [2.85, 0, 0.49], # mic 4
    [4.82, 0, 0.49], # mic 8
    [5.80, 0, 0.49], # mic 12
    [2.85, 0, 2.65], # mic 3
    [4.82, 0, 2.65], # mic 7
    [5.80, 0, 2.65], # mic 11
    [2.85, 0, 4.81], # mic 2
    [4.82, 0, 4.81], # mic 6
    [5.80, 0, 4.81], # mic 10
    [2.85, 0, 6.97], # mic 1
    [4.82, 0, 6.97], # mic 5
    [5.80, 0, 6.97]  # mic 9
    ]

room.add_microphone_array(pra.MicrophoneArray(R, room.fs))

fig, ax = room.plot()
ax.set_xlim([0, 14])
ax.set_ylim([0, 9]);
ax.set_zlim([0, 10]); # for 3-d

room.simulate()

from pyroomacoustics.doa import great_circ_dist

#Safety-Check
center = [4.325, 0, 3.730]
source = [(13.75/2),(8.66/2), (9.5/2)] # I have specified the source location. 
temp = np.arctan([0,(source[2]-center[2])/(source[0]-center[0])]) #for some dumb reason, we need to have an array with[0, (desired value)]
radius = np.sqrt(((source[2]-center[2])**2)+((source[0]-center[0])**2)) #

azimuth = temp[1] # in radians
c = 343.    # speed of sound
fs = 16000  # sampling frequency
nfft = 256  # FFT size
freq_range = [2900, 3500]

X = np.array([pra.stft(signal, nfft, nfft // 2, transform=np.fft.rfft).T for signal in room.mic_array.signals])

# Now we can test all the algorithms available
algo_names = ['SRP', 'MUSIC', 'FRIDA', 'TOPS'] 
spatial_resp = dict()

for algo_name in algo_names:
    # Construct the new DOA object
    # the max_four parameter is necessary for FRIDA only
    doa = pra.doa.algorithms[algo_name](L=R, fs=fs, nfft=nfft, c=c, num_src=1, max_four=4)

    doa.sph_plot_diracs()
    plt.title(algo_name)

    # doa.azimuth_recon contains the reconstructed location of the source
    print(algo_name)
    print('  Recovered azimuth:', doa.azimuth_recon / np.pi * 180., 'degrees')
    print('  Error:', great_circ_dist(azimuth, doa.azimuth_recon) / np.pi * 180., 'degrees')

    plt.show()
    print((doa.azimuth_recon))
jay-pee commented 5 years ago

As far I know, you can't calculate distance with these algorithms. There are efforts made to calculate the distance from the coherent-to-defuse ratio but this is not very reliable, because it is strongly depended on the room measures. However, this would be of course very helpful for a lot of applications. From this algorithms you only get azimuth and elevation angle.

fakufaku commented 5 years ago

That is correct, most of these algorithms only return the angles. With the exception of SRP-PHAT which seems to have a near field mode (see the doc ans source). In this case, you also provide a list of candidate distances r which is used to produce mode vectors with different norms. I don't know if the near field SRP has been really tested, so please let us now the result.

akhilvasvani commented 5 years ago

I have tried testing it with several radius values. Not much difference. Anyhow, solved a couple of my problems. Thank you.

fakufaku commented 5 years ago

@akhilvasvani One last thing, I saw that your microphones are separated by several meters. In that case, the frequency range [2900, 3500] will be plagued by aliasing. You need to use much lower frequency, say [100, 500].

akhilvasvani commented 5 years ago

Ok, I made a mistake. I inputted all my microphones and room dimensions in inches instead of centimeters. Now that I have corrected that—all my numbers are a LOT smaller.

I know you mentioned that: "The spacing should be somewhere around half or a quarter of the wavelength of the frequency bands." And I'm almost certain you're using the formula: v = l*f (where v is speed of sound, l is the wavelength, and f is the frequency) to find the frequency.

Since we're in a reverberant room—the speed of sound is not exactly 34,300 cm/s. And my room is not exactly a square.

However, when I input your changes and put in the frequency band [100,500] MUSIC improves in finding the right azimuth, but TOPS and SRP become bad. When I put in [2900,3500] as my frequency band SRP and TOPS improve significantly.

Is there something I am missing in this picture to accurately determine the frequency bands for SPR and TOPS? If so, why?

Thank you @fakufaku

fakufaku commented 5 years ago

@akhilvasvani

akhilvasvani commented 5 years ago

Thanks.

kehinde-elelu commented 2 years ago

Hey @akhilvasvani. I am currently trying to find the distance between the sound source and microphone array, the DOA algorithm just provides us with the angle of the sound source. Are you able to use the lib to figure out the distance?

fakufaku commented 2 years ago

@ELELUABDULSALAM , the DOA algorithms in the package are not appropriate to find the distance.

kehinde-elelu commented 2 years ago

@fakufaku what do you suggest I use to locate the sound distance

fakufaku commented 2 years ago

I have replied in issue #243 .

akhilvasvani commented 2 years ago

@ELELUABDULSALAM, as @fakufaku and you mentioned, the pyroomacoutics library provides angles where the sound source is located. That said, I am exploring an alternative strategy of using a clustering to determine the true sound source location given multiple candidate locations. Check out my repo.

akhilvasvani commented 2 years ago

@fakufaku I have replied in issue #243 as well with a question.