I’m trying to get a decibel reading from an audio stream using the sounddevice
library.
import sounddevice as sd
import numpy as np
class SoundLevelReader(QObject):
new_level = Signal(float)
def sd_callback(self, indata, frames, time, status):
# see https://en.wikipedia.org/wiki/Sound_pressure#Sound_pressure_level
rms = np.sqrt(np.mean(np.absolute(indata)**2))
ref = 20e-6 # reference sound pressure in air
db = 20 * np.log10(rms / ref)
print("RMS:{:.6f}".format(rms))
print("REF:{:.6f}".format(ref))
print("RES:{:.6f}".format(db))
self.new_level.emit(db)
def main():
# ...
reader = SoundLevelReader()
with sd.InputStream(callback=reader.sd_callback, device=4, blocksize=5000):
sys.exit(app.exec())
I’m basically expecting decibel values in a range from -60 to 0 (theoretically).
However, by trying to respect the reference value of 20µP (ref
), the resulting values get way too high – even way into the positive:
db = 20 * np.log10(rms / ref)
RMS:0.000818
REF:0.000020
RES:32.236420
RMS:0.000455
REF:0.000020
RES:27.131226
But if I leave out the reference entirely, values seem to be more trustworthy:
db = 20 * np.log10(rms)
RMS:0.013473
REF:0.000020
RES:-37.410866
RMS:0.003492
REF:0.000020
RES:-49.137325
The funny thing is that I only get the same values like my DAW, when I use 10 instead of 20 as a factor:
db = 10 * np.log10(rms)
RMS:0.002143
REF:0.000020
RES:-26.689749
RMS:0.033025
REF:0.000020
RES:-14.811516
Question:
Can someone explain, how to correctly calculate a decibel value based on readings coming from the sounddevice
python lib? I know there are many different decibel “variants”. My main goal is to get a reading that’s exactly how DAWs these days would display it.