1 结构体
此部分定义了两个结构体用于存储音频信息:
- AudioFragment:用于存储单个音频片段(0.975s, 16000Hz)的标签评分信息;
- AudioInfo:用于存储整个音频信息,包含音频文件名、时间等基础信息,同时包含每个时间段的标签评分信息,即AudioFragment数组。
1.1 AudioFragment 结构体
- 属性 snoring : Float; 存储打鼾对应的预测评分,例如 0.9821
- 属性 sneeze : Float; 存储打喷嚏对应的预测评分,例如 0.0
- 属性 cough : Float; 存储咳嗽对应的预测评分,例如 0.0
- 属性 topN : Array<(label: String, score: Float)>; 存储N个标签与对应评分信息,例如存一个标签: [(label: “Snoring”, score: 0.9821)]
- 方法init(topN:Array<(label: String, score: Float)>, cough: Float, sneeze: Float, snoring: Float); 有参构造函数,实现对结构体属性的赋值。
1.2 AudioInfo 结构体
- 属性 fileName : String; 存储音频文件名,不包括扩展名,例如"audio"
- 属性 audioTime : Float; 存储音频对应时间,例如 10.0
- 属性 audioChannel : Int; 存储音频通道数,例如 1
- 属性 audioSampleRate : Int; 存储音频采样率,例如 8000
- 属性 audioSampleBit : Int; 存储音频采样深度,例如 16
- 属性 audioFragemnts : [AudioFragemnt]; 存储音频中包含的音频片段信息,每 0.975s 为一个音频片段
- 方法 mutating func setValue (fileName: String, audioTime: Float, audioChannel: Int, audioSampleRate: Int, audioSampleBit: Int, audiofragments: [AudioFragment]) -> (); 赋值函数,实现对结构体属性的赋值。
2 WavReader 类
该类实现对音频文件的加载、头文件解析、采样点数据读取等功能。以下为类中的所有方法。
- 方法 init (fileName: String, fileExtention: String);初始化函数,需给定目标音频文件名与其扩展名
- 方法 private func getURLAndDataByStr (fileName: String);根据提供的目标文件名,加载URL资源并解析,获取音频的NSData类型数据数组
- 方法 private func readHead(data: NSData); 根据获取的NSData解析文件头,解析为特定的文件头信息
- 方法 private func readAudioData(data: NSData);根据获取的NSData解析音频采样点信息,解析为特定的Uint16数组
- 方法 private func utilsReadData(data: NSData, startIndex: Int, dataSize: Int, bitDeep: Int) throws -> [Int16];wav文件以chunk块存储数据,该方法主要通过下标实现读取单个chunk块的数据内容
- 方法 func process();指定各个方法的执行顺序,对方法进行封装,对外暴露 process() 方法。
3 AudioProcesser类
该类实现对Yamnet模型文件的加载、执行预测、不同类型数据的转换、对音频文件的解析进行调用,以及对解析到的数据进行结构化操作。
- 方法 init (fileName: String);初始化函数,需给定目标处理音频文件的文件名(不包含扩展名,默认为 .wav)
- 方法 private func setupInterpreter();初始化 Tensorflow Lite 解释器
- 方法 private func int16ArrayToData(_ buffer: [Int16]) -> Data;将 [Int16] 转换为 Data 类型数据,模型接收输入为 Data 类型
- 方法 private func dataToFloatArray(_ data: Data) -> [Float];将Data数据类型转换为 [Float] 类型数据,将模型输出转换为浮点数组
- 方法 public func start(inputBuffer: [Int16]) -> [Float];调用模型执行预测,并返回模型预测结果
- 方法 func sortByScore(scores: [Float], top: Int) -> Array<(label: String, score: Float)>;将模型输出的标签评分结果排序
- 方法 func convertSampleData2Audiofragment(wavReader: WavReader, top: Int);传入一个WavReader对象,该方法会根据该对象中解析到的音频采样信息调用yamnet 进行预测,预测后包装成 AudioFragmen t数组对象,存储在 AudioInfo 结构体中
- 方法 func predict ( );对文件解析、模型预测等方法进行封装,对外只需要调用predict()方法
- 方法 func isCough(audioFragment: AudioFragment) -> Bool;传入一个AudioFragment结构体,通过其评分信息判断是否为咳嗽音频(通过判断其topN属性中是否包含Cough标签)
- 方法 func isSneeze(audioFragment: AudioFragment) -> Bool;传入一个AudioFragment结构体,通过其评分信息判断是否为打喷嚏音频(通过判断其topN属性中是否包含Sneeze标签)
- 方法 func isSnoring(audioFragment: AudioFragment) -> Bool;传入一个AudioFragment结构体,通过其评分信息判断是否为打鼾音频(通过判断其topN属性中是否包含Snoring标签)