1 音频格式简介

AudioRecord录制的音频文件格式为PCM,MediaPlayer无法播放PCM格式文件,AudioTrack可以播放PCM格式文件。
PCM(Puls Code Modulation)全称脉码调制录音,PCM录音就是将声音的模拟信号表示成0,1标识的数字信号,未经任何编码和压缩处理,所以可以认为PCM是未经压缩的音频原始格式。PCM格式文件中不包含头部信息,播放器无法知道采样率,声道数,采样位数,音频数据大小等信息,导致无法播放。

PCM格式缺少头部信息,支持的播放器有限,所以一般需要把PCM格式转换成其他格式文件。

WAV是一种符合 RIFF Resource Interchange File Format规范的微软开发的音频格式,是一种无损格式。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码(类似mp3),只需要在被编码音频的前面添加带有音频流的编码参数的WAV的文件头。WAV格式支持许多压缩算法,支持多种音频位数、采样频率和声道,采用44.1kHz的采样频率,16位量化位数,因此WAV的音质与CD相差无几,但WAV格式对存储空间需求太大不便于交流和传播。

MP3利用MPEG Audio Layer3 压缩方式进行压缩,所以简称为MP3,是一种有损压缩格式。 MPEG Audio Layer 3 压缩技术可以将音乐以1:10 甚至 1:12 的压缩率,能够在音质丢失很小的情况下把文件压缩到更小的程度。由于MP3体积小,音质高互联网上音乐几乎都是这种格式。但Mp3最高比特率320K,高频部分一刀切是他的缺点,对音质要求高的话还是建议wav格式。

ARM格式全称Adaptive Multi-Rate 和 Adaptive Multi-Rate Wideband,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,多用于人声,通话,是一种有损压缩格式。

Ogg全称应该是OGG Vobis(ogg Vorbis) 是一种新的音频压缩格式,类似于MP3等现有的音乐格式。相对于MP3压缩技术它是完全免费、开放和没有专利限制的,是一种有损压缩格式。

AAC(Advanced Audio Coding),中文称为“高级音频编码”,出现于1997年,基于 MPEG-2的音频编码技术,是一种有损压缩技术。

LAC即是Free Lossless Audio Codec的缩写,为无损音频压缩编码,由于不会丢失任何音频信息可以利用算法恢复原始编码,前景广阔。

2 WAV文件头信息

WAV格式全称为WAVE,前面提到只需要在PCM文件的前面添加WAV文件头,就可以生成WAV格式文件,下面说一说WAV文件头格式。
WAV符合 RIFF Resource Interchange File Format规范,RIFF文件结构可以看作是树状结构,其基本构成是称为"块"(Chunk)的单元,WAVE文件是由若干个Chunk组成的。WAV文件本身由三个“块”信息组成:将文件标识为WAV文件的RIFF块,识别采样率等参数的FORMAT块和包含实际数据(样本)的DATA块。

所有的WAV都有一个文件头,这个文件头记录着音频流的编码参数。数据块的记录方式是little-endian字节顺序。

C语言中对应的WAV的文件头结构如下:

Typedef struct
{WAVEFORMAT wf;//波形格式;
WORD wBitsPerSample;//WAVE文件的采样大小;
}PCMWAVEFORMAT;
WAVEFORMAT结构定义如下:
typedef struct
{WORD wFormatag;//编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
WORD nChannls;//声道数,单声道为1,双声道为2;
DWORD nSamplesPerSec;//采样频率;
DWORD nAvgBytesperSec;//每秒的数据量;
WORD nBlockAlign;//块对齐;
}WAVEFORMAT;

C语言里面的字WORD(32位),16进制文件对应2个字节(Byte),而DWORD(64位),对应4个字节。16进制文件的存储规律,对于WORD,先存储低位字节,然后存储高位字节,而DWORD,则先存储低两位的低位,然后是低两位的高位,然后是高两位的低位,然后是高两位的高位。所以看下图时要对照WORD和DWORD格式的存储结构。

