1

基本上,我使用 AudioRecord 将声音文件录制到 sdcard 目录。它记录 5 秒,然后使用 AudioTrack 播放。

好吧,对我来说,录制的文件不存在。也许它没有成功记录。我在录音中做错了什么?播放部分呢?

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

1 回答 1

2

如果您的要求是在录制时它应该播放(意味着循环播放音频),在您的 while 循环线程中,您正在存储录制的数据(audioData 缓冲区),您可以在其中将其复制到播放器对象,在 while 循环中( player.write(audioData, 0, numShortsRead);)。你说你的 UI 线程卡住了,可能是因为你给音频记录线程更多的优先级。

检查下面我用于上述环回要求的代码:

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

还有一件事,如果您的要求是记录几秒钟然后播放,在播放时您的记录应该重新开始,您可以使用延迟处理程序线程超时,在该线程中您可以停止记录复制缓冲区,然后开始录制。

于 2013-02-28T08:08:27.630 回答