如何用MicroPython将RPI Pico W模拟麦克风原始音频转为MP3文件?
在RPI Pico W上用MicroPython处理模拟麦克风音频:转可收听文件与MP3
一、将原始音频转为可收听的WAV文件
WAV是无压缩的通用音频格式,只需给原始采样数据加上标准文件头,就能生成直接可播放的文件,适配Pico W有限的资源情况。
核心步骤
- 确认音频参数:模拟麦克风一般为单声道,采样率可选8kHz/16kHz,Pico的ADC是12位,需转换为通用的16位PCM格式。
- 采集并转换ADC数据:将0-4095的ADC值转为-32768到32767的16位有符号整数,对齐WAV格式要求。
- 生成WAV文件头并写入数据:文件头包含采样率、位深等关键信息,之后追加原始PCM数据即可。
示例代码
from machine import ADC, Pin import time # 配置麦克风ADC引脚(根据实际接线调整,示例为GPIO26) mic = ADC(Pin(26)) # WAV文件参数 SAMPLE_RATE = 16000 # 采样率,按需调整 BIT_DEPTH = 16 # 16位通用格式 CHANNELS = 1 # 单声道 DURATION = 5 # 录音时长(秒) total_samples = SAMPLE_RATE * DURATION # 采集并转换ADC数据为16位PCM def collect_pcm_data(): pcm_buffer = bytearray(total_samples * 2) # 16位数据,每个样本占2字节 for i in range(total_samples): # 12位ADC值转为16位有符号整数 adc_val = mic.read_u16() >> 4 pcm_val = adc_val - 2048 # 偏移为中心0点 # 小端字节序写入缓冲区 pcm_buffer[i*2] = pcm_val & 0xFF pcm_buffer[i*2+1] = (pcm_val >> 8) & 0xFF # 控制采样间隔,保证采样率准确 time.sleep_us(int(1000000 / SAMPLE_RATE)) return pcm_buffer # 生成WAV标准文件头 def generate_wav_header(sample_rate, bit_depth, channels, sample_count): byte_rate = sample_rate * channels * (bit_depth // 8) block_align = channels * (bit_depth // 8) data_size = sample_count * channels * (bit_depth // 8) header = bytearray() # RIFF块 header.extend(b'RIFF') header.extend((36 + data_size).to_bytes(4, 'little')) header.extend(b'WAVE') # fmt块(PCM格式) header.extend(b'fmt ') header.extend((16).to_bytes(4, 'little')) header.extend((1).to_bytes(2, 'little')) # PCM编码标识 header.extend(channels.to_bytes(2, 'little')) header.extend(sample_rate.to_bytes(4, 'little')) header.extend(byte_rate.to_bytes(4, 'little')) header.extend(block_align.to_bytes(2, 'little')) header.extend(bit_depth.to_bytes(2, 'little')) # data块 header.extend(b'data') header.extend(data_size.to_bytes(4, 'little')) return header # 主执行流程 if __name__ == '__main__': print("开始录音...") pcm_data = collect_pcm_data() print("录音结束,生成WAV文件...") wav_header = generate_wav_header(SAMPLE_RATE, BIT_DEPTH, CHANNELS, total_samples) # 写入内置存储,若用SD卡需先挂载,路径改为'/sd/recording.wav' with open('recording.wav', 'wb') as f: f.write(wav_header) f.write(pcm_data) print("WAV文件已保存")
注意事项
- 若麦克风输出为单极性信号,需调整电平偏移值,确保PCM数据中心在0,避免播放失真。
- Pico内置存储仅约1MB,长时间录音建议外接SD卡,使用
machine.SDCard模块挂载后写入。
二、将原始音频转为MP3文件
MP3是有损压缩格式,受Pico W的CPU和内存限制,有两种可行方案:
方案1:离线转换(推荐)
先在Pico上生成WAV文件,再传到电脑用工具转换,操作简单且无资源压力:
- 按上述方法生成WAV文件,通过USB文件传输或WiFi FTP/HTTP传到电脑。
- 使用
ffmpeg命令行工具转换,示例命令:
ffmpeg -i recording.wav -codec:a libmp3lame -qscale:a 2 recording.mp3
-qscale:a 2对应高质量压缩,数值0-9越大,压缩率越高、音质越低。
方案2:Pico端直接编码(资源受限)
需使用轻量级MP3编码库,如mp3lame的MicroPython移植版本,注意:
- 需使用带有该模块的定制MicroPython固件(自行编译或找预编译版本)。
- 建议降低采样率(如8kHz)、缩短录音时长,避免内存溢出或CPU过载。
示例代码思路
# 前提:已安装mp3lame模块 from mp3lame import Lame from machine import ADC, Pin import time # 初始化编码器 lame = Lame() lame.set_mode(Lame.MONO) lame.set_sample_rate(8000) lame.set_bit_depth(16) # 采集PCM数据(同WAV部分的collect_pcm_data函数,调整采样率为8kHz) pcm_data = collect_pcm_data() # 编码MP3 mp3_data = lame.encode(pcm_data) mp3_data += lame.finish() # 获取编码剩余数据 # 写入文件 with open('recording.mp3', 'wb') as f: f.write(mp3_data)
内容的提问来源于stack exchange,提问作者SweetWhite
相关产品推荐
相关产品推荐

