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 小时前
鸿蒙原生ArkTS布局方式之Popup+TextInput提示输入布局深度解析
华为·harmonyos
nullregedit10 小时前
原生鸿蒙像素画板实战 22:快捷键与鼠标交互
harmonyos·arkts·鸿蒙·bitart·像素画
●VON11 小时前
鸿蒙 PC Markdown 编辑器图片粘贴:从系统剪贴板到标准相对链接
华为·编辑器·harmonyos·鸿蒙
●VON11 小时前
鸿蒙 PC Markdown 编辑器外部修改检测:从文件指纹到冲突决策
华为·编辑器·harmonyos·鸿蒙
●VON11 小时前
鸿蒙 PC Markdown 编辑器十兆级大文档保护模式
华为·编辑器·harmonyos·鸿蒙
●VON11 小时前
鸿蒙 PC Markdown 编辑器三方冲突处理:本地缓冲区、磁盘版本与共同基线
网络·华为·编辑器·harmonyos·鸿蒙
listening77711 小时前
HarmonyOS 6.1 性能极致调优:从“流畅”到“极致”的SmartPerf深度剖析
华为·harmonyos
轻口味12 小时前
【大展鸿图】HarmonyOS DevEco Code 入门与最佳实
华为·harmonyos·鸿蒙·月更
●VON12 小时前
鸿蒙 PC Markdown 编辑器搜索选项响应式布局:220 vp 侧栏中的完整中文控件
服务器·华为·编辑器·harmonyos·鸿蒙
Helen_cai13 小时前
HarmonyOS ArkTS 实战:实现一个外出报备晚归登记应用
华为·harmonyos