欧洲杯直播_欧洲国家杯_欧洲杯比分_24直播吧

Android 音视频开发(一) -- 使用AudioRecord 录制PCM(录音);AudioTrack播放音频

  前言,音视频这块,确实比较难入门,本着学习的态度,我这边也跟着 Android 音视频开发入门指南 打怪升级,留下个脚印,大家共勉。

  音视频 系列文章

  Android 音视频开发(一) – 使用AudioRecord 录制PCM(录音);AudioTrack播放音频

  Android 音视频开发(二) – Camera1 实现预览、拍照功能

  Android 音视频开发(三) – Camera2 实现预览、拍照功能

  Android 音视频开发(四) – CameraX 实现预览、拍照功能

  Android 音视频开发(五) – 使用 MediaExtractor 分离音视频,并使用 MediaMuxer合成新视频(音视频同步)

  音视频工程

  今天要完成的功能如下;

使用AudioRecord 进行录音生成 wav 格式的音频,并进行播放使用 AudioTrack 播放 pcm 格式音频 (Stream 和 static 模式)

  由于声音不好上动图,只能来一张静图了,具体代码看工程:音视频学习Demo

  在这里插入图片描述

  首先,我们先要了解声音是怎么被保存的起来的。在我们的世界中,声音是连续不断的,是一种模拟信号,那如何把声音保存起来呢?计算机能识别的就是二进制,所以,对声音这种模拟信号,采用数字化,即转换成数字信号,就能保存了。

  从上面知道,声音是一种波,有自己的振幅和频率,如果要保存声音,就要保存各个时间点上的振幅;而数字信号并不能保存所有时间点的振幅,事实上,并不需要保存连续的信号,就可以还原到人耳可接受的声音;根据奈奎斯特定律:为了不失真地恢复模拟信号,采样频率应该不小于模拟信号频谱中最高频率的2倍。

  音频数据的承载方式,最常用的就是 脉冲编码调制,即 PCM

  根据上面的分析,PCM 的采集步骤可以以下步骤:

  模拟信号 -> 采样 -> 量化 -> 编码 -> 数字信号

  上面提到,采样率要大于原声波频率的2倍,人耳能听到的最高频率为 20khz,所以,为了满足人耳的听觉要求,采样率至少为40khz,通常就是为 44.1khz,更高则是 48 khz。一般我们都采用 44.1khz 即可达到无损音质。

  上面说到模拟信号是连续的样本值,而数字信号一般是不连续的,所以模拟信号量化,只能取一个近似的整数值,为了记录这些振幅值,采样器会采用一个固定的位数来记录这些振幅值,通常有 8 位,16位,32位。

位数最小值最大值8025516-324683276732-21474836482147483648

  位数越大,记录的值越准确,还原度越高。

  最后就是编码了,数字信号由0,1组成的,因此,需要将振幅转换成一系列 0和1进行存储,也就是编码,最后得到的数据就是数字信号:一串0和1组成的数据:

  在这里插入图片描述

  指支持能 不同发声(注意是不同声音) 的音响的个数。

单声道:一个声道双声道:2个声道立体声:2个声道立体声(4声道):4个声道

  上面了解音频的基础知识后,我们接着使用 AudioRecord 来录制原始数据,即 PCM 数据;

  当手机的硬件录音之后,AudioRecord 可以从该硬件提取音频资源;读取的方法可以使用 read() 方法来实现。那么我们现在开始,首先,先申请好权限:

  在 button 的down 事件开始录音,在up 的时候停止录音:

  接着初始化 AudioRecord:

  上面通过 AudioRecord.getMinBufferSize() 来获取最小一帧的buffer 大小,这样我们能保证每一帧都能被录制。它的参数如下:

