今天在利用JAVA3D播放声音的时候,碰到一个很奇怪的问题,那就是声音设备无法初始化。它抛出如下异常:
java.lang.UnsupportedOperationException: No AudioDevice specified
但是教程上面包括SUN的例子里面都是这样写的,他那样写肯定有它的道理,他不可能写一个错误的代码吧?那心里就纳闷了,为什么我的电脑就是播放不了呢,难道又像播放MIDI一样,因为装了JMF的原因?我把JMF也缷了,电脑也重启了,还是不行,该不会是人品问题吧:(
后来查看错误的调用顺序,发现是这句话抛出了异常:
......
viewer.createAudioDevice();
......
也就是在生成音频设备的时候,这个方法会生成并初始化好音频设备,我们在播放音频的时候,一定需要调此方法的。
然后再看这句话里面的代码,说到这里,突然觉得用JAVA挺爽的,可以看到你用的类的JAVA的源码,Viewver是JAVA3D里面的类,查看这个方法,发现这个方法如下:
publicAudioDevice createAudioDevice() {if(physicalEnvironment==null) {
System.err.println("Java 3D: createAudioDevice: physicalEnvironment is null");returnnull;
}try{
String audioDeviceClassName=(String) java.security.AccessController.doPrivileged(newjava.security.PrivilegedAction() {publicObject run() {returnSystem.getProperty("j3d.audiodevice");
}
});if(audioDeviceClassName==null) {thrownewUnsupportedOperationException("No AudioDevice specified");
}//Issue 341: try the current class loader first before trying the//system class loaderClass audioDeviceClass=null;try{
audioDeviceClass=Class.forName(audioDeviceClassName);
}catch(ClassNotFoundException ex) {//Ignore excpetion and try system class loader}if(audioDeviceClass==null) {
ClassLoader audioDeviceClassLoader=(ClassLoader) java.security.AccessController.doPrivileged(newjava.security.PrivilegedAction() {publicObject run() {returnClassLoader.getSystemClassLoader();
}
});if(audioDeviceClassLoader==null) {thrownewIllegalStateException("System ClassLoader is null");
}
audioDeviceClass=Class.forName(audioDeviceClassName,true,
audioDeviceClassLoader);
}
Class physEnvClass=PhysicalEnvironment.class;
Constructor audioDeviceConstructor=audioDeviceClass.getConstructor(newClass[] {physEnvClass});
PhysicalEnvironment[] args=newPhysicalEnvironment[] { physicalEnvironment };
AudioEngine3DL2 mixer=(AudioEngine3DL2) audioDeviceConstructor.newInstance((Object[])args);
mixer.initialize();returnmixer;
}catch(Throwable e) {
e.printStackTrace();
physicalEnvironment.setAudioDevice(null);
System.err.println("Java 3D: audio is disabled");returnnull;
}
}
然后再细看异常是在
if (audioDeviceClassName == null) {
throw new UnsupportedOperationException("No AudioDevice specified");
}
这一句抛出来的,而audioDeviceClassName 是通过System.getProperty("j3d.audiodevice");来获得的,之所以会抛出这个异常,还是因为系统没有j3d.audiodevice的属性,后来我输出System的所有Properties看了一下,果然没有j3d.audiodevice的属性,那就怪了,为什么我的电脑会没有这个属性呢?
后来才知道,本来这个属性装了JAVA3D以后都会有的,但是由于JAVA3D1.3发现了一个BUG,一个播放声音的BUG,所以在后续的版本中把这个属性去掉了,也就是不再让人用JAVA3D来播放声音了。我用的是JAVA3D1.5,所以就没有这个属性了,所以音频设备也就初始化不了了。
那怎么样呢?JAVA不装这个属性,我们自己指定就是了,于是在viewer.createAudioDevice();代码调用之前,我调用如下代码为它设置这个属性,让它可以自己找到音频播放设备:
System.setProperty("j3d.audiodevice", "com.sun.j3d.audioengines.javasound.JavaSoundMixer");
这样就好了,我们在播放的时候,使用的就是com.sun.j3d.audioengines.javasound.JavaSoundMixer来播放了,不过,因为有BUG的报道,所以用它播放可能会出现一些问题,听说现在JOAL正在努力解决这个问题。让我们共同期待吧。
JOAL的地址:https://joal.dev.java.net
JOGL的地址:https://jogl.dev.java.net
尽管千里冰封
依然拥有晴空
你我共同品味JAVA的浓香.
posted on 2007-10-06 09:02 千里冰封 阅读(1893) 评论(8) 编辑 收藏 所属分类: JAVA扩展