A lot of mods are now trying to add custom sounds and are having problems. Others will use AudioMod which is a good choice but not needed. Adding sounds is really easy and doesn't require any mods or API's. This tutorial isn't made for a specific version of Minecraft and this method has been consistent among updates. This is a generic tutorial so it will work on ModLoader, Forge or no API at all.
As of 1.4.2, minecraft change the sound type "newsound" and "sound" to the name "sound3".
Common Terms File - java.io.File class Sound Name - Refers to the name of sound, e.g., "mob.cow". See Installing Scheme for more info. SoundSystem - Paul's 3D Sound System SoundManager - Minecraft's SoundManager.class that handles all sound. SoundPool - Maps sound names and their corresponding files together in a HashMap. SoundPool.class holds this information and has methods like get random sound.
Sound Types
In Minecraft there are three types of sounds.
Sound - This is the main type of sound that is used for Mobs, hitting blocks, exp pickups, and many more. You will use this type more often than the rest.
Streaming - Streams the sound; meaning plays as it arrives. As of right now this type is only used for Music Disks.
Music - Same as Sound but for Background music instead. Note that Minecraft will randomly choose the music entry in a SoundPool.
Install Scheme
Minecraft has their own install method for all sounds. No this isn't a special path on the hard drive; it's the method that puts the sounds in a specific SoundPool.
This method takes two parameters; SoundName and File Location.
- SoundName
This defines the type of sound and the name. It has three parts.
"[type][name][file-extension]"
There are three different types as mentioned above. "sound3", "music" or "newmusic", and "streaming".
After the type you can specify the name as anything. Like "mob/cow" or "locknload/mod/tutorial/extremecow". Note if you put a number at the end, Minecraft will remove it e.g., "mob/cow1", "mob/cow2". Only if the SoundPool's boolean getrandomsound is set. Read up on random sounds in the section Playing Sounds.
Lastly comes the file extension. Simple just put an extension like ".ogg" The following codecs are allowed. ogg, mus, and wav files. To add more read the section about Audio Mod below.
Put it all together,
"sound3/mob/cow.ogg" or
"sound3/locknload/mod/tutorial/extremecow.ogg"
- File Location
The file location is a path on the hard drive to the sound. This argument accepts Java's File object.
new File(mc.mcDataDir, "resources/mod/tutorial/extremecow.ogg")
mc is the Minecraft instance which you will need to get. Make sure this is the correct path and import the File class as well.
import java.io.File;
Here is the method being used,
mc.installResource("sound3/locknload/mod/tutorial/extremecow.ogg", new File(
mc.mcDataDir, "resources/mod/tutorial/extremecow.ogg"));
Playing Sounds
To use or play the sound you need the name of it.
locknload/mod/tutorial/extremecow
Replace all the forward slashes (/) with dots (.) It will come out to this,
locknload.mod.tutorial.extremecow
Then you can use that modified name in methods that require it.
If you added custom music it will be played randomly with all the other music.
- Random Sounds
When playing a sound, SoundManger has to find it inside the SoundPool. It will then return a List that contains all sounds with that name and use a random number to select it. That means there can be multiple sounds with the same name. So if you only have the one sound in the list it will only return that sound. Take a look at the cow's sound.
cow1.ogg
cow2.ogg
cow3.ogg
cow4.ogg
When you have numbers at the end of the resource name, it will take them off and put them in the List. When Minecraft plays the sound it will randomly choose one from the List. There are 4 outcomes in this example. Note that the sound's name is "mob.cow", not "mob.cow2" or "mob.cow3" and so on.
Records
Records are fairly easy. First you need to use the Streaming sound type.
"streaming/[name][file-extension]"
Make sure to replace the slashes with dots too.
Then creating the record is like any other Item but the second parameter is the sound name.
new ItemRecord(id, "[name]")
What is Audio Mod
What is Audio Mod and should you use it? It recursively installs sounds in a special folder that is specified. It also allows IBXM codec files; xm, s3m, and mod files. So Audio Mod isn't really needed for adding sounds as I explained in this tutorial, but it is possible to use the IBXM codecs as well. Go to Paul's Sound System website and download the plugin called IBXM http://www.paulscode...x.php?topic=4.0 Unzip it and you will see a jar file called CodecIBXM.jar. Just copy the files in minecraft.jar like any other mod, make sure to delete the META-INF that comes with it too. If you are in eclipse you might want to add the jar to the project's Referenced Libraries. After that you need to register the codec with in Minecraft.
Forge
This tutorial was meant to be generic, meaning not having an API in mind but Forge has their own events for loading sound, configuration, and handling sounds when played. The top event class is SoundEvent.
SoundLoadEvent - For loading custom sounds into the specified SoundPool.
// imports
import net.minecraftforge.event.ForgeSubscribe;
import cpw.mods.fml.common.asm.SideOnly;
import net.minecraftforge.client.event.sound.SoundLoadEvent;
@SideOnly(Side.CLIENT)
@ForgeSubscribe
public void onSoundLoad(SoundLoadEvent event) {
Minecraft mc = Minecraft.getMinecraft();
event.manager.soundPoolSounds.addSound("lnl/mod/tutorial/metalhit.ogg",
new File(mc.mcDataDir, "resources/mod/tutorial/metal_hit.ogg"));
}
SoundSetupEvent - Add your own codes to the SoundSystemConfig
// imports
import net.minecraftforge.event.ForgeSubscribe;
import cpw.mods.fml.common.asm.SideOnly;
import net.minecraftforge.client.event.sound.SoundSetupEvent;
import paulscode.sound.SoundSystemConfig;
@SideOnly(Side.CLIENT)
@ForgeSubscribe
public void onSoundSetup(SoundSetupEvent event) {
// add your own codecs
SoundSystemConfig.addLibrary(LibraryClass.class);
SoundSystemConfig.setCodec("file-extension", CodecClass.class);
}
PlaySoundEffectEvent - Called when the SoundManager tries to play a sound effect.
yeah, hi, its me again. It did not play the sound. here is my code with the parts i dont want released to he public taken out. where it sends a message, that was to see if it worked. messages worked audio nope.
In mod_mediaModRadios
package net.minecraft.src;
import java.io.File;
...
public void load()
{
//installs the sound
Minecraft mc = ModLoader.getMinecraftInstance();
mc.installResource("newsound/RadioStations/TheBlock/block1.ogg", new File(mc.mcDataDir, "resources/newsound/RadioStations/TheBlock/block1.ogg"));
...
in BlockRadio
package net.minecraft.src;
import java.util.Random;
import net.minecraft.client.Minecraft;
...
Minecraft mc = ModLoader.getMinecraftInstance();
public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer)
{
entityplayer.addChatMessage("You clicked my block!");
// plays the sound
mc.sndManager.playSoundFX("RadioStations.TheBlock.block1", 1.0F, 1.0F);
entityplayer.addChatMessage("Congrats!");
return true;
}
...
The file is in the spot it is installing and I tried in Eclipse, using startclient.bat from mcp, ecen putting it into MC. It would not play. What did I do wrong?
Thanks!
Great job lockNload :smile.gif: It's good you released a tutorial on this. People have been loving the non-audiomod-dependant sounds in Undead+.
Rollback Post to RevisionRollBack
“Computers are incredibly fast, accurate and stupid; humans are incredibly slow, inaccurate and brilliant; together they are powerful beyond imagination."
yeah, hi, its me again. It did not play the sound. here is my code with the parts i dont want released to he public taken out. where it sends a message, that was to see if it worked. messages worked audio nope.
In mod_mediaModRadios
package net.minecraft.src;
import java.io.File;
...
public void load()
{
//installs the sound
Minecraft mc = ModLoader.getMinecraftInstance();
mc.installResource("newsound/RadioStations/TheBlock/block1.ogg", new File(mc.mcDataDir, "resources/newsound/RadioStations/TheBlock/block1.ogg"));
...
in BlockRadio
package net.minecraft.src;
import java.util.Random;
import net.minecraft.client.Minecraft;
...
Minecraft mc = ModLoader.getMinecraftInstance();
public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer)
{
entityplayer.addChatMessage("You clicked my block!");
// plays the sound
mc.sndManager.playSoundFX("RadioStations.TheBlock.block1", 1.0F, 1.0F);
entityplayer.addChatMessage("Congrats!");
return true;
}
...
The file is in the spot it is installing and I tried in Eclipse, using startclient.bat from mcp, ecen putting it into MC. It would not play. What did I do wrong?
Thanks!
I believe that the only problem in there and the only error in the OP as far as I can see from scanning it is that all the file paths must start with '/', so like '/newsound/...' and '/resources/...'
I believe that the only problem in there and the only error in the OP as far as I can see from scanning it is that all the file paths must start with '/', so like '/newsound/...' and '/resources/...'
Nice tutorial btw
That might be the error but I'm having trouble on what you did wrong. So your running the startclient.bar from mcp so your sound file should be in jars/resources which I believe you have.
Could you add a section to this tutorial about how to add custom music? (I will eventually put this music on the title screen, but for now I just need it to play)
I've tried following this tutorial exactly except replacing newsound with newmusic, and it doesn't seem to work no matter what I try
This is of great help! Thanks! I'm actually currently modding for a server which doesn't use ModLoader. Since I can't force them to do so, can you explain to me exactly what to do to adapt this (where to find this MinecraftInstance without Modloader and where to put the code you gave us?). It's basically for entity sounds so I want the code of the EntityMyMob to be able to select a random living sound amongst the ones I installed with your code.
Thank you very much!
The way ModLoader gets the Minecraft Instance is by Reflection. Reflection is the way of getting fields, excututing private methods and constructors that you can't normally access. So you can access variables, methods, and constructors that aren't meant to be. If you want more info read this great tutorial. http://tutorials.jen...tion/index.html
Here is a simple method of getting the Minecraft Instance
For people who want to know how this works open the spoiler.
In order to use reflection you got to know what your accessing first, like in this example the variable name. But there is also a method to get all variables and methods too if you don't know the name.
Field minecraftField = Minecraft.class
.getDeclaredField("theMinecraft");
This gets the field of the variable "theMinecraft" in Minecraft.class. Note this doesn't get the actual Minecraft Instance, it just holds the information to retrieve it. It will throw NoSuchFieldException if the field is not found and SecurityException if it is blocked from being acessed. Yes you can block access to reflection if you don't want people to mess with it, but it really isn't necessarily unless it will mess up the program badly. So if not errors come up your all good.
minecraftField.setAccessible(true);
The setAccessible(true)will ignore all Access Checks. You can now access the variable even if its private, protected or default. But only for reflection! Once again it will throw a SecurityException if the programmer blocked it.
mc = (Minecraft) minecraftField.get(null);
Now this will get the object instance from the field above. The method get(object obj) will retrieve the object from the field you made above. Note that for the argument there is a null and here is why. When you are retrieving the instance you need the actually Object to retrieve it from, for this example is Minecraft.class. So if you had a Minecraft instance you would put it there. But sense this field is static which means is belongs to the class not an actual instance, you don't need put an object argument there. So it's null. The tutorial link above will explain it better. The method will throw IllegalArgumentException if argument Object doesn't have an instance of it. Also it will throw IllegalAccessException if the field is private, protected or default and you can't access it. That's why you setAccessible(true) to avoid that exception.
Could you add a section to this tutorial about how to add custom music? (I will eventually put this music on the title screen, but for now I just need it to play)
I've tried following this tutorial exactly except replacing newsound with newmusic, and it doesn't seem to work no matter what I try
yes I was thinking about doing all the resources so I will make that tutorial soon. Just been really busy with other stuff
Rollback Post to RevisionRollBack
Same ****, different day - Modification Development Section
yes I was thinking about doing all the resources so I will make that tutorial soon. Just been really busy with other stuff
Thanks, I would really appreciate if you could do music sooner rather than later
Sidenote: I tried using my .ogg file as a "newsound", and following this tutorial and it still doesn't work...I even changed the file path string, and I didn't get any errors. It seems like the methods not really even being called for some reason. Any help on this issue would be much appreciated as well.
Edit: Nevermind. I figured out what was wrong with that. but another issue arose, my sound file is quite large (a few minutes long), and it freezes minecraft until it's done loading. Do you know of a way to pre-load the sound on start-up?
Thanks, I would really appreciate if you could do music sooner rather than later
Sidenote: I tried using my .ogg file as a "newsound", and following this tutorial and it still doesn't work...I even changed the file path string, and I didn't get any errors. It seems like the methods not really even being called for some reason. Any help on this issue would be much appreciated as well.
Edit: Nevermind. I figured out what was wrong with that. but another issue arose, my sound file is quite large (a few minutes long), and it freezes minecraft until it's done loading. Do you know of a way to pre-load the sound on start-up?
Ok I will look into it tomorrow
Rollback Post to RevisionRollBack
Same ****, different day - Modification Development Section
That might be the error but I'm having trouble on what you did wrong. So your running the startclient.bar from mcp so your sound file should be in jars/resources which I believe you have.
Thanks! and Awesome. You can link this tutorial in your Tutorial thread so more people can see it if you want
Well I do have a youtube account so I can do it, but I'm really busy with other coding stuff
oh to bad for me im not realy good at understainding how to do stuff when it is just riten down
Edit: Nevermind. I figured out what was wrong with that. but another issue arose, my sound file is quite large (a few minutes long), and it freezes minecraft until it's done loading. Do you know of a way to pre-load the sound on start-up?
That's what the load method is for, it sets up the mod. So you want to install your resource in the load method in your Mod Class. As for the freezing, you want to do that in another Thread. Basically there are Threads/Tasks that run in Java. When you start a program in Java there is one Main Thread that does all of the computation. Minecraft has more than one so it can do multiple tasks at once. For example they have a Game Thread that does the game loop. You want to load your resource on another new Thread that will not make Minecraft hang for a while. Note that until it loads you won't be able to play it but by the time you get there it should already be done. I'm going to show you a simple way to start a Thread but if you want more information read this Oracle Java Lesson: http://docs.oracle.c...al/concurrency/.
new Thread() {
@Override
public void run() {
// your code goes in here - install resource
}
}.start();
Put that code in the top of your load method in your Mod Class. Then inside the run method just install the resource. Depending on how large it is depends on when it will finish loading, so just make sure it's done before you play it. Also the Thread should close when it's done too.
Rollback Post to RevisionRollBack
Same ****, different day - Modification Development Section
You sir are absolutely awesome : not only you explain what code we should write, but you also try to make us understand how it works in depth! I'll try to make this work, but where should I put this getMinecraftInstance() class? In my EntityCustomMob.java? Then what code should I add to my EntityCustomMob.java so that it plays a random sound from the soundpool I just created (living sound, hurt sound and death sound)? It would be absolutely great if you just explain how to fully implement new sounds for a custom mob.
Common Terms
Sound Types
Installing Scheme
Playing Sounds
Records
What is Audio Mod
Forge
As of 1.4.2, minecraft change the sound type "newsound" and "sound" to the name "sound3".
Common Terms
File - java.io.File class
Sound Name - Refers to the name of sound, e.g., "mob.cow". See Installing Scheme for more info.
SoundSystem - Paul's 3D Sound System
SoundManager - Minecraft's SoundManager.class that handles all sound.
SoundPool - Maps sound names and their corresponding files together in a HashMap. SoundPool.class holds this information and has methods like get random sound.
Sound Types
In Minecraft there are three types of sounds.
Minecraft has their own install method for all sounds. No this isn't a special path on the hard drive; it's the method that puts the sounds in a specific SoundPool.
This method takes two parameters; SoundName and File Location.
- SoundName
- File Location
Here is the method being used,
Playing Sounds
To use or play the sound you need the name of it.
locknload/mod/tutorial/extremecow
Replace all the forward slashes (/) with dots (.) It will come out to this,
locknload.mod.tutorial.extremecow
Then you can use that modified name in methods that require it.
If you added custom music it will be played randomly with all the other music.
- Random Sounds
Records
Records are fairly easy. First you need to use the Streaming sound type.
"streaming/[name][file-extension]"
Make sure to replace the slashes with dots too.
Then creating the record is like any other Item but the second parameter is the sound name.
What is Audio Mod
What is Audio Mod and should you use it? It recursively installs sounds in a special folder that is specified. It also allows IBXM codec files; xm, s3m, and mod files. So Audio Mod isn't really needed for adding sounds as I explained in this tutorial, but it is possible to use the IBXM codecs as well. Go to Paul's Sound System website and download the plugin called IBXM http://www.paulscode...x.php?topic=4.0 Unzip it and you will see a jar file called CodecIBXM.jar. Just copy the files in minecraft.jar like any other mod, make sure to delete the META-INF that comes with it too. If you are in eclipse you might want to add the jar to the project's Referenced Libraries. After that you need to register the codec with in Minecraft.
Then when you start up your mod put this
That's all you have to do.
Forge
This tutorial was meant to be generic, meaning not having an API in mind but Forge has their own events for loading sound, configuration, and handling sounds when played. The top event class is SoundEvent.
Make sure you register it in your PreInit method.
Forge also has it's version of AudioMod in it as well.
Glad I could help :smile.gif:
in BlockRadio
Thanks!
Wouldn't that be like the best achievement ever?
together they are powerful beyond imagination."
I believe that the only problem in there and the only error in the OP as far as I can see from scanning it is that all the file paths must start with '/', so like '/newsound/...' and '/resources/...'
Nice tutorial btw :smile.gif:
That might be the error but I'm having trouble on what you did wrong. So your running the startclient.bar from mcp so your sound file should be in jars/resources which I believe you have.
Thanks! and Awesome. You can link this tutorial in your Tutorial thread so more people can see it if you want
Well I do have a youtube account so I can do it, but I'm really busy with other coding stuff
I've tried following this tutorial exactly except replacing newsound with newmusic, and it doesn't seem to work no matter what I try
The way ModLoader gets the Minecraft Instance is by Reflection. Reflection is the way of getting fields, excututing private methods and constructors that you can't normally access. So you can access variables, methods, and constructors that aren't meant to be. If you want more info read this great tutorial. http://tutorials.jen...tion/index.html
Here is a simple method of getting the Minecraft Instance
For people who want to know how this works open the spoiler.
This gets the field of the variable "theMinecraft" in Minecraft.class. Note this doesn't get the actual Minecraft Instance, it just holds the information to retrieve it. It will throw NoSuchFieldException if the field is not found and SecurityException if it is blocked from being acessed. Yes you can block access to reflection if you don't want people to mess with it, but it really isn't necessarily unless it will mess up the program badly. So if not errors come up your all good.
The setAccessible(true)will ignore all Access Checks. You can now access the variable even if its private, protected or default. But only for reflection! Once again it will throw a SecurityException if the programmer blocked it.
Now this will get the object instance from the field above. The method get(object obj) will retrieve the object from the field you made above. Note that for the argument there is a null and here is why. When you are retrieving the instance you need the actually Object to retrieve it from, for this example is Minecraft.class. So if you had a Minecraft instance you would put it there. But sense this field is static which means is belongs to the class not an actual instance, you don't need put an object argument there. So it's null. The tutorial link above will explain it better. The method will throw IllegalArgumentException if argument Object doesn't have an instance of it. Also it will throw IllegalAccessException if the field is private, protected or default and you can't access it. That's why you setAccessible(true) to avoid that exception.
yes I was thinking about doing all the resources so I will make that tutorial soon. Just been really busy with other stuff
Thanks, I would really appreciate if you could do music sooner rather than later
Sidenote: I tried using my .ogg file as a "newsound", and following this tutorial and it still doesn't work...I even changed the file path string, and I didn't get any errors. It seems like the methods not really even being called for some reason. Any help on this issue would be much appreciated as well.
Edit: Nevermind. I figured out what was wrong with that. but another issue arose, my sound file is quite large (a few minutes long), and it freezes minecraft until it's done loading. Do you know of a way to pre-load the sound on start-up?
Ok I will look into it tomorrow
That's what the load method is for, it sets up the mod. So you want to install your resource in the load method in your Mod Class. As for the freezing, you want to do that in another Thread. Basically there are Threads/Tasks that run in Java. When you start a program in Java there is one Main Thread that does all of the computation. Minecraft has more than one so it can do multiple tasks at once. For example they have a Game Thread that does the game loop. You want to load your resource on another new Thread that will not make Minecraft hang for a while. Note that until it loads you won't be able to play it but by the time you get there it should already be done. I'm going to show you a simple way to start a Thread but if you want more information read this Oracle Java Lesson: http://docs.oracle.c...al/concurrency/.
Put that code in the top of your load method in your Mod Class. Then inside the run method just install the resource. Depending on how large it is depends on when it will finish loading, so just make sure it's done before you play it. Also the Thread should close when it's done too.