2013-10-15 189 views
1

我在使用audiotrack(AudiTrack對象)播放的android中生成音調,但我想將此音調保存爲電話或SD卡中的音頻文件。代碼是將文件保存爲音頻文件後未播放文件

public class MainActivity extends Activity { 
    // int j=2; 
    private final int duration = 3; // seconds 
    private final int sampleRate = 8000; 
    private final int numSamples = duration * sampleRate; 
    private final double sample[] = new double[numSamples]; 
    private final double freqOfTone = 500; // hz 

    private final byte generatedSnd[] = new byte[2 * numSamples]; 

    Handler handler = new Handler(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     // Use a new tread as this can take a while 
     Thread thread = new Thread(new Runnable() { 
      public void run() { 
      genTone(); 
      handler.post(new Runnable() { 

     public void run() { 
     playSound(); 
     } 
     }); 
      } 
     }); 
     thread.start(); 
    } 

    void genTone(){ 
     // fill out the array 
     for (int i = 0; i < numSamples; ++i) { 
     sample[i] = Math.sin(2 * Math.PI * i/(sampleRate/freqOfTone)); 
     //System.out.println("the value is ::"+sample[i]); 

     } 

     // convert to 16 bit pcm sound array 
     // assumes the sample buffer is normalised. 
     int idx = 0; 
     int loop = 0; 
     boolean flip =false; 
     for (double dVal : sample) { 
     short val = (short) (dVal * 32767); 
     generatedSnd[idx++] = (byte) (val & 0x00ff); 

     //System.out.println("the value at address"+generatedSnd[idx-1]); 
     generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
     if(flip) 
     { 
      generatedSnd[idx-1]=(byte)(generatedSnd[idx-1]*2); 
      generatedSnd[idx-2]=(byte)(generatedSnd[idx-2]*2); 
     } 


     System.out.println("the value is:"+generatedSnd[idx-1]); 
     System.out.println("the value is::"+generatedSnd[idx-2]); 

     loop++; 
     if(loop==16){ 
       loop=0; 
       flip=!flip; 
      } 

     } 
    } 


    void playSound(){ 
     AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
     AudioFormat.ENCODING_PCM_16BIT, numSamples, 
     AudioTrack.MODE_STATIC); 
    // audioTrack.write(generatedSnd, 0, generatedSnd.length); 
    audioTrack.write(generatedSnd, 0, numSamples); 
    audioTrack.play(); 
    String sFileName="tonegenerator.mp3"; //String sBody =generatedSnd.toString(); 
    try 
     { 
      File root = new File(Environment.getExternalStorageDirectory(), "Notes"); 
      if (!root.exists()) { 
       root.mkdirs(); 
      } 
      File gpxfile = new File(root, sFileName); 
      // FileWriter writer = new FileWriter(gpxfile); 
      FileOutputStream writer=new FileOutputStream(gpxfile); 
      writer.write(generatedSnd, 0, numSamples); 


      //writer.write(generatedSnd, 0, numSamples); 
      // writer.write(generatedSnd); 
      // writer.append(sBody); 
      writer.flush(); 
      writer.close(); 
      Toast.makeText(this, "Saved", Toast.LENGTH_SHORT).show(); 
     } 
     catch(IOException e) 
     { 
      e.printStackTrace(); 
      // importError = e.getMessage(); 
      // iError(); 
     } 

    } 


    } 

現在該文件也被保存到名爲「Notes」的文件夾中。文件tonegenerator.mp3不能在手機和系統中播放。如果我的代碼不正確的存儲它。那麼我們應該如何存儲它。

+0

僅僅因爲您將文件結尾爲「.mp3」,文件就不會成爲有效的mp3文件。你正在寫的文件看起來像沒有頭壓縮的未壓縮PCM。 – Michael

回答

1
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
    8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
    AudioFormat.ENCODING_PCM_16BIT, numSamples, 
    AudioTrack.MODE_STATIC); 

嘗試將該大小參數從numSamples更改爲generatedSnd數組​​的長度。 並且類似地,

audioTrack.write(generatedSnd, 0, numSamples); 

..設置第三參數該陣列的長度。

此外,你不生成一個MP3,而是一個WAV文件。

更新:基於這樣的事實,你是不是能夠從硬盤版播放文件:

對於wav文件,你還需要編寫WAV頭。它被描述爲here。讀取和寫入這些文件的示例代碼可以參見here,尤其參見writeToFilePath_WriteChunk和相關方法。

如果你想以某種其他格式輸出,那麼你將不得不使用相應的文件格式。

+0

謝謝ankit ..但我擔心的是將生成的音調寫入手機或SD卡作爲音頻文件。 – Alpesh

+0

寫入手機/ SD卡將不會有任何不同的這種文件。你提到它不會在「系統」(我猜是電腦)上播放。這是否與修改建議一致? – radical

+1

是的,電話/ SD卡將不會有任何不同的這種文件。這裏:audioTrack.write(generatedSnd,0,numSamples);把這個寫入audiotrack,當我使用audioTrack.play();但是當我使用這些字節(與我們在audioTrack上寫的相同)將它作爲文件(假設創建文件tonegenerator.wav或.mp3等任何類型的音頻文件)寫入它時。所以文件正在保存,看起來像一個音頻文件,但播放它不會播放,因爲在某些地方使用字節創建音頻文件時出現錯誤。 – Alpesh