一、 利用headset profile进行语音采集
在android audio系统中,已经对AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET作了规划,主要是针对headset profile实现语音输入,所以我们需要实现针对该device输入的sco HAL。即要求实现headset profile的mic输入。
1. 修改audio_policy.conf,添加遥控器mic设备以及对应的HAL;HAL命名为audio.sco.vendor.so#bluetoothmic for headset
sco{ // HAL的名字
inputs {
mvs {
sampling_rates 16000
channel_masks AUDIO_CHANNEL_IN_MONO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET
}
}
}
2. 音频策略的修改,由于android 原生音频策略已经规划了AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,所以不用修改音频策略。
二、headsetprofile建立音频通路的过程
1. headset profile建立连接的过程
2. 建立语音通路的过程
建立语音通路的前提是headset device已经建立连接,并进入connected状态。AudioManager里建立sco连接的api:
/**
*Start bluetooth SCO audio connection.
*<p>Requires Permission:
* {@linkandroid.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
*<p>This method can be used by applications wanting to send and receivedaudio
*to/from a bluetooth SCO headset while the phone is not in call.
*<p>As the SCO connection establishment can take several seconds,
*applications should not rely on the connection to be available when the method
*returns but instead register to receive the intent {@link#ACTION_SCO_AUDIO_STATE_UPDATED}
*and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}.
*<p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, theapplication can check the SCO
*audio state before calling startBluetoothSco() by reading the intent returnedby the receiver
*registration. If the state is already CONNECTED, no state change will bereceived via the
*intent after calling startBluetoothSco(). It is however useful to callstartBluetoothSco()
*so that the connection stays active in case the current initiator stops theconnection.
*<p>Unless the connection is already active as described above, the statewill always
*transition from DISCONNECTED to CONNECTING and then either to CONNECTED if theconnection
*succeeds or back to DISCONNECTED if the connection fails (e.g no headset isconnected).
*<p>When finished with the SCO connection or if the establishment fails,the application must
*call {@link #stopBluetoothSco()} to clear the request and turn down thebluetooth connection.
*<p>Even if a SCO connection is established, the following restrictionsapply on audio
* output streams so that they can be routed to SCO headset:
* <ul>
* <li> the stream typemust be {@link #STREAM_VOICE_CALL} </li>
* <li> the format must bemono </li>
* <li> the sampling mustbe 16kHz or 8kHz </li>
*</ul>
* <p>The following restrictions apply on input streams:
* <ul>
* <li> the format must bemono </li>
* <li> the sampling mustbe 8kHz </li>
* </ul>
*<p>Note that the phone application always has the priority on the usageof the SCO
*connection for telephony. If this method is called while the phone is in call
*it will be ignored. Similarly, if a call is received or sent while anapplication
*is using the SCO connection, the connection will be lost for the applicationand NOT
*returned automatically when the call ends.
*<p>NOTE: up to and including API version
*{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates avirtual
*voice call to the bluetooth headset.
*After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
*connection is established.
*@see #stopBluetoothSco()
*@see #ACTION_SCO_AUDIO_STATE_UPDATED
*/
public void startBluetoothSco(){
IAudioService service = getService();
try {
service.startBluetoothSco(mICallBack,
getContext().getApplicationInfo().targetSdkVersion);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}