1

我正在使用音频轨道(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 也不能在手机和系统中播放。如果我的代码存储不正确。那么我们应该如何存储它。

4

1 回答 1

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 标头。此处对其进行了描述。读取和写入此类文件的示例代码可以在这里看到,尤其是 writeToFilePath_WriteChunks 和相关方法。

如果您希望以其他格式输出,则必须使用相应的文件格式。

于 2013-10-15T11:47:34.153 回答