A working version of the rewritten code

This commit is contained in:
lolco 2025-12-05 11:25:44 +01:00
parent f4442a05f5
commit 39ceb8eedc
7 changed files with 25 additions and 20 deletions

2
.idea/A.K.03.iml generated
View File

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" /> <excludeFolder url="file://$MODULE_DIR$/.venv" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.11 (A.K.03)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.13 (A.K.03)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="PyDocumentationSettings"> <component name="PyDocumentationSettings">

Binary file not shown.

View File

@ -10,11 +10,11 @@ def recording_crop_normalize(recordings, ref_mic):
# Finding the last peak in the recording of the chosen reference microphone # Finding the last peak in the recording of the chosen reference microphone
ref_sig = recordings[:,ref_mic] ref_sig = recordings[:,ref_mic]
ref_peaks, _ = find_peaks(ref_sig, height= 0.5*max(abs(ref_sig))) ref_peaks, _ = find_peaks(ref_sig, height= 0.5*max(abs(ref_sig)))
ref_peak = ref_peaks[-1] ref_peak = ref_peaks[0]
# Cropping all recordings to show only the peaks around the reference peak # Cropping all recordings to show only the peaks around the ference peak
start = ref_peak - 1500 start = ref_peak - 3600
end = ref_peak + 1500 end = ref_peak + 3600
recordings = recordings[start:end] recordings = recordings[start:end]
# Normalizing all recordings after they are cropped # Normalizing all recordings after they are cropped
@ -23,13 +23,15 @@ def recording_crop_normalize(recordings, ref_mic):
for i in range(mic): for i in range(mic):
recordings_cropped_normalized[:, i] = recordings[:, i]/max(abs(recordings[:, i])) recordings_cropped_normalized[:, i] = recordings[:, i]/max(abs(recordings[:, i]))
recordings = recordings_cropped_normalized recordings = recordings_cropped_normalized
return recordings return recordings
def channel_estimation(recording, reference_recording, epsilon): def channel_estimation(recording, reference_recording, epsilon):
# Finding both the recording and the reference recording in the frequency domain # Finding both the recording and the reference recording in the frequency domain
padded_length = max(len(recording), len(reference_recording)) padded_length = max(len(recording), len(reference_recording)) + 100000
rec_freq = fft(recording, padded_length-len(recording))
ref_rec_freq = fft(reference_recording, padded_length-len(reference_recording)) rec_freq = fft(recording, padded_length)
ref_rec_freq = fft(reference_recording, padded_length)
# Performing the deconvolution in the frequency domain # Performing the deconvolution in the frequency domain
ch_est_freq = (ref_rec_freq*np.conj(rec_freq))/(np.abs(rec_freq)**2+epsilon) ch_est_freq = (ref_rec_freq*np.conj(rec_freq))/(np.abs(rec_freq)**2+epsilon)
@ -43,8 +45,7 @@ def distance_calc(channel_estimate, sampling_rate):
# Finding the location of the peak in the channel estimate relative to the reference peak # Finding the location of the peak in the channel estimate relative to the reference peak
center = len(channel_estimate)//2 center = len(channel_estimate)//2
peak = np.argmax(abs(channel_estimate)) peak = np.argmax(abs(channel_estimate))
sample_range = peak - center sample_range = center - peak
# Calculating the distance using the Time Difference of Arrival (TDOA) from found peak location # Calculating the distance using the Time Difference of Arrival (TDOA) from found peak location
time_dif = sample_range/sampling_rate time_dif = sample_range/sampling_rate
distance = time_dif * 34300 # cm distance = time_dif * 34300 # cm
@ -57,31 +58,31 @@ def location_estimation(mic_locations, ref_mic, distances, start_point = None):
# Using the location of the reference microphone as the refence point # Using the location of the reference microphone as the refence point
ref_point = mic_locations[ref_mic] ref_point = mic_locations[ref_mic]
other_indices = [i for i in range(mic_locations.shape[0]) if i != ref_mic]
# Generating the residuals function that is to be minimized. This residual is the difference between the "guessed" location and the location calculated from the microphone recordings # Generating the residuals function that is to be minimized. This residual is the difference between the "guessed" location and the location calculated from the microphone recordings
def residuals_function(guess): def residuals_function(guess):
guess = np.array([guess[0],guess[1],0]) guess = np.array([guess[0],guess[1],guess[2]])
residuals = [] residuals = []
for i, idx in enumerate(other_indices): for i, idx in enumerate(mic_locations):
if i != ref_mic:
mic = mic_locations[idx] mic = mic_locations[idx]
residual = (np.linalg.norm(guess-mic) - np.linalg.norm(guess-ref_point)) - distances[i] residual = (np.linalg.norm(guess-mic) - np.linalg.norm(guess-ref_point)) - distances[i]
residuals.append(residual) residuals.append(residual)
return residuals return residuals
# Using the least squares method to minimize the residuals function # Using the least squares method to minimize the residuals function
location = least_squares(residuals_function, start_point, bounds = ([0,0,-1],[460,460,1])) location = least_squares(residuals_function, start_point, bounds = ([0,0,1],[460,460,460]))
return location.x return location.x
def localization(recordings, sampling_rate): def localization(recordings, sampling_rate):
# Choosing a reference microphone. 0 is mic 1; 4 is mic 5 # Choosing a reference microphone. 0 is mic 1; 4 is mic 5
ref_mic = 4 ref_mic = 1
# Normalize and crop the recordings # Normalize and crop the recordings
recordings = recording_crop_normalize(recordings, ref_mic) recordings = recording_crop_normalize(recordings, ref_mic)
# Finding the channel estimates between each recording and the reference recording # Finding the channel estimates between each recording and the reference recording
epsilon = 0.0001 epsilon = 0.01
channel_estimates = [] channel_estimates = []
recording, mic = recordings.shape recording, mic = recordings.shape
for i in range(mic): for i in range(mic):
@ -103,11 +104,13 @@ def localization(recordings, sampling_rate):
[460, 0, 25], # mic 4 cm [460, 0, 25], # mic 4 cm
[0, 230, 55] # mic 5 cm [0, 230, 55] # mic 5 cm
]) ])
print(distances)
location_estimate = location_estimation(mic_locations, ref_mic, distances) location_estimate = location_estimation(mic_locations, ref_mic, distances)
return location_estimate return location_estimate
# Test # Test
if __name__ == "__main__": if __name__ == "__main__":
from datetime import datetime
# Coordinates of the recordings # Coordinates of the recordings
record_x = [64, 82, 109, 143, 150, 178, 232] record_x = [64, 82, 109, 143, 150, 178, 232]
record_y = [40, 399, 76, 296, 185, 439, 275] record_y = [40, 399, 76, 296, 185, 439, 275]
@ -124,3 +127,5 @@ if __name__ == "__main__":
print(f"\nRecording {i+1}: {filenames[i]}") print(f"\nRecording {i+1}: {filenames[i]}")
location_estimate = localization(recordings, sampling_rate) location_estimate = localization(recordings, sampling_rate)
print("Estimated source position:", location_estimate) print("Estimated source position:", location_estimate)
print((datetime.now()-s).total_seconds())