java - 声音文件不播放

标签 java audio

我正在为类(class)编写游戏,但在添加声音和图像时遇到问题。我们从安德鲁·戴维森的《 killer 游戏编程》书中获得了可以使用的框架,我觉得我正在完全复制它,但我无法播放声音文件。

这是 SDLLoader 类:

package zombieCity;


/* SDLLoader  stores a collection of SDLInfo objects
   in a HashMap whose keys are their names. 

   The name and filename for a line is obtained from a sounds
   information file which is loaded when SDLLoader is created.
   The information file is assumed to be in Sounds/.

   SDLLoader allows a specified clip to be played, stopped, 
   resumed, looped. A SoundsWatcher can be attached to a clip.
   All of this functionality is handled in the SDLInfo object; 
   SDLLoader simply redirects the method call to the right SDLInfo.

   It is possible for many lines to play at the same time, since
   each SDLInfo object is responsible for playing its clip.
*/


import java.util.*;
import java.io.*;

import javax.print.DocFlavor.URL;


public class SDLLoader
{
  private final static String SOUND_DIR = "Sounds/";

  private HashMap<String, SDLInfo> sdlMap; 
    /* The key is the clip 'name', the object (value) 
       is a SDLInfo object */


  public SDLLoader(String soundsFnm)
  { sdlMap = new HashMap<String, SDLInfo>();
    loadSoundsFile(soundsFnm);
  }

  public SDLLoader()
  {  sdlMap = new HashMap<String, SDLInfo>();  } 



  private void loadSoundsFile(String soundsFnm)
  /* The file format are lines of:
        <name> <filename>         // a single sound file
     and blank lines and comment lines.
  */
  { 
    String sndsFNm = SOUND_DIR + soundsFnm;
    System.out.println("Reading file: " + sndsFNm);
    try {
        java.net.URL inFile = this.getClass().getResource("/Sounds/SDLInfo.txt");
        System.out.println("url " + inFile);
        InputStreamReader in = new InputStreamReader(inFile.openStream());
      BufferedReader br = new BufferedReader(in);
      StringTokenizer tokens;
      String line, name, fnm;
      while((line = br.readLine()) != null) {
        if (line.length() == 0)  // blank line
          continue;
        if (line.startsWith("//"))   // comment
          continue;

        tokens = new StringTokenizer(line);
        if (tokens.countTokens() != 2)
          System.out.println("Wrong no. of arguments for " + line);
        else {
          name = tokens.nextToken();
          fnm = tokens.nextToken();
          load(name, fnm);
        }
      }
      br.close();
    } 
    catch (IOException e) 
    { System.out.println("Error reading file: " + sndsFNm);
      System.exit(1);
    }
  }  // end of loadSoundsFile()



  // ----------- manipulate a particular clip --------


  public void load(String name, String fnm)
  // create a SDLInfo object for name and store it
  {
    if (sdlMap.containsKey(name))
      System.out.println( "Error: " + name + "already stored");
    else {
      sdlMap.put(name, new SDLInfo(name, fnm) );
      System.out.println("-- " + name + "/" + fnm);
    }
  }  // end of load()


  public void close(String name)
  // close the specified clip
  {  SDLInfo si = (SDLInfo) sdlMap.get(name);
     if (si == null)
       System.out.println( "Error: " + name + "not stored");
     else
      si.close();
  } // end of close()



  public void play(String name, boolean toLoop)
  // play (perhaps loop) the specified clip
  {  SDLInfo si = (SDLInfo) sdlMap.get(name);
     if (si == null)
       System.out.println( "Error: " + name + "not stored");
     else
      si.beginPlayback(toLoop);
  } // end of play()


  public void stop(String name)
  // stop the clip, resetting it to the beginning
  { SDLInfo si = (SDLInfo) sdlMap.get(name);
    if (si == null)
      System.out.println( "Error: " + name + "not stored");
    else
      si.stop();
  } // end of stop()

  // -------------------------------------------------------


  public void setWatcher(String name, SoundsWatcher sw)
  /* Set up a watcher for the clip. It will be notified when
     the clip loops or stops. */
  { SDLInfo si = (SDLInfo) sdlMap.get(name);
    if (si == null)
      System.out.println( "Error: " + name + "not stored");
    else
      si.setWatcher(sw);
  } // end of setWatcher()

}  // end of ClipsLoader class

堆栈跟踪

    fps: 100; period: 10 ms
Reading file: Sounds/SDLInfo.txt
url file:/C:/Documents%20and%20Settings/MyName/Desktop/java%20programs/Zombie%20City/bin/Sounds/SDLInfo.txt
Exception in thread "main" java.lang.NullPointerException
    at com.sun.media.sound.StandardMidiFileReader.getSequence(Unknown Source)
    at javax.sound.midi.MidiSystem.getSequence(Unknown Source)
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at zombieCity.SDLInfo.loadLine(SDLInfo.java:35)
    at zombieCity.SDLInfo.<init>(SDLInfo.java:27)
    at zombieCity.SDLLoader.load(SDLLoader.java:95)
    at zombieCity.SDLLoader.loadSoundsFile(SDLLoader.java:73)
    at zombieCity.SDLLoader.<init>(SDLLoader.java:38)
    at zombieCity.FlyingHero.simpleInitialize(FlyingHero.java:144)
    at zombieCity.Frame.<init>(Frame.java:68)
    at zombieCity.FlyingHero.<init>(FlyingHero.java:80)
    at zombieCity.FlyingHero.main(FlyingHero.java:376)

此类中捕获了错误:

package zombieCity;
/* Load a line, which can be played, stopped, resumed, looped. 

   An object implementing the SoundsWatcher interface 
   can be notified when the line loops or stops.
*/

import java.io.*;
import javax.sound.sampled.*;


public class SDLInfo implements LineListener, Runnable
{
  private final static String SOUND_DIR = "Sounds/";

  private String name, filename;
  private SourceDataLine line = null;
  private boolean isLooping = false;
  private SoundsWatcher watcher = null;
  private Thread soundPlayer;


  public SDLInfo(String nm, String fnm)
  { name = nm;
    filename = SOUND_DIR + fnm;

    loadLine(filename);
  } // end of SDLInfo()


  private void loadLine(String fnm)
  {
    try {
      // link an audio stream to the sound line's file
      AudioInputStream stream = AudioSystem.getAudioInputStream(
                          getClass().getResource(fnm) );

      AudioFormat format = stream.getFormat();

      // convert ULAW/ALAW formats to PCM format
      if ( (format.getEncoding() == AudioFormat.Encoding.ULAW) ||
           (format.getEncoding() == AudioFormat.Encoding.ALAW) ) {
        AudioFormat newFormat = 
           new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                                format.getSampleRate(),
                                format.getSampleSizeInBits()*2,
                                format.getChannels(),
                                format.getFrameSize()*2,
                                format.getFrameRate(), true);  // big endian
        // update stream and format details
        stream = AudioSystem.getAudioInputStream(newFormat, stream);
        System.out.println("Converted Audio format: " + newFormat);
        format = newFormat;
      }

      DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

      // make sure sound system supports data line
      if (!AudioSystem.isLineSupported(info)) {
        System.out.println("Unsupported Line File: " + fnm);
        return;
      }

      // get clip line resource
      line = (SourceDataLine) AudioSystem.getLine(info);

      // listen to line for events
      line.addLineListener(this);

      line.open(format);    // open the sound file as a line
      stream.close(); // we're done with the input stream

    } // end of try block

    catch (UnsupportedAudioFileException audioException) {
      System.out.println("Unsupported audio file: " + fnm);
    }
    catch (LineUnavailableException noLineException) {
      System.out.println("No audio line available for : " + fnm + " " + noLineException);
    }
    catch (IOException ioException) {
      System.out.println("Could not read: " + fnm);
    }
 //   catch (Exception e) {
  //    System.out.println("Problem with " + fnm);
  //  }
  } // end of loadLine()


  public void update(LineEvent lineEvent){}
  // update() not used


  public void close()
  { if (line != null) {
      line.stop();
      line.close();
    }
  }

  public void beginPlayback(boolean toLoop)
  {
      if (line != null){
          isLooping = toLoop;
          if (soundPlayer == null) {
              soundPlayer = new Thread(this);
              soundPlayer.start();
          }
      }
  }

  public void play()
  {
    try{
      if (line != null) {
          int numRead = 0;
          byte[] buffer = new byte[line.getBufferSize()];
          AudioInputStream stream = AudioSystem.getAudioInputStream(getClass().getResource(filename) );
          line.start();
          // read and play chunks of the audio
          int offset;
          while ((numRead = stream.read(buffer,0,buffer.length)) >= 0) {
              offset = 0;
              while (offset < numRead)
                  offset += line.write(buffer, offset, numRead-offset);
          }
          // wait until all data is played, then stop the line
          stream.close();
          line.drain();
          line.stop();
      }
    }
    catch (IOException ioException) {
      System.out.println("Could not read: " + filename);
    }
    catch (UnsupportedAudioFileException audioException) {
        System.out.println("Unsupported audio file: " + filename);
      }

  } //end of play()

  public void run()
  {
     do{ play();}while(isLooping);
  }

  public void stop()
  // stop and reset line to its start
  { if (line != null) {
      isLooping = false;
      line.drain();
      line.stop();
    }
  }

  public void setWatcher(SoundsWatcher sw)
  {  watcher = sw;  }


  // -------------- other access methods -------------------

  public String getName()
  {  return name;  }

}  // end of ClipInfo class

最佳答案

您是否尝试过使用 .wav 文件

如果您需要转换,请转换为

convert here

关于java - 声音文件不播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15314589/

相关文章:

java - 在实时数据流中找到前 k 个频繁词

java.sql 导入不起作用

r - 来自load.wave的不完整的wav文件,由save.wave保存

redirect - 如何在第三个应用程序中将声音从某些应用程序重定向到某些设备?

java - ActionListener 不适用于所有对象

java - 如何将 JScrollPane 添加到 JPanel

javascript - 单击play()时不必要地下载多个音频文件

flash - 如何在 AS3 flash 中暂停/播放嵌入声音

android - 如何从 sd 卡 android 获取所有音频文件

java - 将war文件上传到tomcat时出现IllegalArgumentException