HarmonyOS纯音测听实现——专业听力检测功能开发

技术栈:HarmonyOS 5.0 + ArkTS + AudioRenderer

适用场景:听力健康应用、医疗辅助工具


前言

纯音测听(Pure Tone Audiometry)是临床上最常用的听力检测方法。本文将介绍如何在HarmonyOS应用中实现一个专业的纯音测听功能。

一、纯音测听原理

1.1 测试频率

标准纯音测听使用以下频率:

  • 125Hz, 250Hz, 500Hz:低频
  • 1000Hz, 2000Hz:中频(语音频率)
  • 4000Hz, 8000Hz:高频

1.2 听阈分级(WHO标准)

听阈 (dB) 听力等级
≤25 正常
26-40 轻度损失
41-55 中度损失
56-70 中重度损失
71-90 重度损失
>90 极重度损失

二、数据结构设计

typescript 复制代码
export interface PureToneFrequencyResult {
  frequency: number;        // 测试频率 Hz
  leftEarThreshold: number; // 左耳听阈 dB,-1表示未测试
  rightEarThreshold: number;// 右耳听阈 dB
}

export interface PureToneTestResult {
  id: string;
  timestamp: number;
  results: PureToneFrequencyResult[];
  leftEarAverage: number;
  rightEarAverage: number;
  overallLevel: string;
  leftEarLevel: string;
  rightEarLevel: string;
}

三、测试页面实现

3.1 页面状态管理

typescript 复制代码
@Entry
@Component
struct PureToneTestPage {
  @StorageLink('appDarkMode') isDarkMode: boolean = true;
  
  @State currentEar: string = 'left';
  @State currentFrequencyIndex: number = 0;
  @State currentVolume: number = 30;
  @State isPlaying: boolean = false;
  @State testResults: PureToneFrequencyResult[] = [];
  @State testPhase: string = 'intro';

  private testFrequencies: number[] = [125, 250, 500, 1000, 2000, 4000, 8000];
  private audioEngine: AudioEngine = AudioEngine.getInstance();

  aboutToAppear(): void {
    this.initTestResults();
    this.audioEngine.init();
  }

  private initTestResults(): void {
    this.testResults = this.testFrequencies.map((freq: number) => ({
      frequency: freq,
      leftEarThreshold: -1,
      rightEarThreshold: -1
    }));
  }
}

3.2 播放测试音

typescript 复制代码
private async playTestTone(): Promise<void> {
  if (this.isPlaying) {
    await this.audioEngine.stop();
    this.isPlaying = false;
    return;
  }

  this.isPlaying = true;
  const frequency = this.testFrequencies[this.currentFrequencyIndex];
  const safeVolume = Math.max(0.1, this.currentVolume / 100);
  
  this.audioEngine.setAudioType('tone');
  this.audioEngine.setWaveformType('sine');
  this.audioEngine.setFrequency(frequency);
  this.audioEngine.setVolume(safeVolume);
  
  await this.audioEngine.start(3);
  
  setTimeout(() => { this.isPlaying = false; }, 3000);
}

3.3 记录听阈

typescript 复制代码
private recordThreshold(): void {
  const result = this.testResults[this.currentFrequencyIndex];
  
  if (this.currentEar === 'left') {
    result.leftEarThreshold = this.currentVolume;
  } else {
    result.rightEarThreshold = this.currentVolume;
  }

  // 震动反馈
  vibrator.startVibration({ type: 'time', duration: 50 }, { id: 0, usage: 'notification' });

  this.nextTest();
}

private nextTest(): void {
  if (this.currentEar === 'left') {
    this.currentEar = 'right';
    this.currentVolume = 30;
  } else {
    this.currentEar = 'left';
    this.currentFrequencyIndex++;
    this.currentVolume = 30;
    
    if (this.currentFrequencyIndex >= this.testFrequencies.length) {
      this.testPhase = 'completed';
      this.saveResults();
    }
  }
}

3.4 计算平均听阈

typescript 复制代码
static async savePureToneTestResult(results: PureToneFrequencyResult[]): Promise<PureToneTestResult> {
  const speechFrequencies = [500, 1000, 2000, 4000];
  let leftSum = 0, rightSum = 0, leftCount = 0, rightCount = 0;
  
  for (const r of results) {
    if (speechFrequencies.includes(r.frequency)) {
      if (r.leftEarThreshold >= 0) {
        leftSum += r.leftEarThreshold;
        leftCount++;
      }
      if (r.rightEarThreshold >= 0) {
        rightSum += r.rightEarThreshold;
        rightCount++;
      }
    }
  }
  
  const leftAvg = leftCount > 0 ? Math.round(leftSum / leftCount) : -1;
  const rightAvg = rightCount > 0 ? Math.round(rightSum / rightCount) : -1;
  
  return {
    id: `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
    timestamp: Date.now(),
    results: results,
    leftEarAverage: leftAvg,
    rightEarAverage: rightAvg,
    overallLevel: getHearingLevelByThreshold(Math.max(leftAvg, rightAvg)),
    leftEarLevel: getHearingLevelByThreshold(leftAvg),
    rightEarLevel: getHearingLevelByThreshold(rightAvg)
  };
}

static getHearingLevelByThreshold(threshold: number): string {
  if (threshold < 0) return '未测试';
  if (threshold <= 25) return '正常';
  if (threshold <= 40) return '轻度损失';
  if (threshold <= 55) return '中度损失';
  if (threshold <= 70) return '中重度损失';
  if (threshold <= 90) return '重度损失';
  return '极重度损失';
}

四、UI界面示例

typescript 复制代码
build() {
  Column() {
    // 进度指示
    Row() {
      ForEach(this.testFrequencies, (freq: number, index: number) => {
        Circle()
          .width(12).height(12)
          .fill(index < this.currentFrequencyIndex ? '#2D7FF9' : 
                index === this.currentFrequencyIndex ? '#34C759' : '#333')
      })
    }.justifyContent(FlexAlign.SpaceEvenly).width('100%')

    Text(`${this.testFrequencies[this.currentFrequencyIndex]} Hz`)
      .fontSize(48).fontWeight(FontWeight.Bold)
    
    Text(`${this.currentEar === 'left' ? '左耳' : '右耳'}`)
      .fontSize(20)

    Slider({ value: this.currentVolume, min: 0, max: 100, step: 5 })
      .onChange((value: number) => { this.currentVolume = value; })

    Row() {
      Button('播放').onClick(() => this.playTestTone())
      Button('听到了').onClick(() => this.recordThreshold())
    }.justifyContent(FlexAlign.SpaceEvenly)
  }
}

五、避坑指南

  1. 音量校准:不同设备音量输出不同,建议添加校准功能
  2. 测试环境:提醒用户在安静环境中使用耳机测试
  3. 免责声明:明确说明仅供参考,不能替代专业医学检查
  4. 数据保护:测试结果仅存储在本地

总结

本文实现了一个专业的纯音测听功能,包括标准频率测试、听阈记录、等级评估等。该功能可帮助用户初步了解自己的听力状况。

相关推荐
贾伟康6 分钟前
【天体运行模拟|16】HarmonyOS ArkTS 多设备布局实战:适配手机、平板和 PC/2in1 的窗口变化
harmonyos·arkts·arkui·响应式布局·多设备适配
大雷神10 分钟前
HarmonyOS AR Engine高精几何重建实战——扫描纸盒并测量体积
华为·ar·harmonyos
用户09340777351414 分钟前
HarmonyOS WPS Open SDK 实践:registerApp 鉴权与就绪门禁
android·typescript·harmonyos
特立独行的猫a1 小时前
仓颉语言原生 Coding Agent:cjh · 仓颉语言实现的 Harness
ai·agent·harmonyos·仓颉·cangjie·harness
大锅盖11 小时前
警示橙如何驱动巡检闭环?ArkUI 物业安全平台的声明式实现
安全·华为·harmonyos
贾伟康1 小时前
【时光清单|03】HarmonyOS ArkTS 提醒服务实战:计算触发时间并防止重复注册
harmonyos·arkts·后台任务·幂等设计·通知提醒
李蚊子1 小时前
从代理提醒到真实响铃:懒熊闹钟的鸿蒙开发实践
前端·harmonyos
GKxx1 小时前
在 HarmonyOS 上从源码构建 GCC 16(gcc/g++ + libstdc++ + libsanitizer):完整记录
c++·华为·harmonyos·鸿蒙·gcc
贾伟康1 小时前
【时光清单|04】HarmonyOS ArkTS 通知服务实战:管理权限、渠道和点击跳转
harmonyos·arkts·系统通知·notificationkit·wantagent
独守一片天2 小时前
HarmonyOS|鸿蒙新生态服务卡片设计与状态同步
华为·harmonyos