Skip to content

Commit

Permalink
mcid.py: optimize FFT and A-weighting calculations (#33057)
Browse files Browse the repository at this point in the history
* Precomputing weighting

* add comments back

* use cache

* spacing

spacing

* clean up

* lower by diff

---------

Co-authored-by: Shane Smiskol <[email protected]>
  • Loading branch information
deanlee and sshane authored Jul 25, 2024
1 parent 2da4aef commit 313a282
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
2 changes: 1 addition & 1 deletion selfdrive/test/test_onroad.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"system.logmessaged": 0.2,
"system.tombstoned": 0,
"logcatd": 0,
"system.micd": 6.0,
"system.micd": 5.0,
"system.timed": 0,
"selfdrive.pandad.pandad": 0,
"system.statsd": 0.4,
Expand Down
22 changes: 12 additions & 10 deletions system/micd.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
import numpy as np
from functools import cache

from cereal import messaging
from openpilot.common.realtime import Ratekeeper
Expand All @@ -10,7 +11,16 @@
FFT_SAMPLES = 4096
REFERENCE_SPL = 2e-5 # newtons/m^2
SAMPLE_RATE = 44100
SAMPLE_BUFFER = 4096 # (approx 100ms)
SAMPLE_BUFFER = 4096 # approx 100ms


@cache
def get_a_weighting_filter():
# Calculate the A-weighting filter
# https://en.wikipedia.org/wiki/A-weighting
freqs = np.fft.fftfreq(FFT_SAMPLES, d=1 / SAMPLE_RATE)
A = 12194 ** 2 * freqs ** 4 / ((freqs ** 2 + 20.6 ** 2) * (freqs ** 2 + 12194 ** 2) * np.sqrt((freqs ** 2 + 107.7 ** 2) * (freqs ** 2 + 737.9 ** 2)))
return A / np.max(A)


def calculate_spl(measurements):
Expand All @@ -27,16 +37,8 @@ def apply_a_weighting(measurements: np.ndarray) -> np.ndarray:
# Generate a Hanning window of the same length as the audio measurements
measurements_windowed = measurements * np.hanning(len(measurements))

# Calculate the frequency axis for the signal
freqs = np.fft.fftfreq(measurements_windowed.size, d=1 / SAMPLE_RATE)

# Calculate the A-weighting filter
# https://en.wikipedia.org/wiki/A-weighting
A = 12194 ** 2 * freqs ** 4 / ((freqs ** 2 + 20.6 ** 2) * (freqs ** 2 + 12194 ** 2) * np.sqrt((freqs ** 2 + 107.7 ** 2) * (freqs ** 2 + 737.9 ** 2)))
A /= np.max(A) # Normalize the filter

# Apply the A-weighting filter to the signal
return np.abs(np.fft.ifft(np.fft.fft(measurements_windowed) * A))
return np.abs(np.fft.ifft(np.fft.fft(measurements_windowed) * get_a_weighting_filter()))


class Mic:
Expand Down

0 comments on commit 313a282

Please sign in to comment.