    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    }