Android AudioRecord to File then use AudioTrack for Playback

倖福魔咒の 提交于 2020-01-30 02:38:52

问题


Basically, I use AudioRecord to record a sound file to sdcard directory. It records for 5 seconds and then playback using AudioTrack.

Well, for me, the recorded file doesn't exist. Maybe it didn't record successfully. Anything I did wrong in recording? what about the playback portion?

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    int minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
            AudioFormat.ENCODING_PCM_16BIT);

  audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
        AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM); 


  recordSound();
 }



private void recordSound(){
    File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+"recordsound");
    //    /mnt/sdcard/recordsound
    // Delete any previous recording.
    if (file.exists())
            file.delete();

    try {
                    file.createNewFile();

                    // Create a DataOuputStream to write the audio data into the saved file.
                    OutputStream os = new FileOutputStream(file);
                    BufferedOutputStream bos = new BufferedOutputStream(os);
                     dos = new DataOutputStream(bos);



                    // Create a new AudioRecord object to record the audio.
                    int bufferSize = audioRecord.getMinBufferSize(FREQUENCY, CHANNEL_CONFIGURATION, AUDIO_ENCODING);
                     audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, CHANNEL_CONFIGURATION, AUDIO_ENCODING, bufferSize);

                    short[] buffer = new short[bufferSize]; 
                    audioRecord.startRecording();

                    new Timer().schedule(stop(), 5000);  //time in miliseconds

                  //  while (audioRecord.RECORDSTATE_RECORDING==1) 
                    {
                            int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
                            for (int i = 0; i < bufferReadResult; i++)
                                    dos.writeShort(buffer[i]);
                    }



                   // dos.close();
            } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }

}

private TimerTask stop()
{
    TimerTask t = new TimerTask() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            audioTrack.stop();
            audioTrack.release();
            try {
                dos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



             try {
                    playfilesound();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



        }
    };
    return t;

}


private void playfilesound() throws IOException
{




    int count = 512 * 1024; // 512 kb
    //Reading the file..
    byte[] byteData = null; 
    File file = null; 
    file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+"recordsound");    //filePath

     if (file.exists())
     {
         int a=0;


     }

    byteData = new byte[(int)count];
    FileInputStream in = null;
    try {
    in = new FileInputStream( file );

    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }


    int bytesread = 0, ret = 0;
    int size = (int) file.length();
    audioTrack.play();


    while (bytesread < size) {    // Write the byte array to the track 
        ret = in.read( byteData,0, count);   //ret =size in bytes

        if (ret != -1) {
            audioTrack.write(byteData,0, ret);
            bytesread += ret; }  //ret
        else break; }   //while

        in.close(); audioTrack.stop(); audioTrack.release();
    }  

回答1:


If your requirement is while it is recording it should play(means looping back audio), In your while loop thread, you are storing the recorded data (audioData bufer), there itself you can copy it to player object with in the while loop (player.write(audioData, 0, numShortsRead);). You said like your UI thread is stuck, it might be because of you are giving more priority to Audio record thread.

Check the below the code which I used for above loop back requirement:

boolean m_isRun=true;
    public void loopback() {
            // Prepare the AudioRecord & AudioTrack
            try {
                buffersize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                        AudioFormat.CHANNEL_CONFIGURATION_MONO,
                        AudioFormat.ENCODING_PCM_16BIT);

            if (buffersize <= BUF_SIZE) {
                buffersize = BUF_SIZE;
            }
            Log.i(LOG_TAG,"Initializing Audio Record and Audio Playing objects");

            m_record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, buffersize * 1);

            m_track = new AudioTrack(AudioManager.STREAM_ALARM,
                    SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, buffersize * 1,
                    AudioTrack.MODE_STREAM);

            m_track.setPlaybackRate(SAMPLE_RATE);
        } catch (Throwable t) {
            Log.e("Error", "Initializing Audio Record and Play objects Failed "+t.getLocalizedMessage());
        }

        m_record.startRecording();
        Log.i(LOG_TAG,"Audio Recording started");
        m_track.play();
        Log.i(LOG_TAG,"Audio Playing started");

        while (m_isRun) {
            m_record.read(buffer, 0, BUF_SIZE);
            m_track.write(buffer, 0, buffer.length);
        }

        Log.i(LOG_TAG, "loopback exit");
    }

    private void do_loopback() {
        m_thread = new Thread(new Runnable() {
            public void run() {
                loopback();
            }
        });

One more thing, If your requirement is record for few seconds and then play, while it is playing your record should start again, you can do that with a delay handler thread with a time out, In that thread you can stop recording copy the buffer, then start recording.



来源:https://stackoverflow.com/questions/15130374/android-audiorecord-to-file-then-use-audiotrack-for-playback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!