Android 音視頻深入 一 AudioRecord錄音生成pcm轉換為wav(附源碼下載)

来源:https://www.cnblogs.com/jianpanwuzhe/archive/2018/02/02/8403784.html
-Advertisement-
Play Games

本篇項目地址,名字是AudioRecord錄音(能暫停,將pch轉換為wav),求starhttps://github.com/979451341/Audio-and-video-learning-materials先來段官方說明 1.AndioRecord大概說明 AndioRecord類的主要功 ...


本篇項目地址,名字是AudioRecord錄音(能暫停,將pch轉換為wav),求star
https://github.com/979451341/Audio-and-video-learning-materials

先來段官方說明

1.AndioRecord大概說明

  AndioRecord類的主要功能是讓各種JAVA應用能夠管理音頻資源,以便它們通過此類能夠錄製聲音相關的硬體所收集的聲音。此功能的實現就是通過”pulling”(讀取)AudioRecord對象的聲音數據來完成的。在錄音過程中,應用所需要做的就是通過後面三個類方法中的一個去及時地獲取AudioRecord對象的錄音數據. AudioRecord類提供的三個獲取聲音數據的方法分別是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int). 無論選擇使用那一個方法都必須事先設定方便用戶的聲音數據的存儲格式。

  開始錄音的時候,AudioRecord需要初始化一個相關聯的聲音buffer, 這個buffer主要是用來保存新的聲音數據。這個buffer的大小,我們可以在對象構造期間去指定。它表明一個AudioRecord對象還沒有被讀取(同步)聲音數據前能錄多長的音(即一次可以錄製的聲音容量)。聲音數據從音頻硬體中被讀出,數據大小不超過整個錄音數據的大小(可以分多次讀出),即每次讀取初始化buffer容量的數據。

2.AudioRecord對象創建

AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

audioSource
音頻源:指的是從哪裡採集音頻。這裡我們當然是從麥克風采集音頻,所以此參數的值為MIC

sampleRateInHz
採樣率:音頻的採樣頻率,每秒鐘能夠採樣的次數,採樣率越高,音質越高。給出的實例是44100、22050、11025但不限於這幾個參數。例如要採集低質量的音頻就可以使用4000、8000等低採樣率。

channelConfig
聲道設置:android支持雙聲道立體聲和單聲道。MONO單聲道,STEREO立體聲

audioFormat
編碼制式和採樣大小:採集來的數據當然使用PCM編碼(脈衝代碼調製編碼,即PCM編碼。PCM通過抽樣、量化、編碼三個步驟將連續變化的模擬信號轉換為數字編碼。) android支持的採樣大小16bit 或者8bit。當然採樣大小越大,那麼信息量越多,音質也越高,現在主流的採樣大小都是16bit,在低質量的語音傳輸的時候8bit足夠了。

bufferSizeInBytes
採集數據需要的緩衝區的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。
AudioRecord.getMinBufferSize(sampleRateInHz,
                channelConfig, channelConfig);


3.PCM和WAV文件

PCM

PCM是在由模擬信號向數字信號轉化的一種常用的編碼格式,稱為脈衝編碼調製,PCM將模擬信號按照一定的間距劃分為多段,然後通過二進位去量化每一個間距的強度。PCM表示的是音頻文件中隨著時間的流逝的一段音頻的振幅。Android在WAV文件中支持PCM的音頻數據。

WAV文件

WAV,MP3等是我們比較常見的音頻格式,不同的編碼格式對原始音頻採用的編碼方式也是不同的,通常為了方便傳輸等問題,會對原始音頻進行壓縮,同時為了能夠使得播放器能夠識別該種格式,所以在每種格式的頭文件都是特定的,有一定的規則,來讓播放器識別出是該種格式,然後按著相應的解碼演算法去播放後面的音頻文件。


4.代碼運行過程

首先是創建和配置AudioRecord

 

  //音頻輸入-麥克風
    private final static int AUDIO_INPUT = MediaRecorder.AudioSource.MIC;
    //採用頻率
    //44100是目前的標準,但是某些設備仍然支持22050,16000,11025
    //採樣頻率一般共分為22.05KHz、44.1KHz、48KHz三個等級
    private final static int AUDIO_SAMPLE_RATE = 16000;
    //聲道 單聲道
    private final static int AUDIO_CHANNEL = AudioFormat.CHANNEL_IN_MONO;
    //編碼
    private final static int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
    // 緩衝區位元組大小
    private int bufferSizeInBytes = 0;

    //錄音對象
    private AudioRecord audioRecord;
    /**
     * 創建預設的錄音對象
     *
     * @param fileName 文件名
     */
    public void createDefaultAudio(String fileName) {
        // 獲得緩衝區位元組大小
        bufferSizeInBytes = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE,
                AUDIO_CHANNEL, AUDIO_ENCODING);
        audioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING, bufferSizeInBytes);
        this.fileName = fileName;
        status = Status.STATUS_READY;
    }

開始錄音,同時開個子線程將錄音的數據放入pcm文件

        audioRecord.startRecording();

        new Thread(new Runnable() {
            @Override
            public void run() {
                writeDataTOFile(listener);
            }
        }).start();

如何將音頻寫入文件是重點,我寫個偽代碼,說明這個代碼運行順序

首先創建pcm文件,得到他的FileOutputStream,然後不斷迴圈AudioRecord通過read將錄音的數據放入位元組數組裡,當錄音結束的時候要記得停止這個迴圈

        // new一個byte數組用來存一些位元組數據,大小為緩衝區大小
        byte[] audiodata = new byte[bufferSizeInBytes];

        FileOutputStream fos = null;
        int readsize = 0;
        try {
            File file = new File(currentFileName);
            if (file.exists()) {
                file.delete();
            }
            fos = new FileOutputStream(file);// 建立一個可存取位元組的文件
        } catch (IllegalStateException e) {
            Log.e("AudioRecorder", e.getMessage());
            throw new IllegalStateException(e.getMessage());
        } catch (FileNotFoundException e) {
            Log.e("AudioRecorder", e.getMessage());

        }
        while (true) {
            readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
            if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) {
                try {
                    fos.write(audiodata);
                } catch (IOException e) {
                    Log.e("AudioRecorder", e.getMessage());
                }
            }
        }

如何我們要實現能夠暫停錄音,只要AudioRecord.stop就行,然後當繼續錄音時在AudioRecord.start就好了,但是要另創建一個pcm記錄,當錄音結束時我們要將這些pcm一起轉換為一個wav,

至於pcm轉換為wav的代碼是固定的,我就不貼出,大家在文章首部代碼地址自取吧

參考文章
http://blog.csdn.net/hellofeiya/article/details/8968534

http://blog.csdn.net/JenseaChen/article/details/46883319

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • java使用Redis連接池 jar包為 jedis-2.9.0.jar+commons-pool2-2.4.2.jar jar下載地址 ...
  • 沒有安裝PDO yum install php70w-pdo yum install php70w-mysqlnd 兩條命令搞定 ...
  • mysql: dbs 資料庫系統 bdms 資料庫管理系統 bda 資料庫管理員 db 資料庫 dba通過dbms來操作db! 軟體項目開發周期中資料庫設計01.需求分析階段:分析客戶的業務和數據處理需求02.概要設計階段:設計資料庫的E-R模型圖,確認需求信息的正確和完整03.詳細設計階段:應用三 ...
  • 一般在做數據統計的時候會用到行轉列,假如要統計學生的成績,資料庫里查詢出來的會是這樣的,但這並不能達到想要的效果,所以要在查詢的時候做一下處理 CREATE TABLE TestTable( [Id] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarcha ...
  • [精品] 支付組件 簡要說明該組件為封裝了 微信,支付寶,銀聯支付, 一鍵快速集成,幾行代碼即可集成 微信,支付寶,銀聯支付。 ## 示例: # 測試賬號:1、銀聯支付:提供測試使用卡號、手機號信息(此類信息僅供測試,不會發生正式交易)招商銀行借記卡:6226090000000048 手機號:181 ...
  • 由類的關係圖發現原來ViewFlipper是ViewAnimator的子類,而ViewAnimator又是FrameLayout的子類。看到這個繼承關係是否對ViewFlipper的工作原理有一定的猜想? 其實ViewFlipper工作機制很簡單,如上圖,就是將添加到ViewFlipper中的子Vi ...
  • 關於inflate參數問題,我想很多人多多少少都瞭解一點,網上也有很多關於這方面介紹的文章,但是枯燥的理論或者翻譯讓很多小伙伴看完之後還是一臉懵逼,so,我今天想通過三個案例來讓小伙伴徹底的搞清楚這個東東。本篇博客我們不講源碼,只看使用。源碼的解讀會在下一篇博文中帶來。 inflate方法從大範圍來 ...
  • **分為4個流程**> 1. 源碼下載> 2. 構建編譯環境> 3. 編譯源碼> 4. 運行### 源碼下載#### 安裝git並且配置```//安裝gitsudo apt-get install git//配置git名稱和郵箱git config --global user.name "your ... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...