sampleRateInHz :采样率,上面说到,想要无损印制,至少 44100hz ,所以这里也是用 44100hzchannelConfig:声道,这里采用双声道audioFormat:PCM 采样位数,一般现在的手机斗志16bit的,也足够使用了,所以这里也是使用 16 bit

  接着创建 AudioRecord ,参数也不难理解,这里不再赘述大佬们都在玩{精选官网网址: www.vip333.Co }值得信任的品牌平台!。

  怎么去录制呢?说白了,就是通过 AudioRecord 的read方法,它会把数据读写到 byte[] 数组中,然后返回写入的大小,根据 byte 就可以保存到文件中了,代码如下:

  首先,使用 record.startRecording() 开始,此时它会开始监听硬件音频数据,然后通过 read() 方法读取数据,接着把它保存到文件中。

  然后我们发现,已经保存了音频的原始数据 PCM 文件:

  在这里插入图片描述

  上面只保存了 pcm 文件,但这是原始的 pcm 文件,它是不支持播放的。我们需要将它转换成 wav 这种可以被识别解码的音频格式。

  想要把 pcm 格式转换成 wav,只需要在pcm的文件起始位置加上至少44个字节的WAV头信息即可,

  这个文件头记录着音频流的编码参数。数据块的记录方式是little-endian字节顺序,来一张官方图:

  在这里插入图片描述

  关于 wav 的说明,这里不重点介绍,它的头部生成方法如下:

  在上面的方法中,通过先后才能下载了 pcm 文件;为了方便,我们可以在 下载 pcm 之前,把头部信息先存储起来,接着再填充 pcm 文件,完成代码如下:

  可以看到,我们先新建了一个 test.wav 的文件,先写入 头部信息,由于无法确定pcm的大小,先传入0,接着再把 pcm 写入到 wav 文件中,当录制结束,再把 pcm 的文件大小写入header头部即可。

  在这里插入图片描述

  当点击 test.wav 就可以播放啦,就可以听到你自己的骚声音了。

  这里使用Android自带的播放器就可以了,当然你也可以使用 MediaPlayer,使用Android 自带的如下:

  注意,如果是7.0 及以上,不能使用显性的 Uri了,所以需要使用FileProvider,它其实也是一个 contentprovider,记得在 AndroidMinefest 也写上:大佬们都在玩{精选官网网址: www.vip333.Co }值得信任的品牌平台!

  在这里插入图片描述

  新建一个 xml,添加一个 file_paths.xml 文件:

  上面我们通过转换 PCM 为 WAV ,使其变成能够被多媒体解码识别的文件,但如果我想播放 pcm 文件呢?大佬们都在玩{精选官网网址: www.vip333.Co }值得信任的品牌平台!

  这里可以通过 AudioTrack 来实现该功能,它为 Android 管理和播放音频的管理类,允许 PCM 音频通过write() 方法将数据流推送到 AudioTrack 来实现音频的播放。(当然也不局限 pcm,其他音频格式也支持的)

  AudioTrack 有两种模式:流模式和静态模式

  流模式:在流模式,当使用 write() 方法时,会向 AudioTrack 写入连续的数据流,数据会从 Java 层传输到底层,并排队阻塞等待播放;在播放音频块数据时,流模式比较好用:

音频数据过大过长,无法存入内存时由于音频数据的特性(高采样率,每采样位…),太大而无法装入内存。接收或生成时,先前排队的音频正在播放。

  静态模式:静态模式,它需要一次性把数据写到buffer中,适合小音频,小延迟的音频播放,常用在UI和游戏中比较实用。

  这里,我们粉笔用两种模式去读取刚才的录音。

  上面说到,静态模式下,需要一次性把音频数据写到buffer中,所以这个 buffer 肯定不能太大,不过我们刚才的录音不算大,所以可以拿到上面录制的 pcm 来实践。

  注释都比较清晰了,先把 test.pcm 文件的数据取出来,放到 ByteArrayOutputStream,然后再通过 audioTrack.write() 写入到 audiotrack中,点击播放即可。

  流模式,数据会从 Java 层传输到底层,并排队阻塞等待播放,所以,这里我们开启一个线程,读取数据后等待播放,初始化与 static 模式没啥区别:

  就是初始化 AudioTrack 时,由于是流模式,所以大小只需要设置一帧的最小buffer 即可,然后调用 play() 方法去等待数据,当AudioTrack 的 write() 有数据到来时,就会播放音频:

  这样,关于 AudioRecord 和 AudioTrack 就学习完啦,后面继续打怪升级。

  参考:

  https://developer.android.google.cn/reference/kotlin/android/media/AudioTrack?hl=en

  https://www.jianshu.com/p/1749d2d43ecb

Android 音视频开发(一) -- 使用AudioRecord 录制PCM(录音);AudioTrack播放音频

Android 音视频开发(一) -- 使用AudioRecord 录制PCM(录音);AudioTrack播放音频

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
请登录后评论...
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~