目录

1.  AudioTrack

1.1 简单示例如下

1.2 参数解释

1)  usage

2) contentType

3) Encoding

4)SampleRate

5)ChannelMask

6)Mode

2.  AudioRecord

2.1 简单示例如下:

2.2 AudioRecord.getMinBufferSize(...)

2.3 AudioRecord 构造函数

2.4  audioRecord.read(...)

2.5  生命周期管理


在上一章,我们介绍过MediaPlayer/AudioTrack, 以及MediaRecorder和AudioRecord,下面分两个章节分别介绍下AudioTrack以及AudioRecord的使用,以及解释下具体的参数。

下图给出了大概的应用app以及底层模块结构,具体架构参考架构图。

图1  AudioTrack、AudioRecord以及MediaPlayer、MediaRecorder结构

下表描述了AudioTrack、AudioRecord、MediaPlayer以及MediaRecorder差异,不要混淆。MediaPlayer在native层会调用AudioTrack播放解码后的音频PCM;

分类

Audio

Media

Player

AudioTrack:

一般播放PCM原始未压缩的音频,播放格式为PCM

MediaPlayer:

一般指播放压缩编码的音频、视频或者音视频文件,除了文件解包外,还有解码;播放格式音频有wav、mp3、ogg、wma;音视频有mp4、wmv、3gp等

Recorder

AudioRecord:

一般指从外部麦克风录制PCM未压缩的音频

MediaRecorder:

一般指录制麦克风数据以及摄像头视频,录制为音频或音视频格式文件,除了编码外,还需要打包

1.  AudioTrack

图2 AudioTrack

1.1 简单示例如下

// 创建 AudioAttributes(指定 Usage 和 ContentType)

AudioAttributes attributes = new AudioAttributes.Builder()

    .setUsage(AudioAttributes.USAGE_SAFETY)       

    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)

    .build();

// 配置音频格式

AudioFormat format = new AudioFormat.Builder()

    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)  

    .setSampleRate(48000)                         

    .setChannelMask(AudioFormat.CHANNEL_OUT_MONO) 

    .build();

// 计算最小缓冲区大小

int minBufferSize = AudioTrack.getMinBufferSize(

    48000,

    AudioFormat.CHANNEL_OUT_MONO,

    AudioFormat.ENCODING_PCM_16BIT

);

// 创建 AudioTrack

AudioTrack audioTrack = new AudioTrack.Builder()

    .setAudioAttributes(attributes)

    .setAudioFormat(format)

    .setBufferSizeInBytes(minBufferSize * 2)      

    .build();

// 写入 PCM 数据并播放

short[] pcmData = generateAvasSound();

audioTrack.play();

audioTrack.write(pcmData, 0, pcmData.length, AudioTrack.WRITE_BLOCKING);

// 播放完成后释放资源

audioTrack.release(); // 重要!否则会泄漏音频会话

1.2 参数解释

以上有四个部分需要解释:

  • setUsage
  • setContentType
  • setEncoding
  • setSampleRate
  • setChannelMask
  • MODE

下面对各个参数分开解释:

1)  usage

传统的方式通过StreamType来区分音频类型,但最新Android 5.0开始都是通过Usage来区分,但新的架构也兼容老的方式。常用的有以下几种Usage:

Usage 常量

说明

典型场景

USAGE_MEDIA

普通媒体播放

音乐、视频、游戏背景音

USAGE_VOICE_COMMUNICATION

语音通话

VoIP(微信语音、Zoom)、电话

USAGE_GAME

游戏音效

手机/平板游戏音效

USAGE_ASSISTANT

语音助手

小爱同学、Siri 回答

USAGE_NOTIFICATION

通知提示音

消息、邮件、日历提醒

USAGE_NOTIFICATION_RINGTONE

来电铃声

电话呼入铃声

USAGE_NOTIFICATION_EVENT

系统事件提示

键盘按键音、充电提示

USAGE_ALARM

闹钟

闹钟、定时器

USAGE_EMERGENCY

紧急警报

地震预警、极端天气警报(最高优先级)

2) contentType

内容类型,例如:

常量

说明

典型场景

CONTENT_TYPE_SPEECH

语音对话

电话、VoIP、语音消息、语音助手回答

CONTENT_TYPE_MUSIC

音乐/歌曲

音乐播放器、视频背景音乐、游戏 BGM

CONTENT_TYPE_MOVIE

电影/视频

本地视频、流媒体(Netflix、YouTube)

CONTENT_TYPE_SONIFICATION

提示音/合成音效

键盘按键音、通知提示、AVAS、倒车雷达

3) Encoding

Encoding是指PCM 音频数据的存储格式,决定了每个采样点用多少位、什么方式表示。

一般有:ENCODING_PCM_16BIT 、ENCODING_PCM_FLOAT等等。

4)SampleRate

采样率比较常见的概念,就是在声音模拟信号转换为数字信号时,需要采样,以Hz 赫兹为单位。有8k、16k、44.1k、48k等采样率。

5)ChannelMask

  ChannelMask指定音频通道的布局(即声道配置),它决定了音频数据如何映射到物理扬声器(如左/右/中置/环绕等),一般有:

CHANNEL_OUT_MONO  指单声道

CHANNEL_OUT_STEREO 指立体声,也就是左右双声道

6)Mode

MODE_STATIC

静态模式:一次性将所有的音频数据写入,适合短小的音效(如游戏音效)。这种方式可以减少延迟,但数据必须一次性全部准备好。

MODE_STREAM

流模式:需要不断写入音频数据,适合播放较长的音频流(如音乐播放)。这种模式下,应用程序通过write方法不断将数据写入AudioTrack的缓冲区。

2.  AudioRecord

    

     

图3 AudioRecord

2.1 简单示例如下:

      最基本的AudioRecord的关键函数示例:

    //计算最小缓冲区大小

               int bufferSizeInBytes = AudioRecord.getMinBufferSize(
                          SAMPLE_RATE,

                           CHANNEL_CONFIG,

                           AUDIO_FORMAT);
            

               // 创建 AudioRecord 实例
               audioRecord = new AudioRecord(

                MediaRecorder.AudioSource.MIC, // 音频源:麦克风
                          SAMPLE_RATE,                       // 采样率(Hz)
                          CHANNEL_CONFIG,              // 声道配置
                           AUDIO_FORMAT,                  // 音频格式
                          bufferSizeInBytes              // 缓冲区大小(字节)

               );


               // 启动录音线程读取数据,自行添加
               while (isRecording) {
                   int bytesRead = audioRecord.read(buffer, 0, buffer.length);
                   if (bytesRead > 0) {
                          // 类似处理录取到的音频数据函数
                          processAudioData(buffer, bytesRead);
                    }

               }

                //......
               //停止释放

               audioRecord.stop();
               audioRecord.release();


         

2.2 AudioRecord.getMinBufferSize(...)

public static int getMinBufferSize(int sampleRateInHz,

                                 int channelConfig,

                               int audioFormat)

  • 作用:获取满足当前配置所需的最小缓冲区大小(单位:字节)。
  • 参数:
    • sampleRateInHz:采样率(如 8000、16000、44100、48000 Hz)
    • channelConfig:声道配置
      • AudioFormat.CHANNEL_IN_MONO(单声道)
      • AudioFormat.CHANNEL_IN_STEREO(立体声)
    • audioFormat:采样精度
      • AudioFormat.ENCODING_PCM_8BIT(8 位,较少用)
      • AudioFormat.ENCODING_PCM_16BIT(16 位,最常用)
      • AudioFormat.ENCODING_PCM_FLOAT(浮点,API 23+)

返回值若为 ERROR 或 ERROR_BAD_VALUE,说明参数不支持。


2.3 AudioRecord 构造函数

public AudioRecord(int audioSource,

                 int sampleRateInHz,

                  int channelConfig,

                 int audioFormat,

                  int bufferSizeInBytes)

  • audioSource:音频输入源
    • MediaRecorder.AudioSource.MIC:默认麦克风
    • MediaRecorder.AudioSource.VOICE_RECOGNITION:优化语音识别(降噪)
    • MediaRecorder.AudioSource.CAMCORDER:摄像时录音
    • (其他如 VOICE_COMMUNICATION 等)
  • sampleRateInHz:采样率(建议使用设备支持的标准值,如 44100)
  • channelConfig & audioFormat:同上
  • bufferSizeInBytes:内部缓冲区大小(必须 ≥ getMinBufferSize() 返回值)
    • 越大越不容易丢帧,但延迟越高;越小延迟低但可能不稳定。

2.4  audioRecord.read(...)

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

  • 从录音缓冲区读取 PCM 数据到 audioData。
  • 返回实际读取的字节数。
  • 若返回 ERROR_INVALID_OPERATION 或 ERROR_BAD_VALUE,说明状态异常。
  • 在 API 23+ 可使用带 READ_BLOCKING / READ_NON_BLOCKING 标志的重载方法。

2.5  生命周期管理

  • startRecording():开始录音(必须调用后才能 read)
  • stop():停止录音(可重复 start/stop)
  • release():释放底层资源(调用后对象不可再用)
  • getState():检查是否初始化成功(STATE_INITIALIZED)

更多内容,请关注后续更新。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