首页 文章

是否可以从蓝牙耳机录制语音并同时在Android扬声器上播放?

提问于
浏览
-1

是否可以从蓝牙耳机录制语音并同时在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 回答

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

相关问题