当前位置: 首页>Python>正文

音頻頻譜分析儀安卓版,[Android]自定義繪制一個簡易的音頻條形圖,附上對MP3音頻波形數據的采集與展現

音頻頻譜分析儀安卓版,[Android]自定義繪制一個簡易的音頻條形圖,附上對MP3音頻波形數據的采集與展現

??在項目中需要到數據統計的地方,往往都需要到一些圖的展示,比如曲線圖、折線圖、餅狀圖、圓形圖、條形圖等等。在本文中我們來實現一個簡易的條形圖的繪制。

??首先,我們創建一個BarGraphView類,讓這個類繼承自View,一般重寫View都必須重寫View的一參構造方法和二參構造方法,如下:

public class BarGraphView extends View {
public BarGraphView(Context context) {super(context);}public BarGraphView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}}

??其次,繪制的過程在于onDraw方法的回調,我們重寫這個方法,來繪制條形圖:

 @Overrideprotected void onDraw(Canvas canvas) {Log.i("bar","onDraw");super.onDraw(canvas);Random random = new Random();rectWidth = canvas.getWidth()/barCount;for (int i = 0;i<barCount;i++){//生成0-99的隨機數,作為高度的百分比,得出一個隨機高度int currentHeight = (random.nextInt(10))*canvas.getHeight()/100;Log.i("bar","currentHeight:"+currentHeight);canvas.drawRect(rectWidth*i+offset,currentHeight,rectWidth*(i+1),getHeight(),mPaint);}postInvalidateDelayed(speed);}

??上文代碼中,我們先通過canvas.getWidth()/barCount;計算出每個條形的寬度,而高度則是隨機取出總高度的百分比。
最后調用canvas.drawRect(rectWidth*i+offset,currentHeight,rectWidth*(i+1),getHeight(),mPaint);

??Canvas代表一個畫板,他可以畫出很圖案,比如條形圖其實就是一個個矩形組成的,那么我們利用drawRect可以畫出一個矩形來作為一個條形。

音頻頻譜分析儀安卓版、??在drawRect方法中五個參數分別代表著:left、top,right、bottom,畫筆。

??其實也就是左上頂點坐標(left,top)和一個右下頂點的坐標來確定一個矩形(right,bottom)
我們用rectWidth*i+offset,來定義矩形的left,用隨機數來定義矩形的top,用計算出的寬度來定義矩形的right,用總體高度來定義矩形的bottm。

??而第五個參數Paint,代表著一個畫筆,有畫板了,也知道要畫什么,但也得有個筆來畫才能展現出來是吧,所以我們增加一個init方法來定義一個Paint變量,讓構造方法調用這個init方法:

    private void init(){mPaint = new Paint();mPaint.setColor(getResources().getColor(R.color.colorAccent));mPaint.setStyle(Paint.Style.FILL);}

??這里為了簡單,我們只是把畫筆定義為默認的colorAccent顏色。

??在onDraw方法的最后調用postInvalidateDelayed(speed);來刷新,模擬一個條形圖動態變化的效果,調用postInvalidateDelayed時View會再回調onDraw方法。

??然后,我們提供幾個設置的方法:

    public void setBarCount(int barCount) {this.barCount = barCount;}public void setOffset(int offset) {this.offset = offset;}public void setSpeed(int speed) {this.speed = speed;}

matlab讀取音頻文件并畫出波形,??好了,一個簡易的條形圖就已經初具規模了。通常我們為了更為直觀的看到一個效果,會把條形圖的條形設置成一個顏色漸變的效果,怎么做呢?

??可以重寫View的onSizeChanged方法,在該方法中,我們利用LinearGradient這個顏色漸變的類來裝入畫筆:

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);LinearGradient linearGradient = new LinearGradient(0,0,rectWidth,getHeight(),Color.RED,Color.GREEN, Shader.TileMode.CLAMP);mPaint.setShader(linearGradient);}

??代碼很簡單,我們只是創建一個LinearGradient對象,對象的前面四個參數代表著兩個坐標,也就是從(x1,y1)到(x2,y2)的漸變過程,我們讓起點坐標都定位0,然后讓終點坐標設置為條形圖的最高點。第五個參數表示起始顏色,第六個顏色表示終止顏色,我們分別用紅和綠,來表示一個綠到紅的漸變過程。最后一個參數Shader.TileMode.CLAMP表示如果著色器超出原始邊界范圍,會復制邊緣顏色。最后我們把創建出來的LinearGradient對象裝入畫筆,就實現一個條形圖的漸變效果了。

??到這里,我們就已經完成了一個簡易條形圖的制作了,另外一個不得不說的點是,由于我們是繼承自View,默認View的warp_content模式是填充父布局,也就是跟match_content一樣的效果了,那么我們可以來設置一個值,使得如果定義屬性為warp_content的話,則有一個默認的值。

??我們重寫onMeasure方法,而其實onMeasure方法中,默認就是調用setMeasuredDimension方法,所以我們可以直接把自定義好的寬高值傳遞給setMeasuredDimension。

