当前位置: 首页 > news >正文

【electron6】Web Audio + AudioWorklet PCM 实时采集噪音和模拟调试

连这条博客(【electron6】浏览器实时播放PCM数据)
一、背景与目标
在语音识别或实时通话类项目中,我们通常需要通过 AudioWorkletNode 从麦克风采集音频数据,并将其转换为标准 16bit PCM(线性脉冲编码调制)格式,以便传输或播放。为了调试 Worklet 数据处理流程,本笔记中使用一个本地 PCM 文件 (.ptt) 来模拟 AudioWorkletNode.process() 的输出数据,从而快速验证 PCM ↔ Float32 转换链路是否正确、是否干净无噪音。
二、音频采集基础结构
显式指定 sampleRate = 16000,保证采样率一致性:

this.audioCtx = new AudioContext({sampleRate: 16000
});
await this.audioCtx.audioWorklet.addModule('./voice.js');this.randomNoiseNode = new AudioWorkletNode(this.audioCtx,"voices",{channelCount: 1,processorOptions: {recording: this.recording,targetSampleRate: 16000,frameSize: 320, // 每帧 20ms},parameterData: {customGain: 1.0}}
);

三、AudioWorkletProcessor 核心实现
Worklet 内部负责实时从输入流读取音频、缓存、打包并发送至主线程:

class VoicesProcessor extends AudioWorkletProcessor {constructor(options) {super();this.buffer = [];this.recording = options.processorOptions.recording;this.frameSize = options.processorOptions.frameSize || 320;}encodePCM(float32Array) {const buffer = new ArrayBuffer(float32Array.length * 2);const view = new DataView(buffer);let offset = 0;for (let i = 0; i < float32Array.length; i++, offset += 2) {let s = Math.max(-1, Math.min(1, float32Array[i]));view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);}return view;}process(inputs, outputs) {const input = inputs[0][0];if (!input) return true;// 将每次 process 的 128 采样块累计缓存this.buffer.push(...input);// 达到一帧长度(320 samples = 20ms@16kHz)时发送if (this.buffer.length >= 320) {const frame = this.buffer.slice(0, 320);this.buffer = this.buffer.slice(320);const bytes = this.encodePCM(new Float32Array(frame));this.port.postMessage({ type: 'result', data: bytes });}return this.recording;}
}registerProcessor('voices', VoicesProcessor);

四、encodePCM 函数(Float32 → PCM16)

const encodePCM = (float32Array: Float32Array) => {const buffer = new ArrayBuffer(float32Array.length * 2);const view = new DataView(buffer);let offset = 0;for (let i = 0; i < float32Array.length; i++, offset += 2) {let s = Math.max(-1, Math.min(1, float32Array[i]));view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);}return view;
};

五、文件模拟 Worklet 数据调试
使用本地 .ptt(其他的.pcm文件也可) PCM 文件模拟 AudioWorkletNode 输出数据:

import axios from 'axios';
const onePcm = require('./ceshi.ptt');const encodePCM = (float32Array: Float32Array) => {const buffer = new ArrayBuffer(float32Array.length * 2);const view = new DataView(buffer);let offset = 0;for (let i = 0; i < float32Array.length; i++, offset += 2) {let s = Math.max(-1, Math.min(1, float32Array[i]));view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);}return view;
}
useEffect(() => {axios({url: onePcm,method: 'get',responseType: 'arraybuffer'}).then(res => {const int16Array = new Int16Array(res.data);const float32Array = new Float32Array(int16Array.length);// Int16 → Float32 标准化for (let i = 0; i < int16Array.length; i++) {let s = Math.max(-1, Math.min(1, int16Array[i]));float32Array[i] = s < 0 ? int16Array[i] / 0x8000 : int16Array[i] / 0x7FFF;}// 模拟 Worklet 内 encodePCM 再还原const decodeView = encodePCM(float32Array);// 使用自定义播放器播放let voice = new ProcessPCM();voice.playback(decodeView, () => {console.log('PCM 播放结束');});});在这里插入图片描述}, []);

六、噪音原因与解决总结
流程数据格式说明
在这里插入图片描述

七、噪音的本质原因复盘
原因描述
在这里插入图片描述

八、最终效果总结
优化点效果
在这里插入图片描述

http://www.dtcms.com/a/490604.html

相关文章:

  • Ajax 详解
  • 网站开发表格wordpress 语法编辑
  • 《零踩坑教程:基于 Trae 的高德地图 API 部署全流程解析》
  • 在Linux服务器上使用Jenkins和Poetry实现Python项目自动化
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段-二阶段(3):文法運用
  • [Sora] 数据管理 | `group_by_bucket`智能分桶 | DataloaderForVideo数据传输
  • 反向代理原理和服务转发实现方式
  • 中山企业网站多少钱爱奇艺做视频网站的
  • mapper.xml sql动态表查询配置
  • SQL Server 2019实验 │ 设计数据库的完整性
  • Leetcode每日一练--35
  • IDEA项目上传Gitee
  • 数据同步:Debezium监听,变更捕获实现?
  • 免费在线自助建站嵩明县住房和城乡建设局网站
  • PyTorch是什么?
  • 11年始终专注营销型网站龙岗召开企业服务大会
  • 11-触发器
  • dify 配置域名https访问
  • Fragment mWho 在registerForActivityResult 中作用
  • 告别插件堆砌!Neovim 配置“瘦身”实战:用 Mini.nvim 替换主流插件全过程
  • PyCharm 2025:最新使用图文教程!
  • 线性表之数组
  • 黄岩网站建设兼职无锡网站建设网络推广
  • 专业的食品行业网站开发叮当快药网站谁做的
  • Agent 时代的大模型演化:从 ChatGPT 到多智能体协作系统
  • uniapp uni.chooseImage+uni.uploadFile使用方法与详解
  • 云手机的魅力与优势
  • 关于 uni-app 与原生微信小程序中的生命周期 —— 一次“生命旅程”的解读
  • 方圆网通网站建设公司怎么做不用数据库的网站
  • uniapp 打开横竖屏。usb调试时可以横竖屏切换,但是打包发布后却不行?