2014-12-23 73 views
-1

是否可以记录从蓝牙耳机的声音,同时在Android扬声器播放?我完成了通过此代码录制手机设备的音频。我正在做第二步 - 在android扬声器中播放此声音。请帮我解决它。谢谢你这么多是否可以录制蓝牙耳机的声音并同时在Android扬声器上播放?

_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(); 
+1

看起来不同,但你可以尝试从蓝牙头戴式装置记录音频(使用AudioRecord insted的MediaRecorder)和写流从蓝牙话筒到数据一个文件放置标题并将其传递给播放器。这里的挑战是如何管理数据流,我建议先继续将数据写入原始文件,并创建另一个线程将读取原始文件数据(固定大小),并写入到另一个文件中,把头部,并将其传递给玩家,播放会有延迟。 –

+0

你有任何参考码吗?谢谢你 – user8264

+0

,我将发布示例代码使用AudioRecord记录对象,你要驾驶它通过startBluetoothSco(修改和记录来自蓝牙),并尝试正如我所说的上面它可能工作回放逻辑 –

回答

0

记录使用AudioRecord

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)); 
    } 
} 


} 
相关问题