亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了將原始PCM數據轉換為RIFF波的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我正在嘗試將原始音頻數據從一種格式轉換為另一種格式,以便進行語音識別。

從Discord服務器以20ms塊的格式接收音頻:48Khz, 16-bit stereo signed BigEndian PCM
我使用CMU’s Sphinx進行語音識別,它將音頻作為RIFF (little-endian) WAVE audio, 16-bit, mono 16,000Hz中的InputStream

音頻數據在byte[]中接收,長度3840。該byte[]數組包含上述格式1的音頻的20ms。這意味著1秒的音頻是3840 * 50,也就是192,000。這就是每秒192,000個樣本。這是有意義的,48KHz采樣率,乘以2(96K采樣),因為一個字節是8比特,我們的音頻是16比特,并且是立體聲的另外兩倍。所以48,000 * 2 * 2 = 192,000

所以每次收到音頻包時,我首先調用此方法:

private void addToPacket(byte[] toAdd) {
    if(packet.length >= 576000 && !done) {
        System.out.println("Processing needs to occur...");
        getResult(convertAudio());
        packet = null; // reset the packet
        return;
    }

    byte[] newPacket = new byte[packet.length + 3840];
    // copy old packet onto new temp array
    System.arraycopy(packet, 0, newPacket, 0, packet.length);
    // copy toAdd packet onto new temp array
    System.arraycopy(toAdd, 0, newPacket, 3840, toAdd.length);
    // overwrite the old packet with the newly resized packet
    packet = newPacket;
}

這只會將新數據包添加到一個大字節[]上,直到該字節[]包含3秒的音頻數據(576,000個樣本,或192000*3)。3秒的音頻數據足以(只是猜測)檢測用戶是否說了機器人的激活熱詞,如”嘿,電腦。”下面是我如何轉換聲音數據:

    private byte[] convertAudio() {
        // STEP 1 - DROP EVERY OTHER PACKET TO REMOVE STEREO FROM THE AUDIO
        byte[] mono = new byte[96000];
        for(int i = 0, j = 0; i % 2 == 0 && i < packet.length; i++, j++) {
            mono[j] = packet[i];
        }

        // STEP 2 - DROP EVERY 3RD PACKET TO CONVERT TO 16K HZ Audio
        byte[] resampled = new byte[32000];
        for(int i = 0, j = 0; i % 3 == 0 && i < mono.length; i++, j++) {
            resampled[j] = mono[i];
        }

        // STEP 3 - CONVERT TO LITTLE ENDIAN
        ByteBuffer buffer = ByteBuffer.allocate(resampled.length);
        buffer.order(ByteOrder.BIG_ENDIAN);
        for(byte b : resampled) {
            buffer.put(b);
        }
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        buffer.rewind();
        for(int i = 0; i < resampled.length; i++) {
            resampled[i] = buffer.get(i);
        }

        return resampled;
    }

最后,嘗試識別講話:

private void getResult(byte[] toProcess) {
    InputStream stream = new ByteArrayInputStream(toProcess);
    recognizer.startRecognition(stream);
    SpeechResult result;
    while ((result = recognizer.getResult()) != null) {
        System.out.format("Hypothesis: %s
", result.getHypothesis());
    }
    recognizer.stopRecognition();
}

我遇到的問題是CMUSphinx沒有崩潰或提供任何錯誤消息,它只是每隔3秒提出一個空的假設。我不確定為什么,但我猜我沒有正確轉換聲音。有什么主意嗎?如有任何幫助,將不勝感激。

推薦答案

因此,實際上有一個更好的內部解決方案來轉換來自byte[]的音頻。

以下是我發現非常有效的方法:

        // Specify the output format you want
        AudioFormat target = new AudioFormat(16000f, 16, 1, true, false);
        // Get the audio stream ready, and pass in the raw byte[]
        AudioInputStream is = AudioSystem.getAudioInputStream(target, new AudioInputStream(new ByteArrayInputStream(raw), AudioReceiveHandler.OUTPUT_FORMAT, raw.length));
        // Write a temporary file to the computer somewhere, this method will return a InputStream that can be used for recognition
        try {
            AudioSystem.write(is, AudioFileFormat.Type.WAVE, new File("C:\filename.wav"));
        } catch(Exception e) {}

這篇關于將原始PCM數據轉換為RIFF波的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標簽:PCM RIFF 原始 數據 轉換為
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定