WAV文件头信息由44个字节组成,所以只需要在PCM文件头部添加44个字节的WAV文件头,就可以生成WAV格式文件。

  • ChunkID:大小为4个字节数据,内容为“RIFF”,表示资源交换文件标识
  • ChunkSize:大小为4个字节数据,内容为一个整数,表示从下个地址开始到文件尾的总字节数
  • Format:大小为4个字节数据,内容为“WAVE”,表示WAV文件标识
  • Subchunkl ID:大小为4个字节数据,内容为“fmt ”,表示波形格式标识(fmt ),最后一位空格。
  • Subchunkl Size:大小为4个字节数据,内容为一个整数,表示PCMWAVEFORMAT的长度。
  • AudioFormat:大小为2个字节数据,内容为一个短整数,表示格式种类(值为1时,表示数据为线性PCM编码)
  • NumChannels:大小为2个字节数据,内容为一个短整数,表示通道数,单声道为1,双声道为2
  • SampleRate:大小为4个字节数据,内容为一个整数,表示采样率,比如44100
  • ByteRate:大小为4个字节数据,内容为一个整数,表示波形数据传输速率(每秒平均字节数),大小为 采样率 * 通道数 * 采样位数
  • BlockAlign:大小为2字节数据,内容为一个短整数,表示DATA数据块长度,大小为 通道数 * 采样位数
  • BitsPerSample:大小为2个字节数据,内容为一个短整数,表示采样位数,即PCM位宽,通常为8位或16bit
  • Subchunk2ID:大小为4个字节数据,内容为“data”,表示数据标记符
  • Subchunk2 Size:大小为4个字节数据,内容为一个整数,表示接下来声音数据的总大小,需要减去头部的44个字节。
  • data:就是其他编码文件内容

文件实例:

  • ChunkID:“52 49 46 46 ”对应ASCII中的RIFF,固定格式。
  • ChunkSize:“A4 29 01 00”:注意为DWORD格式,表示WAV文件的大小,包含了前面8个字节,所以真正的大小等于文件总字节减去8。a4 a9 01 00 对应的正序16进制为“000129a4”大小为76196,所以文件大小为76188.
  • Format:“57 41 56 45 ”:表示ASCII编码的WAVE,固定写法。
  • Subchunkl ID:”66 6D 74 20”表示ASCII编码的fmt,固定写法。
  • Subchunkl Size:“10 00 00 00 ”DWORD格式,对应16。
  • AudioFormat:“01 00”WORD格式,对应定义为编码格式“WAVE_FORMAT_PCM”。
  • NumChannels:“01 00”WORD格式,对应数字1,表示声道数为1,这是个单声道Wav。
  • SampleRate:”80 3e 00 00”,DWORD格式,对应16进制大小为“00003e80”采样率为1600.
  • ByteRate:”00 7d 00 00”,DWORD格式,大小为传输速率为32000,
  • BlockAlign:02 00,WORD格式,对应2
  • BitsPerSample:10 00 ,对应WAVE文件的采样大小,数值为16,采样大小为16Bits
  • Subchunk2ID:“64 61 74 61”表示为ASCII的data,开始数据区。
  • Subchunk2 Size:“80 29 01 00”格式为DWORD,大小为76160减去44 得到76116.
    wav文件 :https://pan.baidu.com/s/10Vzv6I1Wwbzr5VVBMnJfEg

3 PCM转WAV格式

主要采样频率和AudioFormat和声道数,如果pcm转wav过程中,这些信息和录音时的设置不同,会导致生成的wav文件都是杂音,所以抽取成了需要外部传入。

public class PCMCovWavUtil {//录音的采样频率private  int audioRate = 16000;//录音的声道,单声道private  int audioChannel = AudioFormat.CHANNEL_IN_MONO;//量化的深度private  int audioFormat = AudioFormat.ENCODING_PCM_16BIT;//缓存的大小private  int bufferSize = AudioRecord.getMinBufferSize(audioRate,audioChannel,audioFormat) *2;//PCM文件private File pcmFile;//WAV文件private File wavFile;private String basePath = Environment.getExternalStorageDirectory().getPath() + "/audio";//wav文件目录private String outFileName = basePath+"/test.wav";//pcm文件目录private String inFileName = basePath+"/test.pcm";// samHz,shengdao,audioFormat,bufferSizepublic PCMCovWavUtil(int audioRate,int audioChannel,int audioFormat,int bufferSize){this.audioRate = audioRate;this.audioChannel = audioChannel;this.audioFormat = audioFormat;this.bufferSize = bufferSize;File baseFile = new File(basePath);if(!baseFile.exists())baseFile.mkdirs();pcmFile = new File(inFileName);wavFile = new File(outFileName);try{if (!pcmFile.exists())pcmFile.createNewFile();if (!wavFile.exists())wavFile.createNewFile();}catch(IOException e){}}//转换函数public void convertWaveFile() {File  twavFile = new File(outFileName);if(twavFile.exists()){twavFile.delete();}FileInputStream in = null;FileOutputStream out = null;long totalAudioLen = 0;long totalDataLen = totalAudioLen + 36;long longSampleRate = audioRate;int channels = 1;long byteRate = 16 * audioRate * channels / 8;if (audioFormat == AudioFormat.ENCODING_PCM_16BIT){byteRate = 16 * audioRate * channels / 8;}else if (audioFormat == AudioFormat.ENCODING_PCM_8BIT){byteRate = 8 * audioRate * channels / 8;}byte[] data = new byte[bufferSize];try {in = new FileInputStream(inFileName);out = new FileOutputStream(outFileName);totalAudioLen = in.getChannel().size();//由于不包括前面的8个字节RIFF和WAVtotalDataLen = totalAudioLen + 36;addWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate);while (in.read(data) != -1) {out.write(data);}in.close();out.close();System.out.println("==========转换完毕================");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}//添加Wav头部信息private void addWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate,int channels, long byteRate) throws IOException {byte[] header = new byte[44];// RIFF 头表示header[0] = 'R';header[1] = 'I';header[2] = 'F';header[3] = 'F';//数据大小,数据大小,真正大小是添加了8bitheader[4] = (byte) (totalDataLen & 0xff);header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);//wave格式header[8] = 'W';//WAVEheader[9] = 'A';header[10] = 'V';header[11] = 'E';//fmt Chunkheader[12] = 'f'; // 'fmt 'header[13] = 'm';header[14] = 't';header[15] = ' ';//数据大小header[16] = 16; // 4 bytes: size of 'fmt ' chunkheader[17] = 0;header[18] = 0;header[19] = 0;//编码方式 10H为PCM编码格式header[20] = 1; // format = 1header[21] = 0;//通道数header[22] = (byte) channels;header[23] = 0;//采样率,每个通道的播放速度header[24] = (byte) (longSampleRate & 0xff);header[25] = (byte) ((longSampleRate >> 8) & 0xff);header[26] = (byte) ((longSampleRate >> 16) & 0xff);header[27] = (byte) ((longSampleRate >> 24) & 0xff);//音频数据传送速率,采样率*通道数*采样深度/8header[28] = (byte) (byteRate & 0xff);header[29] = (byte) ((byteRate >> 8) & 0xff);header[30] = (byte) ((byteRate >> 16) & 0xff);header[31] = (byte) ((byteRate >> 24) & 0xff);int tongdaowei = 1;if ( audioChannel ==  AudioFormat.CHANNEL_IN_MONO){tongdaowei =1;}else{tongdaowei =2;}// 确定系统一次要处理多少个这样字节的数据,确定缓冲区,通道数*采样位数if (audioFormat == AudioFormat.ENCODING_PCM_16BIT){header[32] = (byte) (tongdaowei * 16 / 8);}else if (audioFormat == AudioFormat.ENCODING_PCM_8BIT){header[32] = (byte) (tongdaowei * 8 / 8);}// header[32] = (byte) (1 * 16 / 8);header[33] = 0;//每个样本的数据位数if (audioFormat == AudioFormat.ENCODING_PCM_16BIT){header[34] = 16;}else if (audioFormat == AudioFormat.ENCODING_PCM_8BIT){header[34] = 8;}header[35] = 0;//Data chunkheader[36] = 'd';//dataheader[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);}}

文件连接:test.pcm test.wav( AudioFormat.ENCODING_PCM_16BIT) , test1.pcm test1.wav ( AudioFormat.ENCODING_PCM_16BIT) https://pan.baidu.com/s/19j4HoQdLXeWnFF9ZqW2fTw
思考如何转成mp3,acc,arm等格式呢?如何将mp3转成aac,或者aac转成mp3呢?FFmpeg过于庞大,所以接下来会讲MediaCodec

音频格式简介和PCM转换成WAV相关推荐

  1. MP3格式的音乐怎么转换成WAV格式

    MP3格式怎么转换成WAV格式?WAV是最接近无损音乐的一种音频格式,所以深受不少人的喜爱,我们听音乐的时候,大部分歌曲是MP3格式的,这时想把mp3格式转换成WAV格式怎么办呢?接下来,主要跟大家分 ...

  2. kux格式怎么转换成mp3_把MP3格式的音频转换成WAV格式

    有时候工作中我们在处理音频的过程中,需要转换音频的格式,以便于更好的使用.例如,可能会要求把MP3格式的音频转换成其他的音频格式.这时候如何解决是一个问题.今天我就和大家介绍好用的音频转换器,可以快速 ...

