首页 > 其他分享 >【android 】Android PCM文件转WAV文件

【android 】Android PCM文件转WAV文件

时间:2023-02-16 10:14:36浏览次数:48  
标签:文件 totalAudioLen param sampleRate header Android 0xff byte android

之前对android音频方面根本不了解,找了很多博客都没找到合适自己的,顺便看了很多代码,发现pcm基本上所有的音频格式都能转,
我项目里面用到的就是wav的,所以这里贴一下pcm转wav的代码,
之前看到一位大佬说wav的头文件很简单,反正我是没看懂,菜得哭.....
 
 
顺便祝涵宝宝新年快乐~么么哒
 
 
/**
 * 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);
}

 

标签:文件,totalAudioLen,param,sampleRate,header,Android,0xff,byte,android
From: https://www.cnblogs.com/opensmarty/p/17125705.html

相关文章

  • Blazor 拖放上传文件转换格式并推送到浏览器下载
    前言昨天有个小伙伴发了一个老外java编写的小工具给我,功能是转换西班牙邮局快递Coreeosexpress的单据格式成Amazon格式,他的需求是改一下程序为匹配转换另一个快递公司M......
  • Windows命令findstr文本文件中查找字符串(findstr-对应于Linux中的grep命令)
    一、实例如查找coco.names文件中的car所在的行:findstr/N/A:02carcoco.names或将全部内容(用点.代替)转出到文本文件:findstr/N/A:02.coco.names>coco.txt二、知识点......
  • 封装axios 到文件 request.js
    importaxiosfrom"axios";import{Message}from"element-ui";//拿token有2种方式:方式1:读取vuex的state;方式2:读取cookieimportstorefrom"@/store";impor......
  • ansible 配置文件管理
    目录ansible配置文件管理配置文件的优先级配置文件分段说明配置参数说明关于ssh连接一些常见的错误说明文章转自ansible配置文件管理配置文件的优先级ansible的配置文......
  • ansible inventory文件
    目录ansibleinventory文件定义主机和组直接写进hosts文件简单实用ping模块检测连通性实用普通用户控制hosts文件管理主机分组简单配置指定主机范围定义主机组嵌套选择主机......
  • Android  JetPack~ LiveData (一)   介绍与使用
    一般情况下LiveData都是搭配这ViewModel使用,这里先介绍一下LiveData,再结合ViewModel使用Android数据绑定技术一,企业级开发Android数据绑定技术二,企业级开发Androi......
  • spring管理配置文件实现注入
    创建配置文件  写入以下内容:  创建配置文件的bean:  <beanid="configProperties"class="org.springframework.beans.factory.config.PropertiesFact......
  • Jdbc_Druid_Utils_V2连接池-需要在src文件夹下创建配置文件druid.properties
    packagecom.atguigu.api.utils;importcom.alibaba.druid.pool.DruidDataSourceFactory;importjavax.sql.DataSource;importjava.io.IOException;importjava.io.InputS......
  • JavaWeb文件上传(感谢狂神)
    1、准备工作采用Apache的开源工具common-fileupload这个文件上传组件。common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。(这两个jar包需要下载引入,Tomc......
  • 文件的操作
    文件的属性是用一个结构体来封装的: 文件属性的操作函数: 文件的类型:  函数操作: 文件权限:  access函数(检查指定文件是否具有某种操作)头文件:#i......