【Android】AudioRecord--录音并将 PCM文件转为WAV

本文详细介绍了如何使用Android的AudioRecord类进行录音,并将得到的PCM数据转换成WAV文件。讨论了AudioRecord的参数设置、PCM编码以及WAV文件格式,同时分享了实现录音及转换的代码实现流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新博客地址http://www.jianshu.com/u/7ae8671ca7f4

前言

Android提供可以用来录音的有AudioRecord和MediaRecord,通过MediaRecord录音,我们可以选择所要录音的格式,然后录完之后,自动生成这种格式的文件,而AudioRecord得到的是PCM编码格式的数据,因此如果我们要对录音的数据做处理,显然我们需要的是通过后者,同时后者还支持对于录音过程中,将模拟信号转化为数字信号的相关参数的设置,其中包括采样率和量化深度,同时也包括通道数目。由于项目的需要所以选择采用AudioRecord,今天写了下,将录音得到的PCM数据转化为WAV,github上应该有这样的工具类可以拿来用,只需要进行一次转化,也没必要搞这么多。

实现功能

通过AudioRecord进行录音,将生成数据写入PCM文件,然后转化为Wav文件

AudioRecord

AudioRecord是Android中用来管理从音频硬件设备获取的音频资源,我们可以对其进行模拟信号向数字信号转化的时候的一些参数的设置,模拟信号向数字信号进行转换的过程为采样,量化,编码。模拟信号是连续的信号,而数字信号是离散的,首先对模拟信号进行采样,采样率即为每一秒采样的次数,量化即为对我们采样得到的数据的一种表示,量化深度即为我们采用多少位的数据进行表示,此处编码过程和量化是同时进行的。每一个AudioRecord对象,通过read()从硬件设备中读取相应的数据,系统会根据采样频率,通道等参数为每个对象分配相应大小的缓存。

构造函数

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

audioSource:音频的来源,常用的为麦克风,其它的几个没有做过多的研究。
samplerateInHz:这个就是采样频率,奈奎斯特定理。我们一般采用44100HZ(在进行模拟/数字信号的转换过程中,当采样频率fs.max大于信号中最高频率fmax的2倍时(fs.max>2fmax),采样之后的数字信号完整地保留了原始信号中的信息,采用的频率正好为人耳所能接听最大频率的两倍)
channelConfig:音频的通道,单声道还是立体声,如果是立体声那么就会又两个声道,所谓声道就是在录制或者播放的过程中,从不同的位置采集或者回放的不同音频信号。即为声源数量和扬声器的数量。
audioFormat:该参数为量化深度,即为每次采样的位数
bufferSizeInBytes:通过 getMinBufferSize()方法可以获得,根据我们采样录制的过程中的参数来确定,每次从硬件读取数据所需要的缓冲区的大小。

开始录音,停止录音

public void startRecording ()
public void stop ()

获取数据

read (byte[] audioData, int offsetInBytes, int sizeInBytes)

通过read函数,我们可以将从硬件获得的音频数据写到我们的一个数组之中,然后建立一个文件输出流,将数据写到外部文件中。如果需要对数据做处理,则在此处进行,如进行一些变声操作等。

此时我们得到数据写到文件中,然后做处理,而不能够对其做一个实时的数据比对或者是其他的处理,然后看到了下面这个方法

录音数据实时处理

public int setNotificationMarkerPosition (int markerInFrames)
public int setPositionNotificationPeriod (int periodInFrames)
public void setRecordPositionUpdateListener (AudioRecord.OnRecordPositionUpdateListener listener, Handler handler)

释放资源

public void release ()

释放掉资源之后,要将原来的对象设为null,涉及到release和null的一带你问题,我们将一个对象设为null,那么这个对象是没有指向的,如果release的话是将对象指向的内存释放掉,但是那段内存还是存在的,对象还是指向哪里的,所以如果在release之后,不置为null,如果在后面误调用了,将会出现问题。

PCM

PCM是在由模拟信号向数字信号转化的一种常用的编码格式,称为脉冲编码调制,PCM将模拟信号按照一定的间距划分为多段,然后通过二进制去量化每一个间距的强度。PCM表示的是音频文件中随着时间的流逝的一段音频的振幅。Android在WAV文件中支持PCM的音频数据。

WAV文件

WAV,MP3等是我们比较常见的音频格式,不同的编码格式对原始音频采用的编码方式也是不同的,通常为了方便传输等问题,会对原始音频进行压缩,同时为了能够使得播放器能够识别该种格式,所以在每种格式的头文件都是特定的,有一定的规则,来让播放器识别出是该种格式,然后按着相应的解码算法去播放后面的音频文件。
WAV是一RIFF为标准的,RIFF是一种资源交换档案标准,是将文件存储在每一个标记块中的档案格式。基本构成单位是trunk,每个trunk是由标记位,数据大小,数据存储,三个部分构成的。
WAV的头文件表示格式分析
基本必要组成有三个trunk,RIFF,FMT,Data

byte[] header = new byte[44];
        //RIFF WAVE Chunk
        // RIFF标记占据四个字节
        header[0] = 'R'; 
        header[1] = 'I';
        header[2] = 'F';
        header[3] = 'F';
        //数据大小表示,由于原始数据为long型,通过四次计算得到长度
        header[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';
        header[9] = 'A';
        header[10
1、Java实现wav音频文件转换为pcm音频文件AudioUtils.java) 2、Java实现播放pcm音频文件PCMPlay.java) WAVwav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。 PCM:PCM(Pulse Code Modulation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。 简单来说:wav是一种无损的音频文件格式,pcm是没有压缩的编码方式。 WAVPCM的关系 WAV可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互转换之中,例如MP3转换成WMA。 简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值