001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.io.File; 006 import java.util.Random; 007 008 import net.minecraftforge.client.ForgeHooksClient; 009 import net.minecraftforge.client.ModCompatibilityClient; 010 import net.minecraftforge.client.event.sound.PlaySoundEffectEvent; 011 import net.minecraftforge.client.event.sound.PlaySoundEffectSourceEvent; 012 import net.minecraftforge.client.event.sound.PlaySoundEvent; 013 import net.minecraftforge.client.event.sound.PlaySoundSourceEvent; 014 import net.minecraftforge.client.event.sound.PlayStreamingEvent; 015 import net.minecraftforge.client.event.sound.PlayStreamingSourceEvent; 016 import net.minecraftforge.client.event.sound.SoundEvent; 017 import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent; 018 import net.minecraftforge.client.event.sound.SoundLoadEvent; 019 import net.minecraftforge.client.event.sound.SoundSetupEvent; 020 import net.minecraftforge.common.MinecraftForge; 021 import static net.minecraftforge.client.event.sound.SoundEvent.*; 022 import paulscode.sound.SoundSystem; 023 import paulscode.sound.SoundSystemConfig; 024 import paulscode.sound.codecs.CodecJOrbis; 025 import paulscode.sound.codecs.CodecWav; 026 import paulscode.sound.libraries.LibraryLWJGLOpenAL; 027 028 @SideOnly(Side.CLIENT) 029 public class SoundManager 030 { 031 /** A reference to the sound system. */ 032 public static SoundSystem sndSystem; 033 034 /** Sound pool containing sounds. */ 035 public SoundPool soundPoolSounds = new SoundPool(); 036 037 /** Sound pool containing streaming audio. */ 038 public SoundPool soundPoolStreaming = new SoundPool(); 039 040 /** Sound pool containing music. */ 041 public SoundPool soundPoolMusic = new SoundPool(); 042 043 /** 044 * The last ID used when a sound is played, passed into SoundSystem to give active sounds a unique ID 045 */ 046 private int latestSoundID = 0; 047 048 /** A reference to the game settings. */ 049 private GameSettings options; 050 051 /** Set to true when the SoundManager has been initialised. */ 052 private static boolean loaded = false; 053 054 /** RNG. */ 055 private Random rand = new Random(); 056 private int ticksBeforeMusic; 057 058 public static int MUSIC_INTERVAL = 12000; 059 060 public SoundManager() 061 { 062 this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL); 063 } 064 065 /** 066 * Used for loading sound settings from GameSettings 067 */ 068 public void loadSoundSettings(GameSettings par1GameSettings) 069 { 070 this.soundPoolStreaming.isGetRandomSound = false; 071 this.options = par1GameSettings; 072 073 if (!loaded && (par1GameSettings == null || par1GameSettings.soundVolume != 0.0F || par1GameSettings.musicVolume != 0.0F)) 074 { 075 this.tryToSetLibraryAndCodecs(); 076 } 077 ModCompatibilityClient.audioModLoad(this); 078 MinecraftForge.EVENT_BUS.post(new SoundLoadEvent(this)); 079 } 080 081 /** 082 * Tries to add the paulscode library and the relevant codecs. If it fails, the volumes (sound and music) will be 083 * set to zero in the options file. 084 */ 085 private void tryToSetLibraryAndCodecs() 086 { 087 try 088 { 089 float var1 = this.options.soundVolume; 090 float var2 = this.options.musicVolume; 091 this.options.soundVolume = 0.0F; 092 this.options.musicVolume = 0.0F; 093 this.options.saveOptions(); 094 SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class); 095 SoundSystemConfig.setCodec("ogg", CodecJOrbis.class); 096 SoundSystemConfig.setCodec("mus", CodecMus.class); 097 SoundSystemConfig.setCodec("wav", CodecWav.class); 098 ModCompatibilityClient.audioModAddCodecs(); 099 MinecraftForge.EVENT_BUS.post(new SoundSetupEvent(this)); 100 sndSystem = new SoundSystem(); 101 this.options.soundVolume = var1; 102 this.options.musicVolume = var2; 103 this.options.saveOptions(); 104 } 105 catch (Throwable var3) 106 { 107 var3.printStackTrace(); 108 System.err.println("error linking with the LibraryJavaSound plug-in"); 109 } 110 111 loaded = true; 112 } 113 114 /** 115 * Called when one of the sound level options has changed. 116 */ 117 public void onSoundOptionsChanged() 118 { 119 if (!loaded && (this.options.soundVolume != 0.0F || this.options.musicVolume != 0.0F)) 120 { 121 this.tryToSetLibraryAndCodecs(); 122 } 123 124 if (loaded) 125 { 126 if (this.options.musicVolume == 0.0F) 127 { 128 sndSystem.stop("BgMusic"); 129 } 130 else 131 { 132 sndSystem.setVolume("BgMusic", this.options.musicVolume); 133 } 134 } 135 } 136 137 /** 138 * Called when Minecraft is closing down. 139 */ 140 public void closeMinecraft() 141 { 142 if (loaded) 143 { 144 sndSystem.cleanup(); 145 } 146 } 147 148 /** 149 * Adds a sounds with the name from the file. Args: name, file 150 */ 151 public void addSound(String par1Str, File par2File) 152 { 153 this.soundPoolSounds.addSound(par1Str, par2File); 154 } 155 156 /** 157 * Adds an audio file to the streaming SoundPool. 158 */ 159 public void addStreaming(String par1Str, File par2File) 160 { 161 this.soundPoolStreaming.addSound(par1Str, par2File); 162 } 163 164 /** 165 * Adds an audio file to the music SoundPool. 166 */ 167 public void addMusic(String par1Str, File par2File) 168 { 169 this.soundPoolMusic.addSound(par1Str, par2File); 170 } 171 172 /** 173 * If its time to play new music it starts it up. 174 */ 175 public void playRandomMusicIfReady() 176 { 177 if (loaded && this.options.musicVolume != 0.0F) 178 { 179 if (!sndSystem.playing("BgMusic") && !sndSystem.playing("streaming")) 180 { 181 if (this.ticksBeforeMusic > 0) 182 { 183 --this.ticksBeforeMusic; 184 return; 185 } 186 187 SoundPoolEntry var1 = this.soundPoolMusic.getRandomSound(); 188 var1 = ModCompatibilityClient.audioModPickBackgroundMusic(this, var1); 189 var1 = SoundEvent.getResult(new PlayBackgroundMusicEvent(this, var1)); 190 191 if (var1 != null) 192 { 193 this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL) + MUSIC_INTERVAL; 194 sndSystem.backgroundMusic("BgMusic", var1.soundUrl, var1.soundName, false); 195 sndSystem.setVolume("BgMusic", this.options.musicVolume); 196 sndSystem.play("BgMusic"); 197 } 198 } 199 } 200 } 201 202 /** 203 * Sets the listener of sounds 204 */ 205 public void setListener(EntityLiving par1EntityLiving, float par2) 206 { 207 if (loaded && this.options.soundVolume != 0.0F) 208 { 209 if (par1EntityLiving != null) 210 { 211 float var3 = par1EntityLiving.prevRotationYaw + (par1EntityLiving.rotationYaw - par1EntityLiving.prevRotationYaw) * par2; 212 double var4 = par1EntityLiving.prevPosX + (par1EntityLiving.posX - par1EntityLiving.prevPosX) * (double)par2; 213 double var6 = par1EntityLiving.prevPosY + (par1EntityLiving.posY - par1EntityLiving.prevPosY) * (double)par2; 214 double var8 = par1EntityLiving.prevPosZ + (par1EntityLiving.posZ - par1EntityLiving.prevPosZ) * (double)par2; 215 float var10 = MathHelper.cos(-var3 * 0.017453292F - (float)Math.PI); 216 float var11 = MathHelper.sin(-var3 * 0.017453292F - (float)Math.PI); 217 float var12 = -var11; 218 float var13 = 0.0F; 219 float var14 = -var10; 220 float var15 = 0.0F; 221 float var16 = 1.0F; 222 float var17 = 0.0F; 223 sndSystem.setListenerPosition((float)var4, (float)var6, (float)var8); 224 sndSystem.setListenerOrientation(var12, var13, var14, var15, var16, var17); 225 } 226 } 227 } 228 229 public void playStreaming(String par1Str, float par2, float par3, float par4, float par5, float par6) 230 { 231 if (loaded && (this.options.soundVolume != 0.0F || par1Str == null)) 232 { 233 String var7 = "streaming"; 234 235 if (sndSystem.playing("streaming")) 236 { 237 sndSystem.stop("streaming"); 238 } 239 240 if (par1Str != null) 241 { 242 SoundPoolEntry var8 = this.soundPoolStreaming.getRandomSoundFromSoundPool(par1Str); 243 var8 = SoundEvent.getResult(new PlayStreamingEvent(this, var8, par1Str, par2, par3, par4)); 244 245 if (var8 != null && par5 > 0.0F) 246 { 247 if (sndSystem.playing("BgMusic")) 248 { 249 sndSystem.stop("BgMusic"); 250 } 251 252 float var9 = 16.0F; 253 sndSystem.newStreamingSource(true, var7, var8.soundUrl, var8.soundName, false, par2, par3, par4, 2, var9 * 4.0F); 254 sndSystem.setVolume(var7, 0.5F * this.options.soundVolume); 255 MinecraftForge.EVENT_BUS.post(new PlayStreamingSourceEvent(this, var7, par2, par3, par4)); 256 sndSystem.play(var7); 257 } 258 } 259 } 260 } 261 262 /** 263 * Plays a sound. Args: soundName, x, y, z, volume, pitch 264 */ 265 public void playSound(String par1Str, float par2, float par3, float par4, float par5, float par6) 266 { 267 if (loaded && this.options.soundVolume != 0.0F) 268 { 269 SoundPoolEntry var7 = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str); 270 var7 = SoundEvent.getResult(new PlaySoundEvent(this, var7, par1Str, par2, par3, par4, par5, par6)); 271 272 if (var7 != null && par5 > 0.0F) 273 { 274 this.latestSoundID = (this.latestSoundID + 1) % 256; 275 String var8 = "sound_" + this.latestSoundID; 276 float var9 = 16.0F; 277 278 if (par5 > 1.0F) 279 { 280 var9 *= par5; 281 } 282 283 sndSystem.newSource(par5 > 1.0F, var8, var7.soundUrl, var7.soundName, false, par2, par3, par4, 2, var9); 284 sndSystem.setPitch(var8, par6); 285 286 if (par5 > 1.0F) 287 { 288 par5 = 1.0F; 289 } 290 291 sndSystem.setVolume(var8, par5 * this.options.soundVolume); 292 MinecraftForge.EVENT_BUS.post(new PlaySoundSourceEvent(this, var8, par2, par3, par4)); 293 sndSystem.play(var8); 294 } 295 } 296 } 297 298 /** 299 * Plays a sound effect with the volume and pitch of the parameters passed. The sound isn't affected by position of 300 * the player (full volume and center balanced) 301 */ 302 public void playSoundFX(String par1Str, float par2, float par3) 303 { 304 if (loaded && this.options.soundVolume != 0.0F) 305 { 306 SoundPoolEntry var4 = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str); 307 var4 = SoundEvent.getResult(new PlaySoundEffectEvent(this, var4, par1Str, par2, par3)); 308 309 if (var4 != null) 310 { 311 this.latestSoundID = (this.latestSoundID + 1) % 256; 312 String var5 = "sound_" + this.latestSoundID; 313 sndSystem.newSource(false, var5, var4.soundUrl, var4.soundName, false, 0.0F, 0.0F, 0.0F, 0, 0.0F); 314 315 if (par2 > 1.0F) 316 { 317 par2 = 1.0F; 318 } 319 320 par2 *= 0.25F; 321 sndSystem.setPitch(var5, par3); 322 sndSystem.setVolume(var5, par2 * this.options.soundVolume); 323 MinecraftForge.EVENT_BUS.post(new PlaySoundEffectSourceEvent(this, var5)); 324 sndSystem.play(var5); 325 } 326 } 327 } 328 }