??我們定義一個寬度的測量:

  private int measureWidth(int widthMeasureSpec){int width;int spacMode = MeasureSpec.getMode(widthMeasureSpec);int size = MeasureSpec.getSize(widthMeasureSpec);if(spacMode==MeasureSpec.EXACTLY){width = size;}else {width = 300;if(spacMode==MeasureSpec.AT_MOST){width = Math.min(width,size);}}Log.i("bar","width:"+width);return width;}

frequency音頻發生器、??在Android中,采用了一個int數值來代表一個測量值,用高二位來代表測量的模式,其余位數代表測量的數值。利用MeasureSpec的getMode和getSize方法我們很容易得到這兩個數值。

??當我們定義寬或高是match_content或者給定了一個確切的數值的話,則模式就是MeasureSpec.EXACTLY,否則就是MeasureSpec.AT_MOST。其實還有個MeasureSpec.UNSPECIFIED,表示空間不受限制,一般View里面不用到這個屬性。如果我們設置為warp_content的話則模式就是MeasureSpec.AT_MOST,我們進行判斷,取出一個最小值作為默認包裹的大小。
??另外再定義一個高度的測量,寫法幾乎一致:

private int measureHeight(int heightMeasureSpec){int height;int spacMode = MeasureSpec.getMode(heightMeasureSpec);int size = MeasureSpec.getSize(heightMeasureSpec);if(spacMode==MeasureSpec.EXACTLY){height = size;}else {height = 300;if(spacMode==MeasureSpec.AT_MOST){height = Math.min(height,size);}}Log.i("bar","height:"+height);return height;}

??最后我們在onMeasure方法中,這樣子寫:

  @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));}

好了,我們來測試一下,創建一個Activity:

public class BarGraphActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_bar_graph);BarGraphView view = (BarGraphView) findViewById(R.id.bargraph);view.setOffset(10);view.setSpeed(300);//設置間隔刷新速度view.setBarCount(20);//設置條形圖的數量}}

??在布局里面定義:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="15dp"tools:context="com.example.qyz.BarGraphActivity">
<com.example.qyz.BarGraphView
    android:id="@+id/bargraph"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

??然后運行,截圖如下:

聲音轉換成波形圖的軟件。條形圖

??這樣子我們的一個簡易條形圖就制作完畢了。
??最后貼出BarGraphView的代碼:

public class BarGraphView extends View {private  int barCount =30;//條形的數量private int rectWidth = 15;//條形的寬度private int offset = 10;private int speed = 300;Paint mPaint;public BarGraphView(Context context) {super(context);init();}public BarGraphView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}private void init(){mPaint = new Paint();mPaint.setColor(getResources().getColor(R.color.colorAccent));mPaint.setStyle(Paint.Style.FILL);}public void setBarCount(int barCount) {this.barCount = barCount;}public void setOffset(int offset) {this.offset = offset;}public void setSpeed(int speed) {this.speed = speed;}@Overrideprotected void onDraw(Canvas canvas) {Log.i("bar","onDraw");super.onDraw(canvas);Random random = new Random();rectWidth = canvas.getWidth()/barCount;for (int i = 0;i<barCount;i++){//生成0-99的隨機數,作為高度的百分比,得出一個隨機高度int currentHeight = (random.nextInt(100))*canvas.getHeight()/100;Log.i("bar","currentHeight:"+currentHeight);canvas.drawRect(rectWidth*i+offset,currentHeight,rectWidth*(i+1),getHeight(),mPaint);}postInvalidateDelayed(speed);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));}private int measureWidth(int widthMeasureSpec){int width;int spacMode = MeasureSpec.getMode(widthMeasureSpec);int size = MeasureSpec.getSize(widthMeasureSpec);if(spacMode==MeasureSpec.EXACTLY){width = size;}else {width = 300;if(spacMode==MeasureSpec.AT_MOST){width = Math.min(width,size);}}Log.i("bar","width:"+width);return width;}private int measureHeight(int heightMeasureSpec){int height;int spacMode = MeasureSpec.getMode(heightMeasureSpec);int size = MeasureSpec.getSize(heightMeasureSpec);if(spacMode==MeasureSpec.EXACTLY){height = size;}else {height = 300;if(spacMode==MeasureSpec.AT_MOST){height = Math.min(height,size);}}Log.i("bar","height:"+height);return height;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);LinearGradient linearGradient = new LinearGradient(0,0,rectWidth,getHeight(),Color.RED,Color.GREEN, Shader.TileMode.CLAMP);mPaint.setShader(linearGradient);}
}

??為了一個真實效果,我們來接入實際MP3的波形音頻,讓條形圖顯示MP3的波形數值,

??怎么得到mp3的波形數值呢?可以利用Visualizer類來進行采集,這部分代碼我直接貼出來,在相關代碼處已經做了注釋:

