2013-10-15 149 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