HarmonyOS分贝检测器开发——实时环境噪音监测实战
HarmonyOS分贝检测器开发——实时环境噪音监测实战
技术栈:HarmonyOS 5.0 + ArkTS + AudioCapturer
适用场景:环境噪音检测、听力保护提醒、声音可视化
前言
分贝仪是一个实用的环境噪音检测工具,可以帮助用户了解所处环境的噪音水平,保护听力健康。本文将详细介绍如何使用HarmonyOS的AudioCapturer实现实时分贝检测。
一、分贝计算原理
1.1 声压级(SPL)
分贝是一个对数单位,用于表示声音强度:
SPL (dB) = 20 × log₁₀(P / P₀)
其中P是测量声压,P₀是参考声压(20μPa)。
1.2 数字音频转换
从数字音频数据计算分贝:
- 计算音频样本的均方根(RMS)
- 转换为分贝值
- 添加校准偏移量
二、代码实现
2.1 分贝检测器类
import audio from '@ohos.multimedia.audio';
/**
* 分贝检测器
* 通过麦克风采集环境声音,实时计算分贝值
*/
export class DecibelDetector {
private audioCapturer: audio.AudioCapturer | null = null;
private isRecording: boolean = false;
private callback: (db: number) => void;
private bufferSize: number = 2048;
constructor(callback: (db: number) => void) {
this.callback = callback;
}
async start(): Promise<void> {
if (this.isRecording) return;
try {
const audioCapturerOptions: audio.AudioCapturerOptions = {
streamInfo: {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
},
capturerInfo: {
source: audio.SourceType.SOURCE_TYPE_MIC,
capturerFlags: 0
}
};
this.audioCapturer = await audio.createAudioCapturer(audioCapturerOptions);
await this.audioCapturer.start();
this.isRecording = true;
this.readBuffer();
} catch (e) {
console.error('DecibelDetector start failed:', e);
}
}
async stop(): Promise<void> {
if (!this.isRecording) return;
this.isRecording = false;
if (this.audioCapturer) {
await this.audioCapturer.stop();
await this.audioCapturer.release();
this.audioCapturer = null;
}
}
private async readBuffer() {
while (this.isRecording && this.audioCapturer) {
const buffer = await this.audioCapturer.read(this.bufferSize, true);
if (buffer) {
const db = this.calculateDecibel(buffer);
this.callback(db);
}
}
}
private calculateDecibel(buffer: ArrayBuffer): number {
const data = new Int16Array(buffer);
let sum = 0;
// 计算均方根 (RMS)
for (let i = 0; i < data.length; i++) {
sum += data[i] * data[i];
}
const rms = Math.sqrt(sum / data.length);
if (rms < 1) return 30; // 极安静环境
// 转换为分贝
let db = 20 * Math.log10(rms / 32767.0);
db += 94; // 校准偏移
return Math.min(Math.max(Math.round(db), 20), 120);
}
}
2.2 权限配置
// module.json5
{
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
2.3 动态权限申请
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
private async requestMicrophonePermission(): Promise<boolean> {
const atManager = abilityAccessCtrl.createAtManager();
const context = getContext(this);
const result = await atManager.requestPermissionsFromUser(
context,
['ohos.permission.MICROPHONE']
);
return result.authResults[0] === 0;
}
2.4 页面使用示例
@Entry
@Component
struct DecibelMeterPage {
@State currentDecibel: number = 0;
@State maxDecibel: number = 0;
@State minDecibel: number = 100;
@State isMonitoring: boolean = false;
private decibelDetector: DecibelDetector | null = null;
aboutToAppear(): void {
this.initDecibelDetector();
}
aboutToDisappear(): void {
this.decibelDetector?.stop();
}
private async initDecibelDetector(): Promise<void> {
if (await this.requestMicrophonePermission()) {
this.decibelDetector = new DecibelDetector((db: number) => {
this.currentDecibel = db;
this.maxDecibel = Math.max(this.maxDecibel, db);
this.minDecibel = Math.min(this.minDecibel, db);
});
await this.decibelDetector.start();
this.isMonitoring = true;
}
}
build() {
Column() {
Text(`${this.currentDecibel}`)
.fontSize(80)
.fontWeight(FontWeight.Bold)
Text('dB')
.fontSize(24)
Row() {
Column() {
Text(`${this.minDecibel}`).fontSize(24)
Text('最小').fontSize(12).fontColor('#666')
}
Column() {
Text(`${this.maxDecibel}`).fontSize(24)
Text('最大').fontSize(12).fontColor('#666')
}
}
.justifyContent(FlexAlign.SpaceAround)
.width('60%')
.margin({ top: 30 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
三、分贝等级参考表
| 分贝范围 | 环境描述 | 健康影响 |
|---|---|---|
| 20-40 dB | 安静的图书馆 | 理想环境 |
| 40-60 dB | 正常交谈 | 舒适环境 |
| 60-80 dB | 繁忙街道 | 可能干扰 |
| 80-100 dB | 工厂噪音 | 长期暴露有害 |
| 100+ dB | 摇滚音乐会 | 可能立即损伤 |
四、避坑指南
- 权限申请:必须在
module.json5声明并动态申请麦克风权限 - 资源释放:页面销毁时必须调用
stop() - 校准值:94是经验值,不同设备可能需要微调
- 隐私声明:应用商店审核要求明确说明麦克风用途
总结
本文实现了一个完整的HarmonyOS分贝检测器,可用于环境噪音监测、听力保护提醒等场景。关键点在于正确的RMS计算和分贝转换公式。
浙公网安备 33010602011771号