Android音訊開發(4):如何儲存和解析wav檔案
無論是文字、影象還是聲音,都必須以一定的格式來組織和儲存起來,這樣播放器才知道以怎樣的方式去解析這一段資料,例如,對於原始的影象資料,我們常見的格式有 YUV、Bitmap,而對於音訊來說,最簡單常見的格式就是 wav 格式了。
wav 格式,與 bitmap 一樣,都是微軟開發的一種檔案格式規範,它們都有一個相似之處,就是整個檔案分為兩部分,第一部分是“檔案頭”,記錄重要的引數資訊,對於音訊而言,就包括:取樣率、通道數、位寬等等,對於影象而言,就包括:影象的寬高、色彩位數等等;第二部分是“資料塊”,即一幀一幀的二進位制資料,對於音訊而言,就是原始的 PCM 資料;對於影象而言,就是 RGB 資料。
前面幾篇文章講了如何利用 Android 平臺的 API 完成原始音訊訊號的採集和播放,而本文則重點關注如何在 Android 平臺上,將採集到的 PCM 音訊資料儲存到 wav 檔案,同時,也介紹如何讀取和解析 wav 檔案。
而文章最後,我還會給出一段 AudioDemo 程式,該程式將最近的幾篇文章涉及到的程式碼綜合起來了,演示了一個完整的 Android 音訊從採集到播放的全過程。
下面言歸正傳,講講如何讀寫 wav 檔案格式。
1. 檔案頭
我們可以簡單地分析一下這個 wav 格式頭,它主要分為三個部分:
第一部分,屬於最“頂層”的資訊塊,通過“ChunkID”來表示這是一個 “RIFF”格式的檔案,通過“Format”填入“WAVE”來標識這是一個 wav 檔案。而“ChunkSize”則記錄了整個 wav 檔案的位元組數。
第二部分,屬於“fmt”資訊塊,主要記錄了本 wav 音訊檔案的詳細音訊引數資訊,例如:通道數、取樣率、位寬等等(含義請參考我的第一篇文章《Android音訊開發(1):基礎知識》)
第三部分,屬於“data”資訊塊,由“Subchunk2Size”這個欄位來記錄後面儲存的二進位制原始音訊資料的長度。
分析到這裡,我想大家應該就明白了,其實,做一種多媒體格式的解析,也不是一件特別複雜的事,說白了,格式就是一種規範,告訴你,我的二進位制資料是怎麼儲存的,你應該按照什麼樣的方式來解析。
具體而言,我們可以定義一個如下的 Java 類來抽象和描述 wav 檔案頭:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
具體每一個欄位的含義,可以參考我上面給出的連結,下面我們再看看如何讀寫 wav 檔案。
2. 讀寫 wav 檔案
文章開頭已經說過,其實說白了,wav 檔案就是一段“檔案頭”+“音訊二進位制資料”,因此:
(1)寫 wav 檔案,其實就是先寫入一個 wav 檔案頭,然後再繼續寫入音訊二進位制資料即可
(2)讀 wav 檔案,其實也就是先讀一個 wav 檔案頭,然後再繼續讀出音訊二進位制資料即可
那麼,在動手寫程式碼之前,有兩點你需要搞清楚:
(1) wav 檔案頭中,有哪些是“變化的”,哪些是“不變的”?
比如:檔案頭開頭的“RIFF”字串就是“不變的”部分,而用來記錄音訊資料總長度的“Subchunk2Size”變數就是屬於“變化的”部分,因為,再音訊資料沒有徹底全部寫完之前,你是無法知道一共寫入了多少位元組的音訊資料的,因此,這個部分,需要用一個變數記錄起來,到全部寫完之後,再使用 Java 的“RandomAccessFile”類,將檔案指標跳轉到“Subchunk2Size”欄位,改寫一下預設值即可。
(2) 如何把 int、short 變數與 byte[] 的轉換
因為 wav 檔案都是二進位制的方式讀寫,因此,“WavFileHeader”類中定義的變數都需要轉換為byte位元組流,具體轉換方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
關於 wav 檔案讀寫的類我已經幫大家“封裝”好了,並且結合著前面幾篇文章給出的音訊採集和播放的程式碼,完成了一個 AudioDemo 程式,放在我的 Github 上了,歡迎大家下載執行測試,然後結合著程式碼具體學習 Android 音訊相關技術,程式碼地址:
注:本系列文章的所有程式碼,以後都會併入到該 demo 專案中。
相關推薦
Android音訊開發(4):如何儲存和解析wav檔案
無論是文字、影象還是聲音,都必須以一定的格式來組織和儲存起來,這樣播放器才知道以怎樣的方式去解析這一段資料,例如,對於原始的影象資料,我們常見的格式有 YUV、Bitmap,而對於音訊來說,最簡單常見的格式就是 wav 格式了。 wav 格式,與 bitmap 一樣,都是
Android音訊開發(1):基礎知識
Android音訊開發(1):基礎知識 導讀 人的說話頻率基本上為300Hz~3400Hz,但是人耳朵聽覺頻率基本上為20Hz~20000Hz。 對於人類的語音訊號而言,實際處理一般經過以下步驟: 人嘴說話——>聲電轉換——>抽樣(模數轉換)——>量化(將數字訊號用適當的數值表示)——&g
多媒體開發(12):解碼aac到wav檔案
簡單來說,aac是一種音訊編碼格式,需要解碼後才能用於音訊輸出。aac編碼格式,已經是一種很常見的音訊編碼格式,以至於很多系統都支援aac的編解碼,比如iOS上的AudioConverterRef介面、Android上的MediaCodec介面等。 但是,不要以為用了系統的介面就是用了硬體解碼,因為,這個系統
使用bottle進行web開發(4):HTTPError
instead bject hat red uil tle ott class not from bottle import error @error(404) def error404(error): return ‘Nothing here, sorry‘
tensorflow學習(4):儲存模型Saver.save()的引數命名機制以及restore並建立手寫字型識別引擎
前言 上一章中我們講到如何訓練一個網路,點選檢視部落格,這章我們來講tensorflow在儲存網路的時候是怎麼給不同的引數命名的,以及怎麼將儲存的引數重新restore到重構的網路結構中的。最後利用重構的網路去預測一張包含數字(0-9)的圖片(任意畫素)。
Android專案開發(4)-忘記密碼---驗證碼驗證頁面功能實現
任務描述 根據所學知識點完成 1、實現activity_forget.xml佈局檔案 2、實現activity_forget.java程式碼檔案中的如下功能: --2.1點選獲取驗證碼,按鈕自動開始3
ArcGISEngine二次開發(4):屬性查詢(2)
屬性查詢(2) 使用IGeometry介面TrackPolygon方法建立物件實現屬性查詢 使用ISpatialFilter介面SpatialRel屬性定義Intersects取交集為查詢物件 之後將查詢到的(FindField方法)屬性顯示在新的wind
ONVIF協議網路攝像機(IPC)客戶端程式開發(4):使用gSOAP生成Web Services框架程式碼
1. 專欄導讀 本專欄第一篇文章「專欄開篇」列出了專欄的完整目錄,按目錄順序閱讀,有助於你的理解,專欄前面文章講過的知識點(或程式碼段),後面文章不會贅述。為了節省篇幅,突出重點,在文章中展示的示例程式碼僅僅是關鍵程式碼,你可以在「專欄開篇」中獲取完整程式碼。
android Bluetooth 開發(二):開啟、關閉、搜尋、允許搜尋、檢視
相關專案的下載連結繼本專案之後實現了語音識別:點選開啟連結1.承接上一篇文章,本篇文章主要實現了藍芽的開啟 關閉 允許搜尋 檢視配對裝置2. BluetoothInit,主要實現了部件的初始化,按鈕的點選事件,通過ListVIew顯示本地配對的藍芽裝置,ListView的點選
~雜記(4):阿里和華為rtos 的接管中斷邏輯探索
1、首先在某晶片的啟動檔案中,給出的中斷向量表全是指向同一個函式。(一開始我以為是錯的,自己改成各個預設中斷服務函式的入口,這樣就成了非接管中斷)。 部分程式碼如下,其中irq_handler就是那個統一的中斷服務函式。他被定義在排程檔案los_dispatch中。 __Vectors:
四國軍棋引擎開發(4)子力判斷和局面評估初步
1.子力判斷 子力判斷在局面評估中起著非常重要的作用,在前一篇文章中已經介紹了子力判斷的部分,那時相對還比較粗糙,這次會更細緻的分析並優化上一次的不足。 pLineup->type用來代表棋子的型別,這裡是用列舉變數來表示,要注意級別大的變數值小,如40的值是5,39的值是6,
pytorch學習筆記(五):儲存和載入模型
# 儲存和載入整個模型 torch.save(model_object, 'model.pkl') model = torch.load('model.pkl') # 僅儲存和載入模型引數(推薦使
Performanced C++ 經驗規則(4):靜態和多型,亦敵亦友
這一篇,我們討論C++中靜態和多型的關係。我們都知道,C++並不是一門“動態”語言,雖然它提供了同樣強大於其它動態語言的多型性,但很多時候,我們之所以選擇C++,看重中正是其“靜態”所帶來的High Performance。所謂靜態,通常是指,在程式執行的過程,是“靜止”不變,固定的(特別是記憶體地
使用Eclipse RCP進行桌面程式開發(三):檢視和透檢視
Eclipse RCP開發中,和使用者進行互動最多的介面,應該是檢視了,而透檢視就是將已有的檢視、選單、工具欄、編輯器等等進行組合和佈局。看完這一節,我們就可以建立如下圖這樣的程式介面了。 首先我們來介紹一下檢視,建立一個檢視其實非常簡單,只要從org.eclipse.ui
Android開發(2):資料儲存之一:SharedPrefrences和檔案讀寫
一、資料儲存 本文主要講前兩種儲存方式,其中檔案讀寫只記錄Internal Storage方式 1. SharedPrefrences方式 輕量級NVP方式儲存,以XML的檔案方式儲存,適合少量資料的儲存。 NVP:Name/Value pair, 名稱/值 對。 2.
Android-影象識別專案OpenCV(4):開發思路以及問題
六、開發思路 搭建好環境和做好各種準備功夫,接下來就開始我們的開發之路。 首先,我們先檢視一下官方教程文件,看有沒有我們需要的例子。我找到了一個二維影象識別的例子: 這個教程是用C++寫的,用計算特徵點來比對兩幅影象。如果我們用這個演算法可得到特徵點的匹
即時通訊音視訊開發(七):音訊基礎及編碼原理入門
前言 即時通訊應用中的實時音視訊技術,幾乎是IM開發中的最後一道高牆。原因在於:實時音視訊技術 = 音視訊處理技術 + 網路傳輸技術 的橫向技術應用集合體,而公共網際網路不是為了實時通訊設計的。 系列文章 《即時通訊音視訊開發(五):認識主流視訊編碼技術H.264》 《即時
即時通訊音視訊開發(六):如何開始音訊編解碼技術的學習
前言 即時通訊應用中的實時音視訊技術,幾乎是IM開發中的最後一道高牆。原因在於:實時音視訊技術 = 音視訊處理技術 + 網路傳輸技術 的橫向技術應用集合體,而公共網際網路不是為了實時通訊設計的。 系列文章 《即時通訊音視訊開發(四):視訊編解碼之預測技術介紹》 《即時通訊音
iOS開發簡記(4):錄音AVAudioRecorder
fail pst 記錄 通道 cdn amp enabled 廣州 指定 錄音,聲音的采集,一般有兩種實現辦法,一是使用AVAudioRecorder,一是使用AudioUnit。如果只是簡單的錄音,使用AVAudioRecorder就可以了,如果想更靈活地處理剛錄到的聲音
Android studio3.0對於百度地圖api開發(4)——百度地圖地圖覆蓋物製作
承接上文未完的繼續介紹,上文內容:https://blog.csdn.net/qq_41562408/article/details/82810484主要實現百度地圖的定位以及對於地圖覆蓋物進行簡單介紹,這篇文章便是對於地圖覆蓋物進行,經過閱讀開發文件,我們會發