白噪声但没有声音 // 在 Raspberry Pi Pico (ADC) 上从驻极体麦克风前置放大器录制音频 // Micropython

问题描述 投票:0回答:1

我对微控制器游戏还很陌生。最近,我尝试通过模拟驻极体麦克风在

Raspberry Pi Pico
上录制音频。因此,我为麦克风构建了一个(工作良好)前置放大器,并通过 ADC 引脚将其连接,稍后将详细解释。

现在我只想使用 micropython 将其作为

.wav
文件存储在内部闪存上。目前,这个 micropython 代码似乎是主要问题,因为它生成了一个
.wav
文件,其中只包含白噪声。

到目前为止我所做的是以下...

(1)搭建驻极体麦克风的MCU接口前置放大器

我在 microchip.com 上发现了一款有用的前置放大器,它采用 MCP6001 运算放大器。绘图如下所示: Conventional MCP6001 preamp for electret microphones

这是 preamp soldered to a circuit board

使用此前置放大器进行的测试效果非常好。使用两节 AA 电池作为电源,我用万用表测量电源电压

V_DD = 2.620(1)V
和输出偏置电压
V_out0 = 1.310(1)V
。当我对着麦克风吹口哨时,峰峰值信号是用示波器测量的。信噪比 (SNR) 相当不错,如下所示:

Oscilloscope measurement of V_out on battery supplied preamp 然后我将前置放大器与通过 USB 供电的 Pico 的 Pico 引脚

V_out ~ 0.2-0.3V

ADC_VREF (GPIO 35)
连接起来。前置放大器输出尚未连接到 Pico,如
 所示。现在我得到了电源电压 measuring setupAGND (GPIO 31) 和输出偏置电压 
V_DD = 3.2(1)V
,与电池版本相比,它的稳定性要差得多,但 SNR 应该足够高,可以录制一些我认为的音频:

Oscilloscope measurement of V_out on Pico ADC_VREF supplied preamp

(2) 在 Pico / Micropython shell 上从 ADC 采样

当我现在将前置放大器输出连接到

V_0 = 1.58(10)V

并在 Thonny micropython shell 中运行以下代码时

ADC0 (GPIO 31 == Pin 26)

考虑到具有最大值的 16 位 ADC,我得到了一些合理的读数值
>>> from machine import Pin, ADC >>> mic = ADC(Pin(26)) >>> mic.read_u16() 32551 >>> mic.read_u16() 31911 >>> mic.read_u16() 31815

(3) 在 Pico / Micropython 主代码上将样本保存到 .wav 文件中

然后,我编写了一段代码来创建

2^16=65536

标头并将其写入 Pico 闪存中的

.wav
(基于
Mike Teachman 的 I2S 示例
),将二进制样本读入缓冲区并通过该缓冲附加 test.wav价值观。
test.wav

我知道运行 micropython 固件会占用大量资源,并且由于时序问题,声音应该会很不稳定(找到了一些使用 C++ 和 DMA 来防止这种情况的建议)。不过,我希望至少能在 
from machine import Pin import time micPin = machine.ADC(Pin(26)) FILE_NAME = 'test17.wav' sampleRate = 44100 # 44.1 kHz - CD quality bitsPerSample = 16 num_channels = 1 # 1 - MONO, 2 - STEREO duration = 3 # in seconds bufferSize = duration * sampleRate # 1/s * s num_samples = bufferSize def create_wav_header(sampleRate, bitsPerSample, num_channels, num_samples): datasize = num_samples * num_channels * bitsPerSample // 8 o = bytes("RIFF", "ascii") # 1-4 (4byte) Marks file as RIFF o += (datasize + 36).to_bytes( 4, "little" ) # 5-8 (4byte) File size in bytes excluding this and RIFF marker o += bytes("WAVE", "ascii") # 9-12 (4bytes) File type o += bytes("fmt ", "ascii") # 13-16 (4bytes) Format Chunk Marker, trailing 0 o += (16).to_bytes(4, "little") # 17-20 (4bytes) Length of above format data o += (1).to_bytes(2, "little") # 21-22 (2bytes) Format type (1 - PCM) o += (num_channels).to_bytes(2, "little") # 23-24 (2bytes) o += (sampleRate).to_bytes(4, "little") # 25-28 (4bytes) o += (sampleRate * num_channels * bitsPerSample // 8).to_bytes(4, "little") # 29-32 (4bytes) o += (num_channels * bitsPerSample // 8).to_bytes(2, "little") # 33-34 (2bytes) o += (bitsPerSample).to_bytes(2, "little") # 35-36 (2bytes) o += bytes("data", "ascii") # 37-40 (4bytes) Data Chunk Marker o += (datasize).to_bytes(4, "little") # 41-44 (4bytes) Data size in bytes return o try: with open('/'+FILE_NAME, 'wb') as recFile: wav_header = create_wav_header( sampleRate, bitsPerSample, num_channels, num_samples ) recFile.write(wav_header) with open('/'+FILE_NAME, 'ab') as recFile: buffer = bytearray(bufferSize) for i in range(bufferSize): buffer[i] = micPin.read_u16() # print(buffer[i]) time.sleep(1/sampleRate) recFile.write(buffer) except (KeyboardInterrupt, Exception) as e: print("caught exception {} {}".format(type(e).__name__, e))

中听到一些东西,但我发现的只是白噪音......

.wav
显示类似
 的内容
hexdump -C test.wav

(摘录)

此外,当我取消注释

00000000 52 49 46 46 bc 09 04 00 57 41 56 45 66 6d 74 20 |RIFF....WAVEfmt | 00000010 10 00 00 00 01 00 01 00 44 ac 00 00 88 58 01 00 |........D....X..| 00000020 02 00 10 00 64 61 74 61 98 09 04 00 a8 88 88 f8 |....data........| 00000030 c8 28 18 98 88 98 d8 18 28 38 d8 b8 c8 88 a8 08 |.(......(8......| 00000040 e8 38 78 98 b8 c8 e8 08 18 28 18 c8 b8 58 38 e8 |.8x......(...X8.| 00000050 58 38 48 18 48 88 d8 38 b8 f8 08 28 28 58 68 88 |X8H.H..8...((Xh.| 00000060 a8 88 58 98 a8 a8 88 08 08 28 58 68 68 58 68 98 |..X......(XhhXh.| 00000070 88 c8 e8 e8 08 38 48 38 28 28 18 68 18 28 38 48 |.....8H8((.h.(8H| 00000080 58 68 88 98 88 68 58 48 38 18 28 38 e8 e8 08 48 |Xh...hXH8.(8...H| 00000090 98 c8 e8 28 18 58 08 48 28 08 68 a8 c8 b8 d8 e8 |...(.X.H(.h.....| 000000a0 18 08 f8 e8 b8 e8 e8 38 88 78 88 58 e8 68 e8 28 |.......8.x.X.h.(| 000000b0 28 48 38 48 88 c8 08 08 28 58 d8 18 48 88 a8 98 |(H8H....(X..H...| 000000c0 b8 a8 c8 a8 b8 b8 b8 d8 d8 18 28 f8 08 28 18 28 |..........(..(.(|

循环中的

print(buffer[i])
命令时,会出现如下所示的值:
for

这些解释了白噪声。但我不明白为什么
84
8
88
200
184
152
似乎在这里失败,而它在 shell 中工作......

关于我做错了什么和/或如何改进这个项目有什么想法吗?

提前谢谢您!

祝一切顺利, 修补匠Toadie

您尝试将 16 位数字存储到一个字节中,即 8 位:
audio-recording micropython adc raspberry-pi-pico
1个回答
0
投票
micPin.read_u16()

当然,样本的前 8 位将被截掉,留下低 8 位,这绝对不是您想要的。
更适合缓冲区的数据类型是带有类型代码 

buffer = bytearray(bufferSize) ... buffer[i] = micPin.read_u16()

(16 位有符号)的

array

此外,为了帮助排除故障,您不应尝试在文件中记录真实的 ADC 读数。只需生成一个正弦波,这样我们就可以确保您的文件系统和 WAV 编码核心正在工作,然后您再担心尝试将真正的麦克风硬件集成到系统中。

我通常预计 MicroPython 的垃圾收集器和缓慢的速度会让这个项目无法完成。

© www.soinside.com 2019 - 2024. All rights reserved.