选择播放设备,采集音频保存到文件并播放

基础知识

1.PCM(脉冲编码调制),将物理音频信号转化为数字,信号转变成一个数字阵列,每个数字代表特定时刻声音的能量水平(振幅)。(只讨论线性 PCM,即阵列中的每个数字都是原始振幅的线性表示)
2.采样率,数字声音每秒采样多少次(表示振幅的数字)。一般来说,采样率越高,音质越好。目前消费类音频系统中使用的数字通常为22050、44100和48000Hz(每秒采样次数)。
3.分辨率/采样大小/每采样位数,用于表示振幅的每个数字的大小和格式。例如,如果使用 8 位整数,则只能表示256级振幅,因此原始物理波形将被简化为256个离散级(并会降低音频精度/质量)。如果使用16位,质量就会好得多。事实上,您可能大部分时间都会使用16位音频。其他选项包括24位、32 位(安卓系统暂时不支持这些选项)和使用浮点数。
4.声道 ,单声道(1声道)或立体声(2声道),也可以是任何更大的数字(但在 Android 上不支持)。如果想要立体声音频,则需要为每个声道设置一个单独的 PCM 阵列,这样信息量就会加倍。

AudioManager

使用该类,查看正在使用的音频设备

 mAudioManager = (AudioManager)getSystemService(Service.AUDIO_SERVICE);

AudioTrack

在流模式下,应用程序使用 write() 方法,向音轨(audio sink)写入连续的数据流。这些方法是阻塞式的,当数据从 Java 层传输到本地层并排队等待播放时,才返回。流模式在播放音频数据块时最有用,例如以下场景:
1.由于要播放的声音持续时间太长,内存无法容纳
2.由于音频数据的特性(高采样率、每采样位数......),内存无法容纳过大的音频数据块
3.在播放先前排队的音频时接收或生成的音频数据

创建后,AudioTrack对象会初始化其关联的音频缓冲区。该缓冲区的大小是在构建过程中指定的,它决定了AudioTrack在数据用完之前可以播放多长时间。对于流模式,数据将以小于或等于总缓冲区大小的块的形式,写入音频接收器(audio sink,就是播放器?)

针对立即停止播放的情况,需要将线程中断。对于AudioTrack对象,先使用pause(),再使用flush()。详见,stop()函数说明

AudioRecord

AudioRecord类管理Java应用程序的音频资源,从平台的音频输入硬件,记录音频。这是通过从AudioRecord对象中读取数据来实现的,应用程序可以使用以下三种read()方法,使用哪种方法基于对AudioRecord用户最方便的音频数据存储格式。

对于使用 public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) 方法时,编码方式需要使用8bit格式

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

其中,参数audioSource与实体设备无法关联,不能通过枚举的方法获得录音源,只能选择默认的几种(详见官网)。这种架构的设计,就是典型的隔离,用AudioRecord接口,不需要了解底层硬件

添加蓝牙功能

1.遍历输入设备,将内置麦克分设置为音频采集设备。

2.若有蓝牙接入,再将蓝牙设置为音频采集设备,针对蓝牙设备,mAudioManager.getAvailableCommunicationDevices()要和mAudioManager.setCommunicationDevice(speakerDevice)绑定使用(why?)

mAudioManager = (AudioManager)getSystemService(Service.AUDIO_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
      for(AudioDeviceInfo device:mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
      {
           Log.d("device!", String.valueOf(device.getType()));
           if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_MIC)
           {
                speakerDevice = device;
                break;
           }

      }
      for (AudioDeviceInfo btDevice : mAudioManager.getAvailableCommunicationDevices())  
//在可以进行通话的设备中寻找
     {
          Log.d("device!", String.valueOf(btDevice.getType()));
          if (btDevice.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO)
          {
                speakerDevice = btDevice;
                mAudioManager.setCommunicationDevice(speakerDevice);
                break;
          }
     }
}

question:手机耳机接入,是不是也默认直接选择手机耳机作为音频输入设备

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值