Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android record mic to ByteArray without saving audio file

Tags:

android

Sorry for my bad english :(

I start my project for android application, this app record microphone, if I click to start record button the app get microphone and write it on a file and when I click to stop , a file saved into SD card.

project code :

The output file

OUTPUT_FILE = Environment.getExternalStorageState() + "/myaudio.3gp";

Start recording

public void startRecord() throws IOException{
    if (recorder != null)
    {
        recorder.release();
    }
    File outFile = new File(OUTPUT_FILE);
    if (outFile.exists())
    {
        outFile.delete();
    }

    recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setOutputFormat(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setOutputFile(OUTPUT_FILE);
    recorder.prepare();
    recorder.start();
}

Stop recording

public void stopRec(){
    recorder.stop();
}

PlaySound recorded file

public void playRecFile() throws IOException{
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setDataSource(OUTPUT_FILE);
    mediaPlayer.prepare();
    mediaPlayer.start();

}

I want to get recorded voice and put it into a variable ByteArray and play it whitout saving the audio file to SD card

I have a project like what I want but it is written in actionscript 3

import flash.media.*;
import flash.events.*;
import flash.utils.ByteArray;

var ch:SoundChannel
var mic:Microphone = Microphone.getMicrophone();

mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
mic.addEventListener(ActivityEvent.ACTIVITY,onAct);

function onAct(evt:ActivityEvent):void
{
    trace(evt.activating,mic.activityLevel);
    if (!evt.activating)
    {
        if (soundBytes.length)
        {
            timerHandler();
        }
    }
}

var soundBytes:ByteArray = new ByteArray();
var soundO:ByteArray = new ByteArray();

function micSampleDataHandler(event:SampleDataEvent):void
{
    trace(event.data.length,event.data.bytesAvailable, soundBytes.length);
    while (event.data.bytesAvailable)
    {
        var sample:Number = event.data.readFloat();
        soundBytes.writeFloat(sample);
    }
}

function timerHandler():void
{
    mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
    soundBytes.position = 0;
    soundO.writeBytes(soundBytes);
    soundO.position = 0;
    soundBytes.position = 0;
    soundBytes.length=0;

    var sound:Sound= new Sound();
    sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler);
    ch=sound.play();
    ch.addEventListener(Event.SOUND_COMPLETE,onSC)
    trace("OUTPUT",soundO.bytesAvailable);

}
function onSC(evt:Event):void
{
    trace("SOUND_COMPLETE");
}
function playbackSampleHandler(event:SampleDataEvent):void
{
    trace("SAMPLE_DATA: ",soundO.bytesAvailable)
    for (var i:int = 0; i < 8192; i++)
    {
        if (soundO.bytesAvailable < 4)
        {
         break;
        }
        var sample:Number = soundO.readFloat();
        event.data.writeFloat(sample);
        event.data.writeFloat(sample);      
    }
    if (soundO.bytesAvailable < 4 && soundO.position!==0)
    {
        mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
        soundO.position=0
        soundO.length = 0;

        trace("END
    }
}
like image 512
Jeff Bic Avatar asked Dec 20 '12 14:12

Jeff Bic


3 Answers

Check Out this answer! It works exactly with MediaRecorder not AudioRecord

Try to use the following solution to record audio to byte array using MediaRecorder:

    // Byte array for audio record
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    ParcelFileDescriptor[] descriptors = ParcelFileDescriptor.createPipe();
    ParcelFileDescriptor parcelRead = new ParcelFileDescriptor(descriptors[0]);
    ParcelFileDescriptor parcelWrite = new ParcelFileDescriptor(descriptors[1]);

    InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(parcelRead);

    MediaRecorder recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setOutputFile(parcelWrite.getFileDescriptor());
    recorder.prepare();

    recorder.start();


    int read;
    byte[] data = new byte[16384];

    while ((read = inputStream.read(data, 0, data.length)) != -1) {
        byteArrayOutputStream.write(data, 0, read);
    }

    byteArrayOutputStream.flush();

I wrap this code in AsyncTask for start execution.

Also, don't forgot to run the following code to stop recording:

    recorder.stop();
    recorder.reset();
    recorder.release();

To convert byteArrayOutputStream to byte[] use byteArrayOutputStream.toByteArray()

like image 85
Mikhail Sharin Avatar answered Nov 19 '22 14:11

Mikhail Sharin


Use the following class to get the Recorded Mic data As the Byte Array. You will get the data as buffer.. try to use that.. hope this will helps you ..

class AudioRecordThread implements Runnable {
        @Override
        public void run() {
            int bufferLength = 0;
            int bufferSize;
            short[] audioData;
            int bufferReadResult;

            try {
                bufferSize = AudioRecord.getMinBufferSize(sampleAudioBitRate, 
                        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);

                if (bufferSize <= 2048) {
                    bufferLength = 2048;
                } else if (bufferSize <= 4096) {
                    bufferLength = 4096;
                }

                /* set audio recorder parameters, and start recording */
                audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleAudioBitRate, 
                        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferLength);
                audioData = new short[bufferLength];
                audioRecord.startRecording();
                Log.d(LOG_TAG, "audioRecord.startRecording()");

                isAudioRecording = true;

                /* ffmpeg_audio encoding loop */
                while (isAudioRecording) {
                    bufferReadResult = audioRecord.read(audioData, 0, audioData.length);

                    if (bufferReadResult == 1024 && isRecorderStart) {
                        Buffer realAudioData1024 = ShortBuffer.wrap(audioData,0,1024);

                    *********************************** 
                        recorder.record(realAudioData1024);
                        ***********************************

                    } else if (bufferReadResult == 2048 && isRecorderStart) {
                        Buffer realAudioData2048_1=ShortBuffer.wrap(audioData, 0, 1024);
                        Buffer realAudioData2048_2=ShortBuffer.wrap(audioData, 1024, 1024);
                        for (int i = 0; i < 2; i++) {
                            if (i == 0) {
        ***********************************                     
        recorder.record(realAudioData2048_1);
        ***********************************                      

                            } else if (i == 1) {
***********************************
recorder.record(realAudioData2048_2);
***********************************


                            }
                        }
                    }
                }

                /* encoding finish, release recorder */
                if (audioRecord != null) {
                    try {
                        audioRecord.stop();
                        audioRecord.release();

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    audioRecord = null;
                }

                if (recorder != null && isRecorderStart) {
                    try {
                        recorder.stop();
                        recorder.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    recorder = null;
                }
            } catch (Exception e) {
                Log.e(LOG_TAG, "get audio data failed:"+e.getMessage()+e.getCause()+e.toString());
            }

        }
    }
like image 32
itsrajesh4uguys Avatar answered Nov 19 '22 15:11

itsrajesh4uguys


I want to get recorded voice and put it into a variable ByteArray and play it whitout saving the audio file to SD card

Use the AudioRecord class to grab audio from the mic into an array and then feed it into an AudioTrack.

like image 3
Michael Avatar answered Nov 19 '22 15:11

Michael