android頻譜
❶ Android音頻開發(7):音樂可視化-FFT頻譜圖
項鎮蔽旅培目地址: https://github.com/zhaolewei/MusicVisualizer
視頻演示地址:御鎮州 https://www.bilibili.com/video/av30388154/
Visualizer 有兩個比較重要的參數
快速傅里葉轉換(FFT)詳細分析: https://zhuanlan.hu.com/p/19763358
❷ Android -- 音視頻基礎知識
幀,是視頻的一個基本概念,表示一張畫面,如上面的翻頁動畫書中的一頁,就是一幀。一個視頻就是由許許多多幀組成的。
幀率,即單位時間內幀的數量,單位為:幀/秒 或fps(frames per second)。一秒內包含多少張圖片,圖片越多,畫面越順滑,過渡越自然。 幀率的一般以下幾個典型值:
24/25 fps:1秒 24/25 幀,一般的電影幀率。
30/60 fps:1秒 30/60 幀,游戲的幀率,30幀可以接受,60幀會感覺更加流暢逼真。
85 fps以上人眼基本無法察覺出來了,所以更高的幀率在視頻里沒有太大意義。
這里我們只講常用到的兩種色彩空間。
RGB的顏色模式應該是我們最熟悉的一種,在現在的電子設備中應用廣泛。通過R G B三種基礎色,可以混合出所有的顏色。
這里著重講一下YUV,這種色彩空間並不是我們熟悉的。這是一種亮度與色度分離的色彩格式。
早期的電視都是黑白的,即只有亮度值,即Y。有了彩色電視以後,加入了UV兩種色度,形成現在的YUV,也叫YCbCr。
Y:亮度,就是灰度值。除了表示亮度信號外,還含有較多的綠色通道量。
U:藍色通道與亮度的差值。
V:紅色通道與亮度的差值。
音頻數據的承載方式最常用的是 脈沖編碼調制 ,即 PCM 。
在自然界中,聲音是連續不斷的,是一種模擬信號,那怎樣才能把聲音保存下來呢?那就是把聲音數字化,即轉換為數字信號。
我們知道聲音是一種波,有自己的振幅和頻率,那麼要保存聲音,就要保存聲音在各個時間點上的振幅。
而數字信號並不能連續保存所有時間點的振幅,事實上,並不需要保存連續的信號,就可以還原到人耳可接受的聲音。
根據奈奎斯特采樣定理:為了不失真地恢復模擬信號,采樣頻率應該不小於模擬信號頻譜中最高頻率的2倍。
根據以上分析,PCM的採集步驟分為以下步驟:
采樣率,即采樣的頻率。
上面提到,采樣率要大於原聲波頻率的2倍,人耳能聽到的最高頻率為20kHz,所以為了滿足人耳的聽覺要求,采樣率至少為40kHz,通常為44.1kHz,更高的通常為48kHz。
采樣位數,涉及到上面提到的振幅量化。波形振幅在模擬信號上也是連續的樣本值,而在數字信號中,信號一般是不連續的,所以模擬信號量化以後,只能取一個近似的整數值,為了記錄這些振幅值,采樣器會採用一個固定的位數來記錄這些振幅值,通常有8位、16位、32位。
位數越多,記錄的值越准確,還原度越高。
最後就是編碼了。由於數字信號是由0,1組成的,因此,需要將幅度值轉換為一系列0和1進行存儲,也就是編碼,最後得到的數據就是數字信號:一串0和1組成的數據。
整個過程如下:
聲道數,是指支持能不同發聲(注意是不同聲音)的音響的個數。 單聲道:1個聲道
雙聲道:2個聲道
立體聲道:默認為2個聲道
立體聲道(4聲道):4個聲道
碼率,是指一個數據流中每秒鍾能通過的信息量,單位bps(bit per second)
碼率 = 采樣率 * 采樣位數 * 聲道數
這里的編碼和上面音頻中提到的編碼不是同個概念,而是指壓縮編碼。
我們知道,在計算機的世界中,一切都是0和1組成的,音頻和視頻數據也不例外。由於音視頻的數據量龐大,如果按照裸流數據存儲的話,那將需要耗費非常大的存儲空間,也不利於傳送。而音視頻中,其實包含了大量0和1的重復數據,因此可以通過一定的演算法來壓縮這些0和1的數據。
特別在視頻中,由於畫面是逐漸過渡的,因此整個視頻中,包含了大量畫面/像素的重復,這正好提供了非常大的壓縮空間。
因此,編碼可以大大減小音視頻數據的大小,讓音視頻更容易存儲和傳送。
視頻編碼格式有很多,比如H26x系列和MPEG系列的編碼,這些編碼格式都是為了適應時代發展而出現的。
其中,H26x(1/2/3/4/5)系列由ITU(International Telecommunication Union)國際電傳視訊聯盟主導
MPEG(1/2/3/4)系列由MPEG(Moving Picture Experts Group, ISO旗下的組織)主導。
當然,他們也有聯合制定的編碼標准,那就是現在主流的編碼格式H264,當然還有下一代更先進的壓縮編碼標准H265。
H264是目前最主流的視頻編碼標准,所以我們後續的文章中主要以該編碼格式為基準。
H264由ITU和MPEG共同定製,屬於MPEG-4第十部分內容。
我們已經知道,視頻是由一幀一幀畫面構成的,但是在視頻的數據中,並不是真正按照一幀一幀原始數據保存下來的(如果這樣,壓縮編碼就沒有意義了)。
H264會根據一段時間內,畫面的變化情況,選取一幀畫面作為完整編碼,下一幀只記錄與上一幀完整數據的差別,是一個動態壓縮的過程。
在H264中,三種類型的幀數據分別為
I幀:幀內編碼幀。就是一個完整幀。
P幀:前向預測編碼幀。是一個非完整幀,通過參考前面的I幀或P幀生成。
B幀:雙向預測內插編碼幀。參考前後圖像幀編碼生成。B幀依賴其前最近的一個I幀或P幀及其後最近的一個P幀。
全稱:Group of picture。指一組變化不大的視頻幀。
GOP的第一幀成為關鍵幀:IDR
IDR都是I幀,可以防止一幀解碼出錯,導致後面所有幀解碼出錯的問題。當解碼器在解碼到IDR的時候,會將之前的參考幀清空,重新開始一個新的序列,這樣,即便前面一幀解碼出現重大錯誤,也不會蔓延到後面的數據中。
DTS全稱:Decoding Time Stamp。標示讀入內存中數據流在什麼時候開始送入解碼器中進行解碼。也就是解碼順序的時間戳。
PTS全稱:Presentation Time Stamp。用於標示解碼後的視頻幀什麼時候被顯示出來。
前面我們介紹了RGB和YUV兩種圖像色彩空間。H264採用的是YUV。
YUV存儲方式分為兩大類:planar 和 packed。
planar如下:
packed如下:
上面說過,由於人眼對色度敏感度低,所以可以通過省略一些色度信息,即亮度共用一些色度信息,進而節省存儲空間。因此,planar又區分了以下幾種格式:YUV444、 YUV422、YUV420。
YUV 4:4:4采樣,每一個Y對應一組UV分量。
YUV 4:2:2采樣,每兩個Y共用一組UV分量。
YUV 4:2:0采樣,每四個Y共用一組UV分量。
其中,最常用的就是YUV420。
YUV420屬於planar存儲方式,但是又分兩種類型:
YUV420P:三平面存儲。數據組成為YYYYYYYYUUVV(如I420)或YYYYYYYYVVUU(如YV12)。
YUV420SP:兩平面存儲。分為兩種類型YYYYYYYYUVUV(如NV12)或YYYYYYYYVUVU(如NV21)
原始的PCM音頻數據也是非常大的數據量,因此也需要對其進行壓縮編碼。
和視頻編碼一樣,音頻也有許多的編碼格式,如:WAV、MP3、WMA、APE、FLAC等等,音樂發燒友應該對這些格式非常熟悉,特別是後兩種無損壓縮格式。
但是,我們今天的主角不是他們,而是另外一個叫AAC的壓縮格式。
AAC是新一代的音頻有損壓縮技術,一種高壓縮比的音頻壓縮演算法。在MP4視頻中的音頻數據,大多數時候都是採用AAC壓縮格式。
AAC格式主要分為兩種:ADIF、ADTS。
ADIF:Audio Data Interchange Format。音頻數據交換格式。這種格式的特徵是可以確定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,即它的解碼必須在明確定義的開始處進行。這種格式常用在磁碟文件中。
ADTS:Audio Data Transport Stream。音頻數據傳輸流。這種格式的特徵是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特徵類似於mp3數據流格式。
ADIF數據格式:
ADTS 一幀 數據格式(中間部分,左右省略號為前後數據幀):
AAC內部結構也不再贅述,可以參考AAC 文件解析及解碼流程
細心的讀者可能已經發現,前面我們介紹的各種音視頻的編碼格式,沒有一種是我們平時使用到的視頻格式,比如:mp4、rmvb、avi、mkv、mov...
沒錯,這些我們熟悉的視頻格式,其實是包裹了音視頻編碼數據的容器,用來把以特定編碼標准編碼的視頻流和音頻流混在一起,成為一個文件。
例如:mp4支持H264、H265等視頻編碼和AAC、MP3等音頻編碼。
我們在一些播放器中會看到,有硬解碼和軟解碼兩種播放形式給我們選擇,但是我們大部分時候並不能感覺出他們的區別,對於普通用戶來說,只要能播放就行了。
那麼他們內部究竟有什麼區別呢?
在手機或者PC上,都會有CPU、GPU或者解碼器等硬體。通常,我們的計算都是在CPU上進行的,也就是我們軟體的執行晶元,而GPU主要負責畫面的顯示(是一種硬體加速)。
所謂軟解碼,就是指利用CPU的計算能力來解碼,通常如果CPU的能力不是很強的時候,一則解碼速度會比較慢,二則手機可能出現發熱現象。但是,由於使用統一的演算法,兼容性會很好。
硬解碼,指的是利用手機上專門的解碼晶元來加速解碼。通常硬解碼的解碼速度會快很多,但是由於硬解碼由各個廠家實現,質量參差不齊,非常容易出現兼容性問題。
MediaCodec 是Android 4.1(api 16)版本引入的編解碼介面,是所有想在Android上開發音視頻的開發人員繞不開的坑。
由於Android碎片化嚴重,雖然經過多年的發展,Android硬解已經有了很大改觀,但實際上各個廠家實現不同, 還是會有一些意想不到的坑。
相對於FFmpeg,Android原生硬解碼還是相對容易入門一些,所以接下來,我將會從MediaCodec入手,講解如何實現視頻的編解碼,以及引入OpenGL實現對視頻的編輯,最後才引入FFmpeg來實現軟解,算是一個比較常規的音視頻開發入門流程吧。
❸ android頻譜分析怎麼做
Android 音樂頻譜分析,把時域上連續的信號(波形)強度轉換成離散的頻域信號(頻譜)。
目前該 軟體,沒有安卓版,主要是太復雜了,大型軟體很少有安卓版的。實時頻譜分析儀/音頻可視化功能: - 128個高品質的頻段20Hz到22kHz的] - 對數頻率刻度,以符合人類感知 - 低延遲高響應性 - 的幀率看到平滑的頻率和幅度的動作 - 高性能的本機代碼中使用OpenGL ES 2.0的參考 - FFT窗口大小2048@43/58(用於ARMv7+)幀
❹ 求助==怎麼在android 鎖屏界面實現音樂頻譜圖
Visualizer 類,這個類只在Android 2.3以上的API才支持。
首先實例化Visualizer,參數SessionId可以通過MediaPlayer的對象獲得
[java] view plain
visualizer = new Visualizer(mPlayerInstance.getAudioSessionId());
接著設置需要轉換的音樂內容長度,專業的說這就是采樣,該采樣值一般為2的指數倍,如64,128,256,512,1024。這里我設置了128,原因是長度越長,FFT演算法運行時間更長。
[java] view plain
❺ Android OpenGLES3繪圖 - 音頻可視化(模仿MIUI系統效果)
小米手機播放音樂時鎖屏頁面可以設置音頻可視化效果,這是用OpenGL繪制出來的,我們來實現一下。
首先簡單分析一下原理:
圖形的每一行代表一個聲音片段,它就是一個一維數組,按照數值大小繪制不同的高度,就形成了一條「山脈」;獲取到下一個聲音片段後,將它繪制到下面一行,然後畫面整體向上滾動就可以了。整體類似於繪制一張游戲里常見的3D地形圖。
創建一個MediaPlayer,它可以直接讀取res/raw裡面的音頻文件,start()開始播放
Visualizer是Android SDK裡面提供的音頻分析工具,它可以直接獲取播放的音頻的波形和頻譜。onWaveFormDataCapture回調方法里返回的是原始的PCM波形數組,onFftDataCapture回調方法里返回的是經過快速傅里葉方法轉換後的聲音頻譜數組,數組的第一位是直流分量,後面是不同頻率的數值。
每次獲取到的是一組聲音數據,將它傳給Render繪制。
首先確定圖形的長寬,寬度w其實是由每組音頻的數組長度決定,可以由Visualizer.getCaptureSizeRange()[0]獲取,這里獲取的是最小的數組,也可以用Visualizer.getCaptureSizeRange()[1]獲取最大的數組;長度h可以自己設置想展示多長。
繪制地形圖也就是繪制w * h * 2個三角形,創建vao、vbo和ebo,由於頂點的位置都是固定的,可以在頂點著色器中用gl_VertexID獲取,所以vbo裡面不用傳頂點數據,直接傳聲音數組。
由於圖形是不斷刷新最後一行並向上滾動的,那麼需要使用一個隊列,為了每一幀數據改變最小,不至於進行大量的數組復制和移動。我們 用ByteBuffer vertexBuffer模擬一個循環隊列,使用一個行號int lineNum來標記隊列的頭部。每添加一行數據後,lineNum會加上w,這樣ByteBuffer分成了兩部分:lineNum * w之後的是新舊數據,之前的是舊數據 。
現在我們需要將數據從主內存(vertexBuffer)復制到GPU顯存(vbo)。vertexBuffer里是一個循環隊列,而vbo裡面只能順序保存(因為ebo序號是順序的,vbo不是順序圖形就會錯亂),更新vbo數據緩存的glBufferSubData方法支持設置偏移位置部分更新。那麼我們 先將vertexBuffer定位到lineNum * w,將它後面的舊數據復制到vbo的前面;然後將vertexBuffer定位到0,將剩下的新數據復制到vbo的後面 。這樣就保證了繪制時從上到下,從舊到新。
為了讓顏色更豐富,這里用了地形圖中常用的熱度漸變色數組。
理論上音頻數值是unsigned byte格式的,但是著色器不支持byte格式,我直接用int vPosition接收數據,然而數值范圍不再是0~255了,這有點奇怪,我沒有深入研究。簡單測試了一下,發現取int的前8位,再進行一點比例縮放,用它去漸變色數組里取顏色,會取得較好的顯示效果。
頂點著色器
shader_audio_v.glsl
將顏色傳給片段著色器顯示
shader_audio_f.glsl
最終效果如下圖,錄屏設置的碼率比較低,實際上是很清晰的。
完整項目在 SurfacePaint 項目下的 opengles3 模塊里的audio。
❻ Android播放器如何製作柱狀頻譜圖急求~~
能拿到數據的話,自己畫唄,自己寫個view,ondraw裡面自己畫幾個柱形就可以了
❼ Android音頻採集
最近項目中需要實現手機採集聲音頻率實現設備律動的效果,整理了下Android與聲音相關的知識。
根據聲音振幅、頻率獲取顏色值,通過藍牙mesh發送指令給燈改變其顏色值。
Android聲音採集相關Api
快速傅里葉變換公式
Mesh網發送rgb值相關指令
人主觀感覺聲音的大小(音量),振幅與人離聲源的距離決定,振幅越大,離聲源的距離越小,響度越大。
LP= 20×lgP/P0
LP:聲壓級(db)
P:聲壓(Pa)
P0:基準聲壓:2*10-5Pa,該值是對800HZ聲音人耳剛能聽到的最低聲壓。
聲音的高低,由頻率決定,頻率謹辯越高,音調越高。
頻率是每秒經吵洞過一給定點的聲波數量,單位赫茲(Hz)
人耳能聽到20~20kHz的聲音。
音品,波形決定聲音的音色。
MediaRecorder:基於文件錄音,已集成錄音、編碼、壓縮
把模擬信號數字化的過程
采樣頻率越高,紅色間隔越密集,記錄音頻所用數據量越大,音頻質量越高。
采樣定理(奈奎斯特理論):當采樣頻率大於信號中最高頻率的2倍時,采樣後的數字信號完整地保留原始信號中的信息。人耳能聽到20~20kHz的聲音,為了保證聲音不失真,采樣頻率應在40kHz以上。
目前44100Hz是唯一可以保證兼容所有Android手機的采樣率。
指將模擬信號分成幾個等級,量化精度越高,聲音質量越好,單位Bit。
CD標准量化精度16Bit,DVD標准量化精度24Bit。
16Bit可以保證兼容所有Android手機。
音頻採集、播放可以疊加,可以同時從多個音頻源採集聲音,例如:單聲道/雙聲道。
即采樣時間,例如20ms一幀代表20ms為單位的數據量為一幀音頻。
一幀音頻幀大小 = 采樣率 x 位寬 x 采樣時間 x 通道數
例:采樣率8000,位寬8,通道2,采樣間隔20ms
(8000 * 8/8 *2)/ (1000/20 ) = 320Byte //1位元組 = 8 bits
對audioData進行快速傅里葉變化,時域->頻域的變化,可以將信號的頻譜提取出來。
傅立葉變換就是多個祥碰缺正餘弦波疊加可以用來近似任何一個原始的周期函數,它實質是是頻域函數和時域函數的轉換。
Visualizer:檢索當前正在播放的音頻,對其進行編碼
以下基於AudioRecord採集的音頻數據後進行快速傅里葉變換得到頻率值