Audio学习2(麦克风和喇叭)

发布时间:2026/10/31 17:45:25
Audio学习2(麦克风和喇叭) 想了想还是看看这两基础哥们。1 麦克风1.1 总览大概有以下这些。类型换能原理输出信号灵敏度SNR体积成本典型应用MEMS 数字麦PDM硅微振膜电容 片内 ΣΔ 调制PDM 1bit 串行中等60~70dB极小3×4mm 级低TWS 耳机、手机、语音阵列、远场唤醒MEMS 数字麦I2S/TDM硅振膜 片内 ADC 抽取多 bit PCM中等60~70dB小中高高端多麦阵列、车载MEMS 模拟麦硅振膜电容 片内前置放大模拟电压中高60~65dB极小低需要外部 Codec 的低成本方案ECM 驻极体麦驻极体薄膜电容 JFET模拟电压高55~65dB中6mm 圆柱极低玩具、低端音箱、DIY动圈麦线圈切割磁感线模拟电压无源低70~80dB大中高舞台演出、户外 K 歌大振膜电容麦电容振膜 48V 幻象供电模拟电压极高80~100dB大高录音棚、专业配音MEMS 超声麦MEMS 压电 / 电容超声阵列数字 / 模拟——小中高手势识别、测距、探伤1.2 MEMS原理本质是微型电容结构硅片光刻出极薄振膜 固定背板声波推动振膜电容变化芯片内部集成前置放大、Σ-Δ 调制器直接输出 PDM最常见少数型号输出 I2S / 模拟电压。✅ 优点尺寸极小可以做到 1.6×1.0mm 级别、支持 SMT 回流焊、批次一致性很好SNR 离散小做多麦波束成形很关键、功耗低、抗震数字 PDM 版本走数字信号不怕主板射频干扰WiFi / 蓝牙干扰是模拟麦的大坑✅ 接口PDM 是最主流两根线CLKDATA一个时钟1bit 密度调制MCU/DSP 内部做抽取滤波转 PCMI2S 麦直接输出 PCM接口更重、成本更高模拟 MEMS 输出模拟电压后级要 PGAADC和老 ECM 链路一致✅ 典型指标SNR 60~70dB声学过载点 120~135dB SPL分上进声 / 下进声PCB 开孔有全向为主也有差分双振膜 MEMS内置降噪✅ 用法单麦基础拾音2 麦 / 4 麦阵列做波束成形 BF、AEC 回声消除、语音降噪、声源定位、远场语音唤醒小爱 / 天猫TWS 耳机里通常 2~3 颗 MEMS一颗主拾音、一颗环境参考做通话降噪 / AOC 堵耳消除1.3 ECM 驻极体电容麦老一代电容麦原理也是电容薄膜预先注入永久电荷驻极体搭配内置 JFET 阻抗变换输出模拟信号没有内置 ADC一定是模拟输出必须外部 PGAADC 才能转 PCM。✅ 优点成本极低、电路简单❌ 短板体积偏大、不能过高温回流焊、一致性差同批次 SNR 偏差 3~5dB做多麦阵列很难对齐相位、模拟走线极易引入干扰现在新手机 TWS 基本淘汰只在低价音箱、玩具、简易 DIY 里还在用。1.4 动圈麦克风电磁感应振膜带动线圈在磁铁缝隙里运动切割磁感线产生电压无源不需要供电。✅ 优势耐大声压、结实、抗造、低频扎实❌ 短板灵敏度偏低、高频上限一般、体积大不适合小型穿戴设备几乎不用在嵌入式语音采集。1.5 采集例子ECM用的GY-MAX4466 模块咪头是 ECM 驻极体电容麦。输出OUT 引脚是模拟音频信号必须接到 MCU/ADC采样之后才能得到 PCM没有 PDM、没有数字输出。ECM 运放MAX4466 方案老模拟路线。优点结构简单、便宜缺点模拟走线极易引入电源噪声、射频干扰想要 PCM依赖主控 ADC。STM32F4 的内置 ADC 就可以直接接这个 OUT 脚来采集。PDM MEMS把 ΣΔ 做进麦里面直接输出数字 1bit 流抗干扰强适合多麦阵列。模块内部有没有 ΣΔ原始输出得到 PCM 的方式GY-MAX4466❌ 无模拟电压外部 ADC 采样INMP441 PDM 麦✅ 片内 ΣΔPDM 1bit 流软件抽取滤波所以在使用MAX4466需要接到ADC的引脚。我这边是用的树莓派Pico2来完成实验使用的GP16ADC0口。实现思路是麦克风使用 MAX4466 模拟放大模块模拟输出接到 Pico 2 的 GP26也就是 ADC0。固件以 20 kHz 采样每 512 个样本组成一帧通过 USB CDC 串口发给电脑。每帧包含 ZAUD 帧头、样本数、帧序号和 512 个 16 位样本。电脑端可以据此同步数据并统计丢帧。这里树莓派Pico的ADC原始能力是12bit SAR ADC也就是12位精度。在2048的时候表示电压在中间也就是几乎没声音在0或者4095的时候都是声音最大的时候。之后在处理的时候扩展到16位。转换到PCM算法如下raw 0 ~ 4095mid 2048pcm16 (raw - 2048) 4;整体代码如下Pico2和上位机的通信协议字节位置长度内容0–34 字节固定标识ZAUDASCII4–52 字节本包样本数512小端序6–72 字节帧序号小端序无符号循环计数8 起1024 字节512 个 16 位小端序样本采样率是 20 kHz、单声道。每包代表 512 / 20000 25.6 ms 音频。核心代码main.c/* * Pico 2 audio capture: MAX4466 analog output on GP26 / ADC channel 0. * Streams 512-sample, 16-bit little-endian frames over USB CDC ACM. */ #include sample_usbd.h #include hardware/adc.h #include hardware/dma.h #include errno.h #include stdint.h #include string.h #include zephyr/device.h #include zephyr/drivers/adc.h #include zephyr/drivers/uart.h #include zephyr/kernel.h #include zephyr/usb/usbd.h #include zephyr/sys/byteorder.h #define SAMPLE_RATE_HZ 20000U #define ADC_CLOCK_HZ 48000000U #define ADC_DMA_CHANNEL 0U #define FRAME_SAMPLES 512U #define FRAME_HEADER_BYTES 8U #define FRAME_BYTES (FRAME_HEADER_BYTES FRAME_SAMPLES * sizeof(uint16_t)) BUILD_ASSERT(SAMPLE_RATE_HZ 20000U, Update ADC clock divider if sample rate changes); static const struct adc_dt_spec adc_spec ADC_DT_SPEC_GET(DT_NODELABEL(audio_user)); static const struct device *const cdc_dev DEVICE_DT_GET_ONE(zephyr_cdc_acm_uart); static struct usbd_context *usb_ctx; static struct k_sem tx_done; static uint8_t tx_frame[FRAME_BYTES]; static volatile size_t tx_offset; static void usb_message_cb(struct usbd_context *ctx, const struct usbd_msg *msg) { if (!usbd_can_detect_vbus(ctx)) { return; } if (msg-type USBD_MSG_VBUS_READY) { (void)usbd_enable(ctx); } else if (msg-type USBD_MSG_VBUS_REMOVED) { (void)usbd_disable(ctx); } } static int usb_device_start(void) { usb_ctx sample_usbd_init_device(usb_message_cb); if (usb_ctx NULL) { return -ENODEV; } if (!usbd_can_detect_vbus(usb_ctx)) { return usbd_enable(usb_ctx); } return 0; } static void cdc_tx_isr(const struct device *dev, void *user_data) { ARG_UNUSED(user_data); if (!uart_irq_update(dev)) { return; } while (uart_irq_tx_ready(dev)) { if (tx_offset sizeof(tx_frame)) { uart_irq_tx_disable(dev); k_sem_give(tx_done); return; } int written uart_fifo_fill(dev, tx_frame tx_offset, sizeof(tx_frame) - tx_offset); if (written 0) { return; } tx_offset (size_t)written; } } static int adc_channel_start(void) { struct adc_channel_cfg channel_cfg { .gain ADC_GAIN_1, .reference ADC_REF_INTERNAL, .acquisition_time ADC_ACQ_TIME_DEFAULT, .channel_id adc_spec.channel_id, }; return adc_channel_setup(adc_spec.dev, channel_cfg); } static void audio_stream_thread(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); uint16_t samples[FRAME_SAMPLES]; uint16_t frame_number 0; dma_channel_config_t dma_cfg dma_channel_get_default_config(ADC_DMA_CHANNEL); channel_config_set_transfer_data_size(dma_cfg, DMA_SIZE_16); channel_config_set_read_increment(dma_cfg, false); channel_config_set_write_increment(dma_cfg, true); channel_config_set_dreq(dma_cfg, DREQ_ADC); /* Pace conversions in hardware and move each result with DMA. */ adc_run(false); /* Zephyrs ADC driver enabled the FIFO IRQ; DMA owns FIFO reads from here. */ adc_irq_set_enabled(false); adc_fifo_setup(true, true, 1, false, false); adc_set_clkdiv(((float)ADC_CLOCK_HZ / SAMPLE_RATE_HZ) - 1.0f); k_sem_init(tx_done, 0, 1); while (1) { /* Clear a possible trailing sample before starting the next exact block. */ adc_run(false); adc_fifo_drain(); dma_channel_configure(ADC_DMA_CHANNEL, dma_cfg, samples, adc_hw-fifo, FRAME_SAMPLES, false); dma_start_channel_mask(BIT(ADC_DMA_CHANNEL)); adc_run(true); dma_channel_wait_for_finish_blocking(ADC_DMA_CHANNEL); adc_run(false); uint32_t dtr 0; if (uart_line_ctrl_get(cdc_dev, UART_LINE_CTRL_DTR, dtr) ! 0 || !dtr) { continue; } memcpy(tx_frame, ZAUD, 4); sys_put_le16(FRAME_SAMPLES, tx_frame 4); sys_put_le16(frame_number, tx_frame 6); for (size_t i 0; i FRAME_SAMPLES; i) { sys_put_le16(samples[i], tx_frame FRAME_HEADER_BYTES i * 2U); } tx_offset 0; uart_irq_tx_enable(cdc_dev); k_sem_take(tx_done, K_FOREVER); } } K_THREAD_STACK_DEFINE(audio_thread_stack, 3072); static struct k_thread audio_thread; int main(void) { if (!device_is_ready(cdc_dev)) { return 0; } if (usb_device_start() ! 0) { return 0; } if (uart_irq_callback_user_data_set(cdc_dev, cdc_tx_isr, NULL) ! 0) { return 0; } if (!device_is_ready(adc_spec.dev) || adc_channel_start() ! 0) { return 0; } k_thread_create(audio_thread, audio_thread_stack, K_THREAD_STACK_SIZEOF(audio_thread_stack), audio_stream_thread, NULL, NULL, NULL, 5, 0, K_NO_WAIT); return 0; }用到的API来自Zephyr 提供uart_line_ctrl_get()查询 CDC 串口的 DTR 状态k_sem_init()/k_sem_take()控制发送同步ARG_UNUSED()是 Zephyr 宏。Pico SDK 提供adc_run()、adc_irq_set_enabled()、adc_fifo_setup()、adc_fifo_drain()、adc_set_clkdiv()操作 RP2350 的 ADCdma_channel_*()、dma_start_channel_mask()配置和控制 DMA。硬件寄存器adc_hw-fifo是 ADC FIFO 寄存器地址。上位机电脑端上位机使用 Python 和 Tkinter 编写可以选择串口、显示实时波形和电平并将采集数据保存为 WAV。当前录音格式为单声道、20 kHz、16 位 PCM。确实可以转换成PCM当时也确实噪音很大。调了几次gain也没有太明显的效果。后面再试试软件优化吧。2 喇叭2.1 总览类型换能原理驱动信号特点频响体积成本典型应用动圈扬声器电动式最通用音圈在磁场里电流驱动音圈带动振膜振动发声模拟交流音频功率信号技术成熟、推力足、失真可控需要功放驱动全频友好低频好跨度很大微型大低音单元低中蓝牙音箱、TWS 耳机单元、电视、汽车喇叭、开发板蜂鸣喇叭压电扬声器压电陶瓷压电材料加电压后形变带动振膜振动模拟交流可高压驱动结构简单、无磁、不怕电磁干扰低频差、偏尖高频为主低频弱很小极低蜂鸣器、便携提示音、穿戴设备提示、简易报警器很少用来放语音音乐静电扬声器ESL高压电场驱动超薄导电振膜极板静电吸力推拉振膜高压音频信号几十上千 V 偏置解析极高、瞬态好需要高压驱动、怕潮湿、低频弱中高频极其顺滑低频难做大薄、大面积很高HiFi 高端音箱消费电子几乎不用平板扬声器平面振膜 / 气动式 AMTAMT褶皱铝膜在磁场里平面振膜整块薄膜驱动模拟功率音频扩散好、高频细腻低频效率偏低中高频优秀偏薄、面积大中高高端头戴耳机、高端 HiFi 音箱、车载顶棚扬声器MEMS 扬声器硅喇叭硅工艺微型振膜静电 / 压电驱动晶圆级封装数字 / 模拟很多自带驱动极小、适合 SMT 贴片、一致性好声压上限有限低频弱中高频为主芯片级极小中正在降价智能眼镜、TWS 副单元、助听器、AR 设备骨传导扬声器骨传导振子振动块机械振动通过颅骨传声不靠空气声波模拟功率信号开放听感、不漏音相对更好有震感、低频弱中低频偏弱中等中高骨传导耳机、安全帽通讯设备气传导扬声器开放式喇叭单元本质还是动圈结构专门优化远场开放辐射模拟功率音频开放声场不堵耳容易漏音全频低频一般中等中开放式耳机、挂耳耳机因为喇叭需要前后震动发声所以给的电流是交流电。不过DAC/CODEC 直接输出的信号电压小、电流能力极弱推不动喇叭输出电流只有mA 甚至 μA 级带载能力非常弱。一般来说喇叭想要正常响、达到额定响度需要几百 mA 级的电流DAC 引脚完全给不出这么大电流。所以需要一个功放来放大电流。功放功放类型简介适配喇叭特点AB 类功放线性模拟放大动圈为主音质好、噪声低、发热大、效率低老方案D 类功放数字功放 / PWM 功放PWM 调制开关放大动圈、压电、MEMS效率高、发热小现在消费音频主流WM8960 内部就是 D 类H 类 / G 类自适应电源轨 D 类改进动圈兼顾效率和大动态高端音箱不过有些有线耳机耳机32Ω、16Ω功率只需要毫瓦级CODEC内置的耳机驱动缓冲电流刚好够用此时就不需要额外外接功放芯片。2.2 Speaker这个是目前某宝上随处可见的一个喇叭功率8W阻抗3Ω。选择功放如下组合后果功放支持≥8Ω功放 8Ω 功率 ≥喇叭功率✅ 理想余量充足功放支持≥8Ω功放 8Ω 功率 喇叭功率⚠️ 能用音量上限不足大声容易失真喇叭阻抗功放允许最小阻抗比如功放最小 4Ω接 2Ω 喇叭❌ 危险过流、烧功放喇叭输入的就是经过放大的交流电。因为是交流电方向一直变化所以接反了影响也不会太大。2.3 播放例子这里给一个MAX98357进行播放的例子。MAX98357 是一款集成 DAC 与 D 类功率放大的音频芯片直接接收 I2S 格式的 PCM 数字音频信号内部完成数模转换后通过 BTL 桥接方式输出差分交流功率信号可直接驱动扬声器无需额外模拟功放它无需 MCLK 主时钟外围电路简洁支持增益配置与单声道混合5V 供电下 8Ω 负载最大输出约 1.8W适合 STM32、ESP32 等嵌入式设备做语音播报、音频播放缺点是功率有限推 3W 8Ω 喇叭无法达到满功率大音量下容易出现削波失真。详细的内容之前写过这里就不再做实验了直接看就行了。总线学习5--I2S_max98357数据手册-CSDN博客

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询