  3. 把MP3格式的音频转换成WAV格式

    有时候工作中我们在处理音频的过程中,需要转换音频的格式,以便于更好的使用.例如,可能会要求把MP3格式的音频转换成其他的音频格式.这时候如何解决是一个问题.今天我就和大家介绍好用的音频转换器,可以快速 ...

  4. 如何将计算机声音改成音乐,win7系统把MP3音频转换成WAV格式的图文教程

    新购买的电脑安装 win7系统 ,开机时觉得系统默认的开机声音一点都不好听,想换开关机声音,但是在网上下载好的MP3音频格式不符合要求,要转换成wav格式,这时候该怎么转换呢?大家可通过搜狗播放器进行 ...

  5. QQ语音消息转换成WAV格式

    原创文|Space9 问题背景 QQ已经成为我们生活中的一部分,在QQ上留下了我们许多美好的回忆,一段动听的音乐,或是一句甜蜜的话语,都能触动我们的内心.腾讯使用的语音文件是经过特殊编码(Silk V ...

  6. mp3怎么转换成wav格式

    在平时的生活和工作中,我们都会使用到电脑,使用电脑同时也避免不了使用播放器下载歌曲,当自己的好友给你发了一首好听的音乐在手机上无法播放的时候,该怎么样才能把音频格式进行转换呢?想必大家都习惯了使用MP ...

  7. ape转wav音质会损失吗 怎么将ape格式转换成wav

    ape转wav音质会损失吗 怎么将ape格式转换成wav?据了解,WAV是波形文件,是从CD上翻拷下来的无损格式文件,音质最好,但体积很大:而APE是无损压缩格式文件,是按一定的算法把波形文件压缩到原 ...

  8. android 字节转wav,android开发:把一个byte数组转换成wav音频文件,并且播放

    ============问题描述============ 如题,byte数组转换成wav音频文件,并且播放,下面代码能生成data/data/com.example.playwav/cache/tem ...

  9. 利用matlab将.mat格式文件转换成wav文件

    利用matlab将.mat格式文件转换成wav文件 clc; clear all; clear all;filenames = dir('f16.mat') n = numel(filenames)f ...

最新文章

  1. 罗杰·科恩伯格:基础科学——人类进步的希望
  2. 图解使用CygWin进行Linux操作和编程
  3. js常见问题之为什么点击弹出的i总是最后一个
  4. 进程和线程的概念、区别和联系
  5. selenium自动化测试_您如何使用Selenium来计算自动化测试的投资回报率?
  6. mongodb副本集_设置MongoDB副本集分为4个步骤
  7. c++qq主界面_QQ小程序,一个被严重低估的超级流量池!错过你就亏大了
  8. MVC3 EntityFramework 插入Mysql数据库 乱码问题
  9. 原生社区交友婚恋视频即时通讯双端APP源码 ONE兔2.0版
  10. c语言大华面试题,大华股份的一道笔试题 C/C++
  11. (php毕业设计)基于php校园网络报修管理系统获取
  12. 米勒拉宾算法——素性测试
  13. Pyhton爬小说实例解析笔记——爬虫基础
  14. Ubuntu 下访问摄像头 及将摄像头数据重定向到http协议 远程访问摄像头
  15. 网站并发量的计算方法
  16. 如何开张美国银行卡CitiBank
  17. ctfshow-web入门-node.js
  18. Python matplotlib绘图如何显示中文的问题【有报错没有解决】
  19. 为什么理科男喜欢皈依佛门?
  20. 2007上海户口评分标准

热门文章

  1. 2011年10月买到Incredible S G11山寨,大家警惕!
  2. 探究阿里云物联网开发板1-Haas 100
  3. 小白看了也能搭建物联网项目——物联网开发板——QD-mini板
  4. python面向对象 : 反射和内置方法
  5. html 中写目录列表,制作的HTML目录列表
  6. OpenCV+kinect1.0手语识别(二)手部区域的抠图与跟踪
  7. DNS的工作原理及解析
  8. java实现基于管程法的消费者生产者模式(两个消费者一个生产者)
  9. html中蝴蝶飞飞怎么制作,【幼儿园折纸蝴蝶教案】手工折纸蝴蝶教案_幼儿园手工蝴蝶教案_亲亲宝贝网...
  10. 批量将磁盘上所有文件的路径地址、文件名、扩展名和文件夹名整理到 Excel 表格中