public class BarGraphActivity extends AppCompatActivity {// 定義播放聲音的MediaPlayerprivate MediaPlayer mPlayer;Visualizer mVisualizer;WaveView waveView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_bar_graph);waveView = (WaveView) findViewById(R.id.bargraph);waveView.setOffset(10);mPlayer = MediaPlayer.create(this, R.raw.demo);setupVisualizer();// 開發播放音樂mPlayer.start();}/*** 初始化頻譜*/private void setupVisualizer(){// 以MediaPlayer的AudioSessionId創建Visualizer// 顯示該MediaPlayer播放的MP3音頻數據mVisualizer = new Visualizer(mPlayer.getAudioSessionId());//設置數據采樣值,一般為2的指數倍,如64,128,256,512,1024。mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[0]);/*** listener,監聽采樣過程*rate, 采樣的周期,即隔多久采樣一次*iswave,波形信號*isfft,是FFT信號*/mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener(){//采集快速傅里葉變換有關的數據@Overridepublic void onFftDataCapture(Visualizer visualizer,byte[] fft, int samplingRate){}//采集波形數據@Overridepublic void onWaveFormDataCapture(Visualizer visualizer,byte[] waveform, int samplingRate){waveView.update(waveform);Log.i("bar","onWaveFormDataCapture length:"+waveform.length);}}, Visualizer.getMaxCaptureRate() / 5, true, false);//必須設置為true后,采集工作才會開始mVisualizer.setEnabled(true);}
}

??因為我們在上文的數值都是寫死成隨機的,我們復制BarGraphView重命名為:WaveView,把onDraw方法的代碼改為如下:

    @Overrideprotected void onDraw(Canvas canvas) {Log.i("bar","onDraw");super.onDraw(canvas);if(data==null)return;rectWidth = canvas.getWidth()*3/data.length;for (int i = 0,j=0;j<data.length;i++,j+=3){int currentHeight = (int) (getHeight()*((data[i]+128)/256.0));canvas.drawRect(rectWidth*i+offset,currentHeight,rectWidth*(i+1),getHeight(),mPaint);}}

??由于數據比較多,我們把采集到的byte數組數據,128個采集值每3個顯示一個出來。

音頻波形可視化app???最后,還要申請一下權限:

<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>

音頻

https://www.nshth.com/python/338723.html
>

相关文章:

  • 音頻頻譜分析儀安卓版
  • matlab讀取音頻文件并畫出波形
  • frequency音頻發生器
  • 聲音轉換成波形圖的軟件
  • 音頻波形可視化app
  • 音頻分析儀軟件
  • 音樂波形圖制作手機軟件
  • 十段音頻自定義怎么調
  • 國二python難嗎,python字符串(二)
  • 電腦軟件下載app,在電腦上體驗了 16 款手機 App 后,我很失望
  • elasticsearch中文文檔,Elastic安全分析新利器 —— Event Query Language (EQL) 介紹
  • 數據結構與算法python,[FreeCodeCamp筆記] Python 數據結構和算法1 二分搜索 Binary Search
  • 黑蘋果macOS系統鏡像工具,MacOS Monterey 12.2.1 (21D62) OC 0.7.8 / Cl 5144 / PE 三分區原版黑蘋果鏡像
  • 51單片機畢業設計論文,【畢業設計】基于單片機無線充電的4軸飛行器 -物聯網 嵌入式 stm32
  • 數據庫基礎知識整理,數據庫筆記整理
  • python運行不報錯又無任何結果輸出,linux 正確錯誤輸出_報告錯誤的正確方法
  • 計算機組成原理第六版課后答案,杭電計算機組成原理實驗九R-I,杭電計組實驗9-實現R-I型指令的CPU設計實驗.doc
  • python面向對象,Python零基礎速成班-第10講-Python面向對象編程(下),Property屬性、特殊方法、設計模式、鏈表應用
  • 數據庫視圖是什么,【SpringMVC】SpringMVC模型數據+視圖解析器
  • mp3格式轉換器,FFmpeg支持的音頻和視頻編解碼格式
  • 音樂學校招生要求,學校的音樂樓
  • c語言輸入兩個數輸出較大數,C語言求兩個數的較大值
  • 定義一個函數求三個數的最大值,輸入兩個整數,要求輸出其中值較大者。要求用函數求出最大值
  • MySQL學習 DAY1
  • 一個眼神一個微笑就讓人滿足,看得到的微笑
  • centos7安裝MySQL,centos7下載spark連接mysql數據庫提取數據(pyspark,Scala,python獨立執行)
  • node.js開發,從零開始nodejs系列文章-nodejs到底能干什么
  • python控制軟件自動化,Python實現網站自動登錄---傻瓜教程
  • get all of,resent = msg.get_all('Resent-Date') AttributeError: 'str' object h
  • opencv人體動作識別,torchvision使用keypoint rcnn 進行人體關鍵點定位
  • 深度卷積神經網絡原理與實踐,卷積神經網絡resent網絡實踐
  • 服務器,win服務器系統路由器,Windows server 2012 之路由功能
  • 小青蛙走迷宮的問題
  • 漢諾塔-小青蛙
  • 小青蛙oracle跟蹤,在小青蛙TOAD中用oracle語句寫
  • 音頻頻譜分析儀安卓版,[Android]自定義繪制一個簡易的音頻條形圖,附上對MP3音頻波形數據的采集與展現
  • 連乘符號∏的運算法則,∏這個是什么符號?
  • 用例失敗jenkins卻構建成功,jenkins 構建異常_jenkins構建失敗的原因是什么?