> **技术栈**:HarmonyOS 5.0 + ArkTS + AudioCapturer

>

> **适用场景**:环境噪音检测、听力保护提醒、声音可视化

---

## 前言

分贝仪是一个实用的环境噪音检测工具,可以帮助用户了解所处环境的噪音水平,保护听力健康。本文将详细介绍如何使用HarmonyOS的`AudioCapturer`实现实时分贝检测。

## 一、分贝计算原理

### 1.1 声压级(SPL)

分贝是一个对数单位,用于表示声音强度:

```

SPL (dB) = 20 × log₁₀(P / P₀)

```

其中P是测量声压,P₀是参考声压(20μPa)。

### 1.2 数字音频转换

从数字音频数据计算分贝:

1. 计算音频样本的均方根(RMS)

2. 转换为分贝值

3. 添加校准偏移量

## 二、代码实现

### 2.1 分贝检测器类

```typescript

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 权限配置

```json

// module.json5

{

  "requestPermissions": [

    {

      "name": "ohos.permission.MICROPHONE",

      "reason": "$string:microphone_reason",

      "usedScene": {

        "abilities": ["EntryAbility"],

        "when": "inuse"

      }

    }

  ]

}

```

### 2.3 动态权限申请

```typescript

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 页面使用示例

```typescript

@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 | 摇滚音乐会 | 可能立即损伤 |

## 四、避坑指南

1. **权限申请**:必须在`module.json5`声明并动态申请麦克风权限

2. **资源释放**:页面销毁时必须调用`stop()`

3. **校准值**:94是经验值,不同设备可能需要微调

4. **隐私声明**:应用商店审核要求明确说明麦克风用途

## 总结

本文实现了一个完整的HarmonyOS分贝检测器,可用于环境噪音监测、听力保护提醒等场景。关键点在于正确的RMS计算和分贝转换公式。

**🎓 我的HarmonyOS开发课堂**:[点击进入课堂学习](https://developer.huawei.com/consumer/cn/training/classDetail/03d6a547f8124d35aab33fc40840288f?type=1?ha_source=hmosclass&ha_sourceId=89000248)

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