John
John

Reputation: 3090

Is it possible to record the voice from Bluetooth headset and play on Android speaker simultaneously?

Is it possible to record the voice from Bluetooth headset and play on Android speaker simultaneously? I finished to record audio from handset device by this code. And I am doing the second step- play this sound in android speaker. Please help me to resolve it. Thank you so much

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

Upvotes: 1

Views: 2764

Answers (1)

Shivaraj Patil
Shivaraj Patil

Reputation: 8364

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


}

Upvotes: 0

Related Questions