java - 将文件另存为音频文件后无法播放

标签 java android

我正在使用 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 也无法在手机和系统中播放。如果我的代码存储不正确。那么我们应该如何存储呢。

最佳答案

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_WriteChunks 和相关的方法。

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

关于java - 将文件另存为音频文件后无法播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19379411/

相关文章:

java - 具有继承的 Jaxb POJO 生成

java - 在Java中生成一个长随机整数

javascript - 使用 react 导航条件渲染屏幕

android - 创建一个新的 sw<xxx>dp 限定符

java - 如何让Camel Websocket组件在客户端连接时发送消息?

java - 如何在 freemarker 中将日期转换为字符串?

java - 为什么Java不允许接口(interface)中的私有(private)成员?

android - 如何在 tileview android 中单击并在其上填充位图时选择特定图 block

Android 开发 - 任何 Google + SDK 或代码示例?

安卓 SDK。无法启动 AVD