需要帮助在For循环之外访问AudioInputStream

时间:2015-05-31 00:54:48

标签: java scope

如何声明/访问attachedFiles AudioInputStream数据以将其写入for循环外的磁盘?当我将磁盘写入命令放在for循环中时,它几乎按预期工作,但外部不识别attachedFiles。

import java.io.File;
import java.io.IOException;
import java.io.SequenceInputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;


public class WaveFileMerge
{
   public void waveFileMerge(String[] fileList) throws UnsupportedAudioFileException, IOException {

       for(int x=0;x<fileList.length;x++){

           if(fileList[x] != null){

                AudioInputStream currentClip = AudioSystem.getAudioInputStream(new File(fileList[x]));
                AudioInputStream blankAudio = AudioSystem.getAudioInputStream(new File("C:\\test\\dummy.wav"));



                AudioInputStream appendedFiles = new AudioInputStream( 
                                 new SequenceInputStream(currentClip, blankAudio),
                                 blankAudio.getFormat(), 
                                 blankAudio.getFrameLength() + currentClip.getFrameLength());


              }


      }

      AudioSystem.write(appendedFiles,AudioFileFormat.Type.WAVE,
                                new File("C:\\test\\final.wav"));
}
}

1 个答案:

答案 0 :(得分:1)

您的问题是variable scope之一。在一对大括号({})之间声明的变量无法在这些大括号之外访问。因此,如果要在appendedFiles循环之外访问for,则必须在该循环之外声明它。但是,您不必在声明变量后立即使用该变量。初始化后可以将其设置为null,然后再使用它。对于您的代码,这看起来像:

AudioInputStream appendedFiles = null; //declare the variable outside the loop.
for(int x=0;x<fileList.length;x++){

       if(fileList[x] != null){

            AudioInputStream currentClip = AudioSystem.getAudioInputStream(new File(fileList[x]));
            AudioInputStream blankAudio = AudioSystem.getAudioInputStream(new File("C:\\test\\dummy.wav"));



            appendedFiles = new AudioInputStream( 
                             new SequenceInputStream(currentClip, blankAudio),
                             blankAudio.getFormat(), 
                             blankAudio.getFrameLength() + currentClip.getFrameLength()); //set it to something within the loop


          }


  }

  AudioSystem.write(appendedFiles,AudioFileFormat.Type.WAVE,
                            new File("C:\\test\\final.wav")); //you can still reference it outside the loop.

警告

但是,您应该小心,在循环外部编写文件确实可以实现您的意图。如果你在循环之外写,那么你只会写出appendedFiles的最后一个值来自循环。这可能不是你想要的(否则,为什么循环并创建其他对象?)。

你可能想要什么

如果您希望使用一个循环来创建输入流,然后将它们全部写入,则需要另一个循环。在这种情况下,您的代码将创建一个数组或AudioInputStream的列表,它将在第一个循环中附加,然后在单独的循环中将它们写出。我的猜测是这就是你想要的。这看起来像下面的代码:

    SequenceInputStream streamForAppendedFiles = null;
    AudioInputStream blankAudio = null;
    long totalFrameLength = 0l;

    //loop through the files, adding the input streams for them together as we go. 
    for(int x=0;x<fileList.length;x++){
       if(fileList[x] != null){

            AudioInputStream currentClip = AudioSystem.getAudioInputStream(new File(fileList[x]));
            blankAudio = AudioSystem.getAudioInputStream(new File("C:\\file\\with\\no\\audio.wav"));

            totalFrameLength+= currentClip.getFrameLength() + blankAudio.getFrameLength();

            SequenceInputStream currentClipPlusBlank = new SequenceInputStream(currentClip,blankAudio);

            if(streamForAppendedFiles==null){
                //first time through the loop, the stream with everything is just the current clip
                streamForAppendedFiles = currentClipPlusBlank;
            } else {
                //for subsequent loops, add the current stream to the running total. Think of this like +=.
                streamForAppendedFiles = new SequenceInputStream(streamForAppendedFiles,currentClipPlusBlank);
            }

          }
    }

    //convert the stream with everything to an audio stream
    AudioInputStream audioStreamAppendedFiles = new AudioInputStream( 
            streamForAppendedFiles,
            blankAudio.getFormat(), 
            totalFrameLength);

    //write the file.
    File finalFile = new File("C:\\test\\final.wav");
    AudioSystem.write(audioStreamAppendedFiles,AudioFileFormat.Type.WAVE,finalFile);