2011-07-19 121 views
0

從下面的代碼我可以創建test.pcm文件,但我無法在移動設備或pc中播放它。使用AudioRecord錄製音頻android

我也厭倦了test.mp3,test.wav和test.raw。我得到了敬酒,該播放器不支持這種類型的文件。

沒有任何人有想法,我該如何播放文件,這是我使用AudioRecord錄製的?

使用下面的代碼,我從麥克風獲得短陣列並將其寫入到SD卡中。

這裏是代碼:

package com.anroid.AudioProcess; 

import java.io.File; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Environment; 

import java.io.BufferedOutputStream; 
import java.io.DataOutputStream; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 


public class AudioProcess extends Activity { 
    /** Called when the activity is first created. */ 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     // Record 20 seconds of audio. 
     Recorder recorderInstance = new Recorder(); 
     Thread th = new Thread(recorderInstance); 
     recorderInstance.setFileName(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.pcm")); 
     th.start(); 
     recorderInstance.setRecording(true); 
     synchronized (this) { 
     try { 
      this.wait(20000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     } 
     recorderInstance.setRecording(false); 
     try { 
      th.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 


    } 
} 





class Recorder implements Runnable { 
    private int frequency; 
    private int channelConfiguration; 
    private volatile boolean isPaused; 
    private File fileName; 
    private volatile boolean isRecording; 
    private final Object mutex = new Object(); 

    // Changing the sample resolution changes sample type. byte vs. short. 
    private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 

    /** 
    * 
    */ 
    public Recorder() { 
     super(); 
     this.setFrequency(11025); 
     this.setChannelConfiguration(AudioFormat.CHANNEL_CONFIGURATION_MONO); 
     this.setPaused(false); 
    } 

    public void run() { 
     // Wait until we're recording... 
     synchronized (mutex) { 
      while (!this.isRecording) { 
       try { 
        mutex.wait(); 
       } catch (InterruptedException e) { 
        throw new IllegalStateException("Wait() interrupted!", e); 
       } 
      } 
     } 

     // Open output stream... 
     if (this.fileName == null) { 
      throw new IllegalStateException("fileName is null"); 
     } 
     BufferedOutputStream bufferedStreamInstance = null; 
     if (fileName.exists()) { 
      fileName.delete(); 
     } 
     try { 
      fileName.createNewFile(); 
     } catch (IOException e) { 
      throw new IllegalStateException("Cannot create file: " + fileName.toString()); 
     } 
     try { 
      bufferedStreamInstance = new BufferedOutputStream(
        new FileOutputStream(this.fileName)); 
     } catch (FileNotFoundException e) { 
      throw new IllegalStateException("Cannot Open File", e); 
     } 
     DataOutputStream dataOutputStreamInstance = 
      new DataOutputStream(bufferedStreamInstance); 

     // We're important... 
     android.os.Process 
       .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 

     // Allocate Recorder and Start Recording... 
     int bufferRead = 0; 
     int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(), 
       this.getChannelConfiguration(), this.getAudioEncoding()); 
     AudioRecord recordInstance = new AudioRecord(
       MediaRecorder.AudioSource.MIC, this.getFrequency(), this 
         .getChannelConfiguration(), this.getAudioEncoding(), 
       bufferSize); 
     short[] tempBuffer = new short[bufferSize]; 
     recordInstance.startRecording(); 
     while (this.isRecording) { 
      // Are we paused? 
      synchronized (mutex) { 
       if (this.isPaused) { 
        try { 
         mutex.wait(250); 
        } catch (InterruptedException e) { 
         throw new IllegalStateException("Wait() interrupted!", 
           e); 
        } 
        continue; 
       } 
      } 

      bufferRead = recordInstance.read(tempBuffer, 0, bufferSize); 
      if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { 
       throw new IllegalStateException(
         "read() returned AudioRecord.ERROR_INVALID_OPERATION"); 
      } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) { 
       throw new IllegalStateException(
         "read() returned AudioRecord.ERROR_BAD_VALUE"); 
      } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { 
       throw new IllegalStateException(
         "read() returned AudioRecord.ERROR_INVALID_OPERATION"); 
      } 
      try { 
       for (int idxBuffer = 0; idxBuffer < bufferRead; ++idxBuffer) { 
        dataOutputStreamInstance.writeShort(tempBuffer[idxBuffer]); 
       } 
      } catch (IOException e) { 
       throw new IllegalStateException(
        "dataOutputStreamInstance.writeShort(curVal)"); 
      } 

     } 

     // Close resources... 
     recordInstance.stop(); 
     try { 
      bufferedStreamInstance.close(); 
     } catch (IOException e) { 
      throw new IllegalStateException("Cannot close buffered writer."); 
     } 
    } 

    public void setFileName(File fileName) { 
     this.fileName = fileName; 
    } 

    public File getFileName() { 
     return fileName; 
    } 

    /** 
    * @param isRecording 
    *   the isRecording to set 
    */ 
    public void setRecording(boolean isRecording) { 
     synchronized (mutex) { 
      this.isRecording = isRecording; 
      if (this.isRecording) { 
       mutex.notify(); 
      } 
     } 
    } 

    /** 
    * @return the isRecording 
    */ 
    public boolean isRecording() { 
     synchronized (mutex) { 
      return isRecording; 
     } 
    } 

    /** 
    * @param frequency 
    *   the frequency to set 
    */ 
    public void setFrequency(int frequency) { 
     this.frequency = frequency; 
    } 

    /** 
    * @return the frequency 
    */ 
    public int getFrequency() { 
     return frequency; 
    } 

    /** 
    * @param channelConfiguration 
    *   the channelConfiguration to set 
    */ 
    public void setChannelConfiguration(int channelConfiguration) { 
     this.channelConfiguration = channelConfiguration; 
    } 

    /** 
    * @return the channelConfiguration 
    */ 
    public int getChannelConfiguration() { 
     return channelConfiguration; 
    } 

    /** 
    * @return the audioEncoding 
    */ 
    public int getAudioEncoding() { 
     return audioEncoding; 
    } 

    /** 
    * @param isPaused 
    *   the isPaused to set 
    */ 
    public void setPaused(boolean isPaused) { 
     synchronized (mutex) { 
      this.isPaused = isPaused; 
     } 
    } 

    /** 
    * @return the isPaused 
    */ 
    public boolean isPaused() { 
     synchronized (mutex) { 
      return isPaused; 
     } 
    } 

} 

回答

0

認爲你應該使用另一個類,然後AudioRecord。 AudioRecord是現在對你的soundport的原始數字印象。 你在那裏「借」了一個代碼,只是一系列數字。

嘗試使用AudioManager來代替,認爲這更適合您的風格。

1

MediaRecorder是你需要在這裏。如果您不打算擺弄原始音頻數據,請使用MediaRecorder對象進行錄製。將輸出格式設置爲THREE_GPP,它應該適合你。

1

更改文件擴展名不會更改文件格式,例如,放置.mp3不會自動創建MP3文件。 AudioRecord生成原始PCM數據。

您必須告訴媒體播放器播放原始文件,以及需要什麼類型的數據(採樣率,編碼等),就像您進行錄製時一樣,因爲該信息不是由文件給出的本身。

您可以在這裏閱讀Audacity中的說明:http://delog.wordpress.com/2011/03/25/playing-raw-pcm-audio-using-audacity/