我有一个蓝牙耳机(可以播放立体声音乐)连接到我的安卓手机(Android 4.4.3)。现在我想让我的代码在高采样率(44100)下同时从耳机中播放立体声音乐和录制音频。我按照以下帖子中的解决方案进行了操作。
如何使用蓝牙耳机录制声音
通过与Android设备配对的蓝牙耳机捕获音频
我的基本代码如下。
权限:
我是一名有用的助手,可以进行文本翻译。
这里有一些问题。
情况1:如果我调用以下序列:
音乐通过手机扬声器播放,而不是蓝牙耳机。录音机可以从蓝牙耳机的麦克风录制声音,但采样率非常低(8kHz)。
情况2:如果我不调用turnOnBluetooth(),即执行以下序列
现在音乐通过蓝牙耳机播放,但录音机仅记录手机内置麦克风的音频。
我还尝试通过更改AudioManager的模式来解决问题。
结果与情况1相同。如果我设置
权限:
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.RECORD_AUDIO
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.BROADCAST_STICKY
android.permission.BLUETOOTH
打开蓝牙Sco的代码:
m_amAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
public void turnOnBluetooth() {
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
System.err.println("bluetooth connected");
unregisterReceiver(this);
} else if (AudioManager.SCO_AUDIO_STATE_DISCONNECTED == state) {
System.err.println("bluetooth disconnected");
}
}
};
registerReceiver(broadcastReceiver, new IntentFilter(
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));
try {
if (m_amAudioManager.isBluetoothScoAvailableOffCall()) {
if (m_amAudioManager.isBluetoothScoOn()) {
m_amAudioManager.stopBluetoothSco();
m_amAudioManager.startBluetoothSco();
System.err.println("Bluetooth SCO On!");
} else {
System.err.println("Bluetooth Sco Off!");
m_amAudioManager.startBluetoothSco();
}
} else {
System.err.println("Bluetooth SCO not available");
}
} catch (Exception e) {
System.err.println("sco elsepart startBluetoothSCO " + e);
unregisterReceiver(broadcastReceiver);
}
}
播放立体声音乐的代码:
public void playMusic(){
this.mediaPlayer = new MediaPlayer();
this.mediaPlayer
.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
this.mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().
getAbsolutePath()+ "/"+ folderName + "/stereo.wav");
// change type to STREAM_VOICE_CALL can partly solve the problem
// but reduces the quality of the music, which is critical in my case
this.mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
this.mediaPlayer.prepare();
this.mediaPlayer.start();
}
记录音频的代码:
public void recordAudio() {
AudioRecorder recorder = new AudioRecord(
audioSource, // MediaRecorder.AudioSource.MIC
RECORDER_SAMPLERATE, // 44100
RECORDER_CHANNELS, // AudioFormat.CHANNEL_IN_MONO
RECORDER_AUDIO_ENCODING, // AudioFormat.ENCODING_PCM_16BIT
bufferSize // obtained by AudioRecord.getMinBufferSize()
);
int i = recorder.getState();
if (i == 1)
recorder.startRecording();
// then read bytes from the recorder
}
我是一名有用的助手,可以进行文本翻译。
这里有一些问题。
情况1:如果我调用以下序列:
turnOnBluetooth();
playMusic();
recordAudio();
音乐通过手机扬声器播放,而不是蓝牙耳机。录音机可以从蓝牙耳机的麦克风录制声音,但采样率非常低(8kHz)。
情况2:如果我不调用turnOnBluetooth(),即执行以下序列
playMusic();
recordAudio();
现在音乐通过蓝牙耳机播放,但录音机仅记录手机内置麦克风的音频。
我还尝试通过更改AudioManager的模式来解决问题。
m_amAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
设置音频路由方式为
m_amAudioManager.setSpeakerphoneOn(false);
m_amAudioManager.setBluetoothScoOn(true);
结果与情况1相同。如果我设置
m_amAudioManager.setBluetoothScoOn(false);
它重复了第二种情况。
我已经在这个问题上工作了几天,上述行为让我感到困惑。我在音频设置中错过了什么吗?还是我需要更复杂的控制蓝牙耳机的设置?谢谢您阅读这篇文章,欢迎任何建议。谢谢!