为什么 Numpy 在计算当前响度时有时会返回 NaN 值?

Why is Numpy sometimes returning NaN values when calculating the current loudness?

对于我的项目,我需要检查周围环境的噪音。我结合了两段代码来创建一个非常准确的分贝计:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pyaudio
import numpy as np
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
pa = pyaudio.PyAudio()
stream = pa.open(format=FORMAT,
                        channels=CHANNELS,
                        rate=RATE,
                        input=True,
                        frames_per_buffer=CHUNK)
buffer = []

while True:
    string_audio_data = stream.read(CHUNK) 
    audio_data = np.fromstring(string_audio_data, dtype=np.short)
    loudness = 20*np.log10(np.sqrt(np.mean(np.absolute(audio_data)**2)))
    print(loudness)

感谢 SO 上的 K K and thanks to YuanGao on cmsdk.com 录音。

这个 returns 以分贝为单位的响度非常准确,至少与其他相当可靠的分贝计相比是这样。

但是,一旦音频开始变得有点响亮,脚本通常 returns nan 或毫无意义的数字。

是否存在我忽略的固有错误,或者这只是此方法的局限性?

您的数据类型为np.int16。您正在取绝对值然后对其求平方,但所有这些算术都是使用 16 位算术进行的。

作为失败示例,请在您的解释器中尝试以下操作

>>> x = np.arange(30000, 30100, dtype=np.short)
>>> print(x * x)

你就会发现问题所在。大约一半的结果是负数,因为它们被截断为 16 位。很有可能你的总和是负数,然后对数给你 NaN.

这也解释了为什么它只在音乐响亮时发生。轻音乐不会溢出来。

所以改变

    audio_data = np.fromstring(string_audio_data, dtype=np.short)

    audio_data = np.fromstring(string_audio_data, dtype=np.short).astype(float)

您的代码将按预期运行。