睡眠音频分割及识别问题(十一)--基于Android的YAMNet音频识别(总结)
WAV文件格式介紹
WAV文件遵守資源交換文件格式之規則,在文件的前44(或46)字節放置標頭(header),使播放器或編輯器能夠簡單掌握文件的基本信息,其內容以區塊(chunk)為最小單位,每一區塊長度為4字節,而區塊之上則由子區塊包裹,每一子區塊長度不拘,但須在前頭先宣告標簽及長度(字節)。標頭的前3個區塊記錄文件格式及長度;接著第一個子區塊包含8個區塊,記錄聲道數量、采樣率等信息;接著第二個子區塊才是真正的音頻資料,長度則視音頻長度而定。內容如下表所示。須注意的是,每個區塊的端序不盡相同,而音頻內容本身則是采用小端序。
Android端使用java對wav進行數據讀取,具體實現參考AudioReader的readHead()方法代碼細節。
Android端實現讀取音頻文件源碼介紹
主要使用Java io庫中的 InputStream 接口,實現讀取文件的字節流信息。主要實現類為AudioReader類,工具類為Utils,項目代碼結構如下所示:
PO包的文件說明如下:
- AudioFragment為一個接口,存放0.975s音頻文件的相關信息;
- IAudioFragment 為AudioFragment實現的接口;
- Score包含一個字符串(label)和一個浮點數(score),存放???;
- AudioReader為讀取wav文件信息、預測音頻標簽的實現類;
- LabelsName存儲著521個標簽的字符串;
- MyComparator主要實現對Score對象數組的排序;
- Utils中包括幾個常用的音頻數據處理方法(工具類)。
IAudioFragment接口
該接口主要對功能進行初步定義。主要包含前N名的Score數組,以及實現是否在打鼾、咳嗽和打噴嚏。
public interface IAudioFragment { float start = 0; float end = 0; public Score[] scores = null; public abstract boolean isSnore(); public abstract boolean isCough(); public abstract boolean isSneeze(); public Score[] getScores(); public void setScores(Score[] scores); }AudioFragment實現類
對接口IAudioFragment進行實現,實現原理為:只保存前5的評分時,若Snore標簽在前5中,則isSnore()返回true,否則返回false,其他方法同理。其中浮點數start和end表示該AudioFragment對象的起始與結束時間。例如:當你傳入一段10s的音頻進行預測時,會返回一個AudioFragment對象數組,其數組中第一個元素的起始時間為start = 0,結束時間為end = 0.975;第二個元素的起始時間為start =0.975,結束時間為end = 1.950(單位s)。
以下為部分核心代碼:
Score類
該對象只包含兩個屬性,將標簽與評分綁定在一個對象中。
String label; float score;LabelsName類
主要存儲521個標簽的字符串數組,供其他類調用。
IAudioProcess接口
主要對音頻的加載與處理功能的定義。
// 通過傳入Android上下文環境,音頻文件路徑,獲取該音頻文件的輸入流 public InputStream initInputStream(Context context, String fileName); // 初始化Yamnet模型 public Yamnet initYamnetModel(Context context); // 預測函數,該函數應該在傳入音頻文件后再調用,應該返回多個AudioFragment對象,AudioFragment對象中默認存儲評分前5的標簽 public AudioFragment[] predict(); // 同predict(),可以指存儲評分中前topN個標簽 public AudioFragment[] predict(int topN); // 在初始化后使用,對目標fileName音頻文件進預測,返回多個AudioFragment對象,AudioFragment對象中存儲評分前topN的標簽 public AudioFragment[] predictByAudioFile(String fileName,int topN); // 預測0.975s音頻數據的具體實現方法,Yamnet模型要求輸入input為[-1,1]的長度為 15600的數組,經過預測得到評分結果,再與 start、end與topN一起用于構造一個 AudioFragment對象。 public AudioFragment predictOneSecond(Yamnet model, float[] input, float start, float end, int topN); // 0.975sAudioReader類
主要對IAudioReader進行實現。其構造函數必須傳入解析的文件名,以及上下文環境。以下為構造函數:
/** * @param context Android Context * @param fileName The target wav format file that needs to be predicted * */ public AudioReader(Context context, String fileName){ this.context = context; this.fileName = fileName; initInputStream(context,fileName); getInstance(context); }在安卓活動中構建AudioReader對象并執行預測的示例如下:
(1)在初始化時直接指定文件并預測
(2)在初始化時直接指定文件并預測前10個標簽
AudioReader audioReader = new AudioReader(this,"demo.wav"); AudioFragment[] audioFragments = audioReader.predict(10);(3)在初始化后改變預測文件
AudioReader audioReader = new AudioReader(this,"demo.wav"); // 預測other.wav中評分前10的標簽 AudioFragment[] audioFragments = audioReader.predict("other.wav",10);MyComprator類
主要對Score對象數組的排序,主要使用方法如下:
// resultScores 為Score對象數組,升序。在原有的resultScores上改變 Arrays.sort(resultScores, new MyComprator());Utils類
主要完成重復性工作,例如Byte與int的轉換、Byte與String的轉換、Byte與int的轉換,打印AudioFragment數組。
總結
以上是生活随笔為你收集整理的睡眠音频分割及识别问题(十一)--基于Android的YAMNet音频识别(总结)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 备份成文件的脚本_Mysql
- 下一篇: php 文件 不更新,php页面不刷新更