# Locating sound

This topic can often be confusing (as anything can when you first start off). There are a lot of similar projects online and this is a well documented area but I thought I would explain how I went about tackling the problem.

This post is by no means a "copy and paste the code" and "follow the circuit diagram" kind of solution, but more of a theoretical understanding.

I will briefly explain how sound location can be achieved, discussing some of the key calculations that need to be considered.

To begin with, one main topic in this area is correlation.

Correlation will allow you to detect similarities in signals and will help in finding time delays (as it is time delays that will allow you to interpret where the sound has come from) like we do as humans.

So say there was no time delay between signals? Sound obviously came from directly ahead.
And if the time delay was at its maximum? The sound obviously came from either left or right at 90 degrees(how we decide whether sound approached from the left of right will be discussed in more detail).

Steps to be explained:

1. Entering microphone A and microphone B samples into separate arrays
2. Shifting microphone B array left (ensuring the maximum time delay hasn't been breached)
3. Correlation section(correlate signals,store result, shift microphone array B right by one element) this is carried out for multiple times
4. Calculate the angle of arrival from knowing the location of the highest element in the correlation results array

By following these steps you will successfully be able to gather an angle of arrival to a sound source. I will now go further into the algorithm part of the project. But that's pretty much it!!!!!

1. Entering microphone A and microphone B samples into separate arrays

The important considerations you must consider here are your sample time and the amount of samples you want to take.

usually when making this project you will be detecting a voice or some sort of noise that you can hear. I think the human hearing range is somewhere between 100-10khz(I could be wrong). Your sampling frequency (time in between each sample) should be more than twice the max frequency component, so:

2x10khz = 20khz

As it needs to be above this say 25khz.

Now to calculate the time you need between each sample you do:

1/frequency=time

1/25000 = 40us

So you need 40us between your samples.

Now for the amount of samples you need:

If you took 100 samples, you would be looking at a signal over the space of 4ms which is considerably small. You would want a larger window of about 0.5-1second.

1. Shifting microphone B array left (ensuring the maximum time delay hasn't been breached)

Now the reason I mentioned shifting this array is because we need to correlate the signal at different lag positions (we will lag the signal by shifting one array with respect to the other)

An important consideration here is to know how much we can actually shift this array.

The maximum shift can be calculated by:

Distance between microphones/speed of sound= max time delay between mics

max time delay between mics/ sample time= element shift

So now you shift your microphone b data array by this amount of elements and then you are ready for the next section.

1. Correlation section(correlate signals,store result, shift microphone array B right by one element) this is carried out for multiple times

I would consider this the beefiest part of the project and there isn't enough character space to post it all (if you want me to explain this or anything else just leave a comment)

1. Calculate the angle of arrival from knowing the location of the highest element in the correlation results array

To calculate angle of arrival:

Degree per element shift = system detection angle/ size of correlation results array

4.5 degrees= 180 degrees/40

Angle of arrival = degree per element shift x element location

So for an element location of 15:

4.5 x 15 = 67.5 degrees

I am happy to answer any questions, I've run out of room to type

Ryanfryer123:
So say there was no time delay between signals? Sound obviously came from directly ahead.

Or sounds from directly above, behind, and under will all arrive with no time delay.

Beyond that, I would love to see even a snippet of Arduino code you used to “build .5-1sec worth” of samples (20,000? based on 100 samples per 4ms).

The way you would detect whether sound came from directly above behind and under would come down to your layout of microphones. For 360 ground detection a triangular formation would be needed. You could essentially check which microphone received the sound first, then through method of elimination you will know that the sound would be in that direction.

To detect whether the sound came from above (or below) you would need a mic placed in the 3rd dimension(like a pyramid). Then use a time delay to give you an angle of elevation.

My actual program wasn't built on arduino but on a different microcontroller so the amount of samples I have mentioned may not be possible on arduino (I'm not too sure as I'm new to arduino)

I used 12500 actual samples of mic data and a 40us time delay between samples

12500 x 40us = ~ 0.5 seconds for the arrays to be filled

But to answer the main question of whether the sound came from infornt or behind and up or down is tackled from knowing the highest correlation results element location and through some trigonometry.

The image I have attached is how I approached detecting whether sound hit one mic first or the other ( in a 2 mic system)

1. Correlation section

Step 1: correlate the signals
Step 2: store the result
Step 3: shift array b right by one element

My algorithm to do this was as follows:

// main loop to be carried out for the total of elements you want to shift with respect to both of you maximum time delays
For (k=0; k<=size_of_your_corr_result_array; k++)
{
Result=0; // reset to 0 every time loop iterates

// cross correlation calculation loop
For (I=0;I<=your_total_numb_of_samples; I++)
{
_
}_
_
// to store the result within an element of the results array*_
* Cross_corr_eqn_result = (float)result;
Cross_corr_array_results[k] = Cross_corr_eqn_result;
_
// shift all elements right by one element*_
* For (I=your_total_numb_of_samples-2;I>=1;I--)
_
{_