简体   繁体   English

* .wav文件应放在目录中的什么位置?

[英]Where do the *.wav files need to live in the directory?

I am working on sound code for a game. 我正在为游戏编写声音代码。 And I was using the following code: 我正在使用以下代码:

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

/**
 * This enum encapsulates all the sound effects of a game, so as to separate the sound playing
 * codes from the game codes.
 * 1. Define all your sound effect names and the associated wave file.
 * 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
 * 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
 *    sound files, so that the play is not paused while loading the file for the first time.
 * 4. You can use the static variable SoundEffect.volume to mute the sound.
 */
public enum SoundEffect {
   EXPLODE("explode.wav"),   // explosion
   GONG("gong.wav"),         // gong
   SHOOT("shoot.wav");       // bullet

   // Nested class for specifying volume
   public static enum Volume {
      MUTE, LOW, MEDIUM, HIGH
   }

   public static Volume volume = Volume.LOW;

   // Each sound effect has its own clip, loaded with its own sound file.
   private Clip clip;

   // Constructor to construct each element of the enum with its own sound file.
   SoundEffect(String soundFileName) {
      try {
         // Use URL (instead of File) to read from disk and JAR.
         URL url = this.getClass().getClassLoader().getResource(soundFileName);
         // Set up an audio input stream piped from the sound file.
         AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
         // Get a clip resource.
         clip = AudioSystem.getClip();
         // Open audio clip and load samples from the audio input stream.
         clip.open(audioInputStream);
      } catch (UnsupportedAudioFileException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (LineUnavailableException e) {
         e.printStackTrace();
      }
   }

   // Play or Re-play the sound effect from the beginning, by rewinding.
   public void play() {
      if (volume != Volume.MUTE) {
         if (clip.isRunning())
            clip.stop();   // Stop the player if it is still running
         clip.setFramePosition(0); // rewind to the beginning
         clip.start();     // Start playing
      }
   }

   // Optional static method to pre-load all the sound files.
   static void init() {
      values(); // calls the constructor for all the elements
   }
}

Now when I replace one of the listed *.wav files from the code with my own or even name one of my own to the file name listed from the above code. 现在,当我用自己的代码替换其中一个列出的* .wav文件时,甚至用我自己的名字替换为上面代码中列出的文件名。 I receive the follow error: 我收到以下错误:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at soundTest.main(soundTest.java:19)
Caused by: 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 SoundEffect.<init>(sfx.java:75)
    at SoundEffect.<clinit>(sfx.java:55)

From following the stack URL url is null going in, which is telling me the *.wav file itself is not being read. 从堆栈URL URL后面开始,null为null,这表明* .wav文件本身未被读取。

I have tried the following lines and yes the *.wav file was present (I am aware that I cannot have three items named the same, I've used one played with it, then commented it out and try again with another one, I just removed the "//" to make is easier to read): 我尝试了以下几行,是的* .wav文件存在(我知道我不能有三个名称相同的项目,我用过一个项目,然后将其注释掉,然后再尝试另一个项目,我只需删除“ //”即可使它更易于阅读):

TEST("file://C:/shoot.wav");
TEST("/soundTest/shoot.wav");
TEST("shoot.wav");  

As well as, placing a copy of the file in the directory with the package (default), in the src folder, and of course in the root (c:). 同样,将文件的副本放置在带有包的目录中(默认),src文件夹中,当然还要放在根目录(c :)中。

How I am envoking the enum is in my main statement where it is all the standard java, main code but with: 我如何调用枚举是在我的主声明中,它是所有标准的Java,主代码,但具有:

 SoundEffect.SHOOT.play();

Where exactly does the *.wav file need to be at int he directory? * .wav文件到底需要在哪里? Or if there is another issue I am missing please point it out. 或者,如果还有其他我想念的问题,请指出。 I am also using the Eclipse IDE "Kepler," on Windows 8.1. 我还在Windows 8.1上使用Eclipse IDE“ Kepler”。 I would like to note the posted code is all I have thus far. 我想指出的是到目前为止所发布的代码。

There is some discussion in the comments that Eclipse might be the problem. 评论中有一些讨论可能是Eclipse的问题。 I seriously doubt Eclipse is the problem. 我严重怀疑Eclipse是问题所在。 I have loaded hundreds of audio files using Eclipse. 我已经使用Eclipse加载了数百个音频文件。 Usually I put the files in a sub-directory "audio" that is one level below the calling code, and use the relative address form: "audio/mySound.wav". 通常,我将文件放在调用代码下一级的子目录“ audio”中,并使用相对地址形式:“ audio / mySound.wav”。

Here is how I load my URL: 这是我加载网址的方法:

URL url = this.getClass().getResource("audio/" & fileName);

I am puzzled as to why there are MIDI references in your stack trace. 我对为什么堆栈跟踪中存在MIDI引用感到困惑。 MIDI has nothing to do with loading .wav files, and really should not be involved at all. MIDI与加载.wav文件无关,实际上完全不应该涉及MIDI。 Are you sure this is the correct stack trace? 您确定这是正确的堆栈跟踪吗? Why are we seeing references to MIDI? 为什么我们会看到对MIDI的引用?

Sometimes an unrecognizable .wav file format will throw unexpected errors. 有时无法识别的.wav文件格式将引发意外错误。 The most common .wav is 16-bit encoding, 44100 bps, stereo, little-endian. 最常见的.wav是16位编码,44100 bps,立体声,小端。 Are your .wav files of this format? 您的.wav文件是否为这种格式?

There are some aspects of your code that I haven't seen implemented in this manner, particularly the use of ENUMS. 我的代码中有些方面我还没有看到以这种方式实现,特别是ENUMS的使用。 I'll take your word all that has been tested and verified. 我相信您所有经过测试和验证的信息。 I tend to just name individual sound objects (using a wrapper for wav files with Clip or SourceDataLine for playback) and use them that way. 我倾向于只命名单个声音对象(使用带有Clip的WAV文件的包装器或用于回放的SourceDataLine),然后以这种方式使用它们。 Could be what you have with that is a good organizational tool, but I'm not clear if it is working as intended. 可能是您拥有的一个很好的组织工具,但是我不清楚它是否按预期工作。

For example, with Static use of SoundEffect, as in SoundEffect.SHOOT.play(), are you sure it is pointing to the shoot.wav? 例如,与SoundEffect.SHOOT.play()一样,在静态使用SoundEffect时,您确定它指向Shoot.wav吗? Have you written a test to verify this? 您是否编写了测试来验证这一点? Combining ENUMS and static invocations--it's getting a little tricky for me to follow. 结合使用ENUMS和静态调用-跟着我变得有些棘手。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM