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 }