美文网首页
Android pcm转码wav

Android pcm转码wav

作者: CQ_TYL | 来源:发表于2019-12-05 10:59 被阅读0次

百度语音识别后生成的语音文件为pcm文件,pcm可以使用ffmpeg进行转码,我自己尝试过使用其他工具转码均失败,其他播放软件直接播放pcm也均是失败!
ffmpeg下载地址:(window64)https://ffmpeg.zeranoe.com/builds/win64/static/

image.png
转换命令:
//将pcm文件复制到bin目录,然后命令行直接输入下面命令即可转换后使用常用的音频播放软件播放
ffmpeg -y  -f s16le -ac 1 -ar 16000 -i "outfile(2).pcm" -ac 1 -ar 16000 outfile(2).wav

下面直接上android pcm转wav代码:

package com.shiyoukeji.book.activity.SpeechRecongnition;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by tyl
 * 2019/12/5/005
 * Describe:音频pcm转码wav
 */

public class convertPcmToWav {
    /**
     * PCM文件转WAV文件
     * @param inPcmFilePath 输入PCM文件路径
     * @param outWavFilePath 输出WAV文件路径
     * @param sampleRate 采样率,例如15000
     * @param channels 声道数 单声道:1或双声道:2
     * @param bitNum 采样位数,8或16
     */
    public static void convertPcmToWav(String inPcmFilePath, String outWavFilePath, int sampleRate,
                                       int channels, int bitNum) {
        FileInputStream in = null;
        FileOutputStream out = null;
        byte[] data = new byte[1024];

        try {
            //采样字节byte率
            long byteRate = sampleRate * channels * bitNum / 8;

            in = new FileInputStream(inPcmFilePath);
            out = new FileOutputStream(outWavFilePath);

            //PCM文件大小
            long totalAudioLen = in.getChannel().size();

            //总大小,由于不包括RIFF和WAV,所以是44 - 8 = 36,在加上PCM文件大小
            long totalDataLen = totalAudioLen + 36;

            writeWaveFileHeader(out, totalAudioLen, totalDataLen, sampleRate, channels, byteRate);

            int length = 0;
            while ((length = in.read(data)) > 0) {
                out.write(data, 0, length);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 输出WAV文件
     * @param out WAV输出文件流
     * @param totalAudioLen 整个音频PCM数据大小
     * @param totalDataLen 整个数据大小
     * @param sampleRate 采样率
     * @param channels 声道数
     * @param byteRate 采样字节byte率
     * @throws IOException
     */
    private static void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,
                                            long totalDataLen, int sampleRate, int channels, long byteRate) throws IOException {
        byte[] header = new byte[44];
        header[0] = 'R'; // RIFF
        header[1] = 'I';
        header[2] = 'F';
        header[3] = 'F';
        header[4] = (byte) (totalDataLen & 0xff);//数据大小
        header[5] = (byte) ((totalDataLen >> 8) & 0xff);
        header[6] = (byte) ((totalDataLen >> 16) & 0xff);
        header[7] = (byte) ((totalDataLen >> 24) & 0xff);
        header[8] = 'W';//WAVE
        header[9] = 'A';
        header[10] = 'V';
        header[11] = 'E';
        //FMT Chunk
        header[12] = 'f'; // 'fmt '
        header[13] = 'm';
        header[14] = 't';
        header[15] = ' ';//过渡字节
        //数据大小
        header[16] = 16; // 4 bytes: size of 'fmt ' chunk
        header[17] = 0;
        header[18] = 0;
        header[19] = 0;
        //编码方式 10H为PCM编码格式
        header[20] = 1; // format = 1
        header[21] = 0;
        //通道数
        header[22] = (byte) channels;
        header[23] = 0;
        //采样率,每个通道的播放速度
        header[24] = (byte) (sampleRate & 0xff);
        header[25] = (byte) ((sampleRate >> 8) & 0xff);
        header[26] = (byte) ((sampleRate >> 16) & 0xff);
        header[27] = (byte) ((sampleRate >> 24) & 0xff);
        //音频数据传送速率,采样率*通道数*采样深度/8
        header[28] = (byte) (byteRate & 0xff);
        header[29] = (byte) ((byteRate >> 8) & 0xff);
        header[30] = (byte) ((byteRate >> 16) & 0xff);
        header[31] = (byte) ((byteRate >> 24) & 0xff);
        // 确定系统一次要处理多少个这样字节的数据,确定缓冲区,通道数*采样位数
        header[32] = (byte) (channels * 16 / 8);
        header[33] = 0;
        //每个样本的数据位数
        header[34] = 16;
        header[35] = 0;
        //Data chunk
        header[36] = 'd';//data
        header[37] = 'a';
        header[38] = 't';
        header[39] = 'a';
        header[40] = (byte) (totalAudioLen & 0xff);
        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
        out.write(header, 0, 44);
    }
}

调用代码:

                      String recordFilePath="/storage/emulated/0/dacheASR/outfile.pcm";
                         String wavFilePath="/storage/emulated/0/dacheASR/outfile.wav";
                        convertPcmToWav.convertPcmToWav(recordFilePath,wavFilePath,16000,1,16);

相关文章

  • Android pcm转码wav

    百度语音识别后生成的语音文件为pcm文件,pcm可以使用ffmpeg进行转码,我自己尝试过使用其他工具转码均失败,...

  • Andorid pcm转码wav

    参考文章:https://blog.csdn.net/hesong1120/article/details/790...

  • 基于ffmpeg转码成wav总结

    最近在做音频相关的开发,有需求把pcm,opus格式的音频转码成wav格式的。首选是通过ffmpeg命令转码,...

  • 录音程序

    1.获取pcm文件: 2.pcm转wav 3.录音转为pcm再转为wav:

  • [kalid] pcm2wav

    20180827 qzd pcm文件转wav文件时,主要是在pcm文件加入wav的头。wav的文件头包含wav标示...

  • PCM文件转wav文件

    PCM是采样的原始音频数据, 是无压缩的原始数据, 给pcm添加wav的文件头, 就是wav文件, 所以wav也是...

  • 音视频入门之音频采集、编码、播放

    今天我们学习音频的采集、编码、生成文件、转码等操作,我们生成三种格式的文件格式,pcm、wav、aac 三种格式,...

  • android音频编辑之音频合成

    前言 音频编辑系列: android音频编辑之音频转换PCM与WAV android音频编辑之音频裁剪 andro...

  • iOS将PCM数据文件转换为WAV文件

    最近学习写wav文件,搞了很久,踩了不少坑。将PCM数据文件转换为WAV文件其实就是在PCM数据前加上WAV的头。...

  • WAV和PCM的关系和区别

    什么是WAV和PCM? WAV:wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Inter...

网友评论

      本文标题:Android pcm转码wav

      本文链接:https://www.haomeiwen.com/subject/myhdgctx.html