是否可以从蓝牙耳机录制语音,同时在Android扬声器上播放?
是否可以从蓝牙耳机录制语音,同时在Android扬声器上播放?我用这个代码完成了从手机设备录制音频。我正在做第二步-在android扬声器中播放这个声音。请帮我解决这个问题。多谢各位是否可以从蓝牙耳机录制语音,同时在Android扬声器上播放?,android,bluetooth,Android,Bluetooth,是否可以从蓝牙耳机录制语音,同时在Android扬声器上播放?我用这个代码完成了从手机设备录制音频。我正在做第二步-在android扬声器中播放这个声音。请帮我解决这个问题。多谢各位 _audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); _audioManager.startBluetoothSco(); _recorder = new MediaRecorder(); _recorder.setA
_audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
_audioManager.startBluetoothSco();
_recorder = new MediaRecorder();
_recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
_recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
_recorder.setOutputFile(file.toString());
_recorder.prepare();
_recorder.start();
录音
public class MainActivity extends Activity {
public static final int SAMPLE_RATE = 16000;
private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;
private final String startRecordingLabel = "Start recording";
private final String stopRecordingLabel = "Stop recording";
private boolean mIsRecording = false;
private ProgressBar mProgressBar;
float iGain = 1.0f;
CheckBox gain;
Button showPref;
OnBluetoothRecording bluetoothRecording;
protected int bitsPerSamples = 16;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
initRecorder();
Button bluetooth = (Button)findViewById(R.id.blue);
showPref = (Button)findViewById(R.id.showPreferece);
gain = (CheckBox) findViewById(R.id.checkBox1);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
showPref.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),BluetoothPreferenceActivity.class));
}
});
final Button button = (Button) findViewById(R.id.start);
button.setText(startRecordingLabel);
bluetooth.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent("");
}
});
gain.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (gain.isChecked()) {
iGain = 5.0f;
} else {
iGain = 2.0f;
}
}
});
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
BluetoothRecordingManager.checkAndRecord(getApplicationContext(), new OnBluetoothRecording() {
@Override
public void onStartRecording(boolean state, boolean bluetoothFlag) {
Log.d("CallBack","starting Recording");
if (!mIsRecording) {
button.setText(stopRecordingLabel);
mIsRecording = true;
mRecorder.startRecording();
mRecording = getFile("raw");
startBufferedWrite(mRecording);
} else {
button.setText(startRecordingLabel);
mIsRecording = false;
mRecorder.stop();
File waveFile = getFile("wav");
try {
rawToWave(mRecording, waveFile);
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
}
Toast.makeText(MainActivity.this,
"Recorded to " + waveFile.getName(),
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelRecording() {
}
}, true);
}
});
}
@Override
public void onDestroy() {
mRecorder.release();
super.onDestroy();
}
private void initRecorder() {
int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
mBuffer = new short[bufferSize];
mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
}
private void startBufferedWrite(final File file) {
new Thread(new Runnable() {
@Override
public void run() {
DataOutputStream output = null;
try {
output = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(file)));
while (mIsRecording) {
double sum = 0;
int readSize = mRecorder.read(mBuffer, 0,
mBuffer.length);
final int bytesPerSample = bitsPerSamples / 8;
final int emptySpace = 64 - bitsPerSamples;
int byteIndex = 0;
int byteIndex2 = 0;
int temp = 0;
int mLeftTemp = 0;
int mRightTemp = 0;
int a = 0;
int x = 0;
for (int frameIndex = 0; frameIndex < readSize; frameIndex++) {
for (int c = 0; c < 1; c++) {
if (iGain != 1) {
long accumulator = 0;
for (int b = 0; b < bytesPerSample; b++) {
accumulator += ((long) (mBuffer[byteIndex++] & 0xFF)) << (b * 8 + emptySpace);
}
double sample = ((double) accumulator / (double) Long.MAX_VALUE);
sample *= iGain;
int intValue = (int) ((double) sample * (double) Integer.MAX_VALUE);
for (int i = 0; i < bytesPerSample; i++) {
mBuffer[i + byteIndex2] = (byte) (intValue >>> ((i + 2) * 8) & 0xff);
}
byteIndex2 += bytesPerSample;
}
}// end for(channel)
// mBuffer[frameIndex] *=iGain;
if (mBuffer[frameIndex] > 32765) {
mBuffer[frameIndex] = 32767;
} else if (mBuffer[frameIndex] < -32767) {
mBuffer[frameIndex] = -32767;
}
output.writeShort(mBuffer[frameIndex]);
sum += mBuffer[frameIndex] * mBuffer[frameIndex];
}
if (readSize > 0) {
final double amplitude = sum / readSize;
mProgressBar.setProgress((int) Math.sqrt(amplitude));
}
}
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
} finally {
mProgressBar.setProgress(0);
if (output != null) {
try {
output.flush();
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
} finally {
try {
output.close();
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
}
}
}
}).start();
}
private void rawToWave(final File rawFile, final File waveFile)
throws IOException {
byte[] rawData = new byte[(int) rawFile.length()];
DataInputStream input = null;
try {
input = new DataInputStream(new FileInputStream(rawFile));
input.read(rawData);
} finally {
if (input != null) {
input.close();
}
}
DataOutputStream output = null;
try {
output = new DataOutputStream(new FileOutputStream(waveFile));
// WAVE header
// see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
writeString(output, "RIFF"); // chunk id
writeInt(output, 36 + rawData.length); // chunk size
writeString(output, "WAVE"); // format
writeString(output, "fmt "); // subchunk 1 id
writeInt(output, 16); // subchunk 1 size
writeShort(output, (short) 1); // audio format (1 = PCM)
writeShort(output, (short) 1); // number of channels
writeInt(output, SAMPLE_RATE); // sample rate
writeInt(output, SAMPLE_RATE * 2); // byte rate
writeShort(output, (short) 2); // block align
writeShort(output, (short) 16); // bits per sample
writeString(output, "data"); // subchunk 2 id
writeInt(output, rawData.length); // subchunk 2 size
// Audio data (conversion big endian -> little endian)
short[] shorts = new short[rawData.length / 2];
ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN)
.asShortBuffer().get(shorts);
ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
for (short s : shorts) {
// Apply Gain
/*
* s *= iGain; if(s>32767) { s=32767; } else if(s<-32768) {
* s=-32768; }
*/
bytes.putShort(s);
}
output.write(bytes.array());
} finally {
if (output != null) {
output.close();
}
}
}
private File getFile(final String suffix) {
Time time = new Time();
time.setToNow();
return new File(Environment.getExternalStorageDirectory(),
time.format("%Y%m%d%H%M%S") + "." + suffix);
}
private void writeInt(final DataOutputStream output, final int value)
throws IOException {
output.write(value >> 0);
output.write(value >> 8);
output.write(value >> 16);
output.write(value >> 24);
}
private void writeShort(final DataOutputStream output, final short value)
throws IOException {
output.write(value >> 0);
output.write(value >> 8);
}
private void writeString(final DataOutputStream output, final String value)
throws IOException {
for (int i = 0; i < value.length(); i++) {
output.write(value.charAt(i));
}
}
}
公共类MainActivity扩展活动{
公共静态最终整数抽样率=16000;
私人录音机;
私有文件记录;
私人卖空者;
私有最终字符串startRecordingLabel=“开始录制”;
私有最终字符串stopRecordingLabel=“停止录制”;
私有布尔错误记录=假;
私人ProgressBar mProgressBar;
浮动iGain=1.0f;
复选框增益;
按钮showPref;
蓝牙录音;
受保护的整数位样本=16;
@凌驾
创建时的公共void(最终捆绑包savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
initRecorder();
按钮蓝牙=(按钮)findViewById(R.id.blue);
showPref=(按钮)findViewById(R.id.showPreferece);
增益=(复选框)findViewById(R.id.checkBox1);
mProgressBar=(ProgressBar)findViewById(R.id.ProgressBar);
showPref.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
startActivity(新意图(getApplicationContext(),BluetoothPreferenceActivity.class));
}
});
最终按钮按钮=(按钮)findViewById(R.id.start);
按钮.setText(startRecordingLabel);
bluetooth.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//TODO自动生成的方法存根
意向i=新意向(“”);
}
});
gain.setOnCheckedChangeListener(新的OnCheckedChangeListener(){
@凌驾
检查更改后的公共无效(复合按钮视图,
布尔值(已检查){
if(gain.isChecked()){
iGain=5.0f;
}否则{
iGain=2.0f;
}
}
});
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(最终视图v){
BluetoothRecordingManager.checkAndRecord(getApplicationContext(),new-OnBluetoothRecording()){
@凌驾
公共void onStartRecording(布尔状态,布尔bluetoothFlag){
Log.d(“回调”,“开始录制”);
如果(!错误记录){
按钮.setText(停止录制标签);
错误记录=正确;
mRecorder.startRecording();
mRecording=getFile(“原始”);
开始缓冲写入(mRecording);
}否则{
按钮.setText(startRecordingLabel);
错误记录=错误;
mRecorder.stop();
File waveFile=getFile(“wav”);
试一试{
rawToWave(mRecording,waveFile);
}捕获(IOE异常){
Toast.makeText(MainActivity.this,e.getMessage(),
吐司。长度(短)。show();
}
Toast.makeText(MainActivity.this,
“记录到”+waveFile.getName(),
吐司。长度(短)。show();
}
}
@凌驾
CancelRecording()上的公共void{
}
},对);
}
});
}
@凌驾
公共空间{
mRecorder.release();
super.ondestory();
}
私有void initRecorder(){
int bufferSize=AudioRecord.getMinBufferSize(采样率,
AudioFormat.CHANNEL(单声道,AudioFormat.ENCODING(PCM)(16位);
mBuffer=新短[缓冲区大小];
mRecorder=新的音频记录(MediaRecorder.AudioSource.MIC、采样率、,
单声道中的AudioFormat.CHANNEL\u,AudioFormat.ENCODING\u PCM\u 16位,
缓冲区大小);
}
私有void startBufferedWrite(最终文件){
新线程(newrunnable()){
@凌驾
公开募捐{
DataOutputStream输出=null;
试一试{
输出=新的DataOutputStream(新的BufferedOutputStream(
新文件输出流(文件));
同时(误录){
双和=0;
int readSize=mRecorder.read(mBuffer,0,
姆布弗长度);
final int bytesPerSample=bitsPerSamples/8;
最终int-emptySpace=64位采样;
int byteIndex=0;
int byteIndex2=0;
内部温度=0;
int mleftemp=0;
int mRightTemp=0;
int a=0;
int x=0;
对于(int-frameIndex=0;frameIndex>((i+2)*8)和0xFF);
}
byteIndex2+=bytesPerSample;
}
}//结束(频道)
//mBuffer[frameIndex]*=iGain;
if(mBuffer[frameIndex]>32765){