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. 数据保护:测试结果仅存储在本地

总结

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

相关推荐
柠果9 小时前
HarmonyOS深色模式适配实战——主题切换与WCAG对比度标准
harmonyos
柠果9 小时前
HarmonyOS权限管理实战——麦克风、震动等敏感权限申请
harmonyos
2401_8604947011 小时前
在React Native中实现鸿蒙跨平台开发中开发一个运动类型管理系统,使用React Navigation设置应用的导航结构,创建一个堆栈导航器
react native·react.js·harmonyos
hahjee11 小时前
diffutils文件对比:鸿蒙PC上的diff工具集
华为·harmonyos
2401_8603195211 小时前
react-native-calendarsReact Native库来帮助你处理日期和时间,实现鸿蒙跨平台开发日历组件
react native·react.js·harmonyos
赵财猫._.11 小时前
React Native鸿蒙开发实战(九):复杂业务场景实战与架构设计
react native·react.js·harmonyos
ifeng091812 小时前
uniapp开发鸿蒙:跨端兼容与条件编译实战
华为·uni-app·harmonyos
ifeng091812 小时前
uniapp开发鸿蒙:常见问题与踩坑指南
华为·uni-app·harmonyos
2401_8604947012 小时前
如何在React Native中实现鸿蒙跨平台开发任务列表页面在很多应用中都是一个常见的需求,比如待办事项列表、购物车列表等
react native·react.js·harmonyos