Content: Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Background: Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Pattern: Blank Waves Notes Sharp Wood Rockface Leather Honey Vertical Triangles
Welcome to Xbox Chaos: Modding Evolved

Register now to gain access to all of our features. Once registered and logged in, you will be able to contribute to this site by submitting your own content or replying to existing content. You'll be able to customize your profile, receive reputation points as a reward for submitting content, while also communicating with other members via your own private inbox, plus much more! This message will be removed once you have signed in.

Lord Zedd

.MAP
Injecting Custom Sounds

18 posts in this topic

This tutorial can also be applied to injecting sounds from another map, which I'll touch on when the time comes, but tldr its all this but with more ugh blocks to keep track of.

 

This tutorial can also apply to every other game that is not named Halo 4. Use some common sense to adapt any changes.

 

Stuff needed:

1. Preparing your sound

Before we begin we need to make sure your sound is all good and ready for conversion. But we also need to make sure your Audacity is good to go as well.

Head to Edit>Preferences, and under Import/Export make sure "Use Custom Mix" is selected like this. You can also uncheck "Show Metadata Editor" if you'd like.

nOWPeJK.png

 

 

Open it up in Audacity and you should see something like this

9G1RuhR.png

 

Preferably you will want the same setup as circled in red, if not stereo then mono, and if not 44100Hz then 32000Hz or 22000Hz. Anything else you will need to go to Tracks>Resample and set what you want. If you have more than 2 channels continue on as that will be fixed on export.

 

When everything checks out and you've made any edits to the sound if you are into that, go up to File>Export and change the save as type to WAV. Give it a name and hit save it to your desktop. The following dialog should pop up

tb3StjU.png

 

Here is where you will combine channels if you have more than two. Change the bottom slider and click the boxes to link them however you wish. Hit OK when done. Your WAV will be made and you can close Audacity. Make sure to note down your sample rate and channel count as you will need that later.

 

2. Converting your sound

Copy xma2encode to your desktop and with nothing selected hold Shift and right click. Select "Open Command Window Here" from the menu and you will get a command prompt window. You will want to type the following:

xma2encode yoursound.wav /targetfile yoursound.xma

If you want to get experimental you can also use

xma2encode yoursound.wav /blocksize # /targetfile yoursound.xma

With # being the size in kb you want each block to be, which will translate to permutation chunks. By default it is x10000 bytes or 64kb which is also what will be used in this tutorial. A bigger number may save you some work but it may also not work since nothing past 64kb has been tried. Multiply your choice by 1024 in windows calculator and note the result as decimal and hex for later. This is the block size.

 

xma2encode does not display any progress and just spits out your file and exits, so verify your new .xma file is on your desktop and close the command window.

 

3. Preparing your converted sound

You can't use the .xma as it stands. You must strip the header. Open the .xma in a hex editor and find the string "data", skip 4 bytes past that, then select from there backwards to the beginning and delete.

NBctTXe.png

 

File>Save As whatever name and extension, or save over your xma I dont care.

Ctrl+A to get the overall byte count of your file (as hex) and make note of that. And while we are here, open up a fresh calculator and divide the overall size by the hex block size. That will get you the number of full blocks in your sound (programmer mode rounds the result which is what you want) so note it, but you also need the size of the final block that tends to be smaller. So multiply the count by the block size then subtract it from the overall size. The result is your final block size.

 

For me that looks like this:

block size: x10000

overall size: x39800

----------

full-block count: 3

----------

final block size: x9800

----------

total block count: 4 (3 full plus the final)

 

Note the total block count and final block size and close everything down.

 

4. Injecting donor sound

Open the above Assembly and set up your H3/whatever game's shared path in settings.

 

Now you need to find a donor sound that you will be overwriting the injected raw of. I like to use a smaller/shorter sound. The smallest sounds are going to be campaign dialogue, with "sound\dialog\130_epilogue\letterbox\130lb_100_arb" from epilogue being my favorite (Arbiter saying "Were It So Easy"). So open up whatever map and extract. (This tutorial will use the Epilogue sound and if you don't your results may vary.)

 

While you could manually expand the raw table and update everything that way, we are gonna be hardcore and edit the tagc.

Open the tagc in a hex editor and do a text search for "ersp". Go xD bytes after it and select everything before it and paste it into a new document then save it as a new .tagc. Time to make some fixes to the tagc.

 

The 4 bytes following "ersp" is the size of the ersp block, and that must be updated to the overall size (hex) of your headerless xma + x11.

The last 4 bytes in your document right now is the size of the raw itself, so replace it with the overall size (hex) of your headerless xma.

 

Open your headerless xma and paste its contents at the end of your custom tagc document.

 

Do another search for ersp in the original tagc, this should take you to a second, empty page that all sounds seem to have. Copy everything from there (including the ersp text) to the end of the file and paste at the end of your custom document.

 

Search for rspg. x11 bytes past that is size. Replace those 4 bytes with the headerless size again. Skip another byte forward and you'll be at another size, replace for a final time and save. (See image if confused. The 4 underlined bytes in both instances need to be replaced, notice the one byte between them not underlined)

QoSvpDo.png

 

One last fix is needed. Select All on your custom tagc and note the hex size of the entire document. Enter this over the 4 bytes after "tagc" at the beginning of the file. Save once more and try injecting your custom tagc. It should go through fine. If you get an error you messed up somewhere in the tagc so try it again.

 

If it injected you can close the hex editor for now.

 

5. Fixing the raw pages block entry

We only modified the tagc as necessary, and there are still some things we need to fix further.

Since you only injected one thing, we can just go to the second to last Raw Pages index (the last should have a size of 0).

This is where OrangeMohawk's tool comes into play. Open that and drag your headerless file over it to get the CRC/hash info for it and replace the ones in the tag. Save Changes.

 

Take this time to make a backup and make sure that the map still loads ingame. If it doesn't check your CRC, Hashes, and TAGC.

 

6/7/8. Expansion

This tutorial was made before you were able to add entries to tag blocks (reflexives) from inside Assembly using the + button. The original end of the tutorial is spoilered, but the updated version is:

Open up play and add 2 entries to the "Sizes" block. For the first entry convert your headerless size to decimal and paste it in the first field.

Then in that first entry you added, add 1 entry for "Parts". Paste the decimal size in the second field, leaving the first field 0.

Note the index of the 2 added Raw Sizes chunks and go to the last Segments chunk below Raw Sizes. Replace the "Size Datumindex" values with both Raw Sizes indexes. The first being the one you filled in and the second being the empty one. Save. PLAY is now finished. Onward to UGH!

 

Scroll down to Pitch Ranges and add 1 entry. Note the Index of the new chunk.

 

Check other indexes to find the name index for "default". In your new chunk give "Import Name Index" that name index.

 

"Pitch Range Parameter Index" refers to the block above, so give it the index of whichever chunk looks like this:

ZoEbrPM.png

 

Make "Encoded Permutation Data Index" 0

 

Make "Encoded Runtime Permutation Flag Index" -1

 

Make "Encoded Permutation Count" 1040

 

Make "First Permutation Index" the index of the chunk you are about to add to Permutations.

 

-

 

Add 1 entry to Permutations.

 

Give "Import Name Index" the default import name too.

 

Make "Encoded Skip Fraction" 0

 

Make "Sample Size" the decimal size of the headerless xma.

 

Make "First Permutation Chunk" the index of the first chunk you are about to add to Permutation Chunks.

 

Make the "Permutation Chunk Count" the number of blocks your sound is made up of. (Remember when we did that?)

 

Leave the rest of the block empty

 

-

 

Add the same number of sound blocks you found to Permutation Chunks.

 

Make the first chunk look like this, with both Chunk Size values differing if you chose not to use 64kb block size. Also make "Unknown Size" the size of your headerless sound.

tuRNKj4.png

 

If you only had one chunk skip ahead, the following is only for filling out further chunks. Save and move on.

 

Here is what each further chunk should look like, where only the "File Offset" will change each time, besides the final chunk.

GIAIlZn.png

 

You can get the File Offset by starting at 0 and adding the decimal block size each time. 64kb is 64 times 1024 which equals 65536 so the second chunk is offset  65536. Third will be 131072, and so on and so forth.

 

At the final chunk make it look like this: (offset and sizes may vary)

PPAajBT.png

 

The Chunk Size has now changed to the smaller one and a flag was added. When everything is filled out Save Changes.

 

~Single-Chunkies may continue following now.

 

All we need now is to touch up the SND! tag. So open that up. Keep UGH! open.

 

Starting from the top;

 

Leave the "Flags" alone (Only bit 3 checked)

 

Set the "Sound Class" to whatever you want. Keeping it somewhat accurate to your intended application will benefit you. (Music gets music, etc.)

 

For "Platform Codec Index" head back to UGH! at the top and find the Platform Codec block index that matches your sound (Which is likely 44kHz Stereo). Give it that index.

 

For "Pitch Range Index" give it the index of the chunk you added.

 

Make "Language B Index" -1

 

Keep the "Unknown" 0

 

For "Playback Parameter Index" find an existing index that is either empty besides the 2 angles (Distance Flags checked), or one mostly empty besides the angles and Distance C and D. Distance A and B have not worked well in my testing. You for sure want Gain Variance, and both Random Pitch Bounds at 0 however. Gain Base is okay if it's only like -3 or something. Look for higher/lower gains if you want it louder/quieter.

 

For "Scale Index" find the chunk that looks like this and give it its index:

JrmlNOi.png

 

Promotion Index, Custom Playback Index, and Extra Info Index should be -1

 

Leave the rest of the tag alone. Save Changes. Your sound is now injected! Rename the tag as you see fit and have fun!

 

6. Preparing for expansion

In addition to the Raw Sizes info, we need to get the info of a few blocks in ugh! to accommodate your sound. So open up ugh!

 

Scroll down to "Pitch Ranges" and copy its count and entry size.

Do the same for "Permutations" below it.

And do it again for "Permutation Chunks" further down.

 

If you were injecting a sound from another map, you'd be doing this with just about all the blocks in ugh!.

 

With all that info grabbed, time for math! But first close the map.

Multiply the count and entry size for the 4 blocks and copy their hex size.

Then add up each hex result. The result rounded to the next x10000 is how much data you need. The rounded result divided by x10000 (chop off the 0s) is the amount of "pages" you need to enter into mapexpand.

 

Mine looks like this:

Raw Sizes: 4046*16 = xFCE0

Pitch Ranges: 2207*12 = x6774

Permutations: 7271*16 = x1C670

Permutation Chunks: 8260*20 = x28550

= x5B014, or x60000, or 6 pages.

 

If your un-rounded size is already pretty close (like xZD000 or higher), add an extra page for good measure.

 

 

7. Expansion

Run mapexpand (if you don't know how look at other tutorials) on your map, and obviously note the memory and file addresses.

 

Now move/duplicate those 4 blocks (see http://www.xboxchaos.com/topic/3543-duplicating-reflexives/). Start at Step 2, don't do Step 4. knowing you already have the sizes so you just need the file offsets (which I didn't already have you get because mapexpand-ing changes them.)

 

Grab all the offsets at once, then one after the other move them into your free space noting their file offsets. Leave like x100 bytes space in between each block and make sure there's a lot of space after permutation chunks.

 

When all is copied save and close the hex editor. Reopen your map in Assembly, and in the Map Information tab double click the Map Magic value to copy it. Now add that to each file offset. The results are your new memory addresses, so plug those into play and ugh!.

 

8. Filling in new chunks

Now with the blocks moved to locations that are safe to resize, we need to properly fill them in. Starting with play.

Add 2 to the count of Raw Sizes. For the first value in the block, convert your headerless size to decimal and paste it in.

Then right click the value's name and choose View Value As. Scroll down to raw example and get the address below it. Add x20 to it and paste that into the inside block with a count of 1. Copy the decimal headerless size to the second value in that block. The second added Sizes block will be left empty.

 

Note the index of the 2 added Raw Sizes chunks and go to the last Segments chunk below Raw Sizes. Replace the "Size Datumindex" values with both Raw Sizes indexes. The first being the one you filled in and the second being the empty one. Save. PLAY is now finished. Onward to UGH!

 

Scroll down to Pitch Ranges and add 1 to the count. Note the Index of the new chunk.

 

Check other indexes to find the name index for "default". In your new chunk give "Import Name Index" that name index.

 

"Pitch Range Parameter Index" refers to the block above, so give it the index of whichever chunk looks like this:

ZoEbrPM.png

 

Make "Encoded Permutation Data Index" 0

 

Make "Encoded Runtime Permutation Flag Index" -1

 

Make "Encoded Permutation Count" 1040

 

Make "First Permutation Index" the index of the chunk you are about to add to Permutations.

 

-

 

Add 1 to the count of Permutations.

 

Give "Import Name Index" the default import name too.

 

Make "Encoded Skip Fraction" 0

 

Make "Sample Size" the decimal size of the headerless xma.

 

Make "First Permutation Chunk" the index of the first chunk you are about to add to Permutation Chunks.

 

Make the "Permutation Chunk Count" the number of blocks your sound is made up of. (Remember when we did that?)

 

Leave the rest of the block empty

 

-

 

Add the same number of sound blocks you found to the count of Permutation Chunks. Scroll through them to make sure everything is 0 (to make your you didn't skimp on space at the end of pasting the Chunks block)

 

Make the first chunk look like this, with both Chunk Size values differing if you chose not to use 64kb block size. Also make "Unknown Size" the size of your headerless sound.

tuRNKj4.png

 

If you only had one chunk skip ahead, the following is only for filling out further chunks. Save and move on.

 

Here is what each further chunk should look like, where only the "File Offset" will change each time, besides the final chunk.

GIAIlZn.png

 

You can get the File Offset by starting at 0 and adding the decimal block size each time. 64kb is 64 times 1024 which equals 65536 so the second chunk is offset  65536. Third will be 131072, and so on and so forth.

 

At the final chunk make it look like this: (offset and sizes may vary)

PPAajBT.png

 

The Chunk Size has now changed to the smaller one and a flag was added. When everything is filled out Save Changes.

 

~Single-Chunkies may continue following now.

 

All we need now is to touch up the SND! tag. So open that up. Keep UGH! open.

 

Starting from the top;

 

Leave the "Flags" alone (Only bit 3 checked)

 

Set the "Sound Class" to whatever you want. Keeping it somewhat accurate to your intended application will benefit you. (Music gets music, etc.)

 

For "Platform Codec Index" head back to UGH! at the top and find the Platform Codec block index that matches your sound (Which is likely 44kHz Stereo). Give it that index.

 

For "Pitch Range Index" give it the index of the chunk you added.

 

Make "Language B Index" -1

 

Keep the "Unknown" 0

 

For "Playback Parameter Index" find an existing index that is either empty besides the 2 angles (Distance Flags checked), or one mostly empty besides the angles and Distance C and D. Distance A and B have not worked well in my testing. You for sure want Gain Variance, and both Random Pitch Bounds at 0 however. Gain Base is okay if it's only like -3 or something. Look for higher/lower gains if you want it louder/quieter.

 

For "Scale Index" find the chunk that looks like this and give it its index:

JrmlNOi.png

 

Promotion Index, Custom Playback Index, and Extra Info Index should be -1

 

Leave the rest of the tag alone. Save Changes. Your sound is now injected! Rename the tag as you see fit and have fun!

Share this post


Link to post
Share on other sites

inb4

"HALO 3 MAIN MENU WITH DUBSTEP PATCH DOWNLOAD"

"HALO 3 MAIN MENU WITH DIFFERENT DUBSTEP PATCH DOWNLOAD"

"HALO 3 MAIN MENU WITH HEAVY METAL PATCH DOWNLOAD"

"HALO 3 MAIN MENU WITH HALO 3 MENU MUSIC PATCH DOWNLOAD"

Share this post


Link to post
Share on other sites

inb4

"HALO 3 MAIN MENU WITH DUBSTEP PATCH DOWNLOAD"

"HALO 3 MAIN MENU WITH DIFFERENT DUBSTEP PATCH DOWNLOAD"

"HALO 3 MAIN MENU WITH HEAVY METAL PATCH DOWNLOAD"

"HALO 3 MAIN MENU WITH HALO 3 MENU MUSIC PATCH DOWNLOAD"

HALO 3 MAIN MENU WITH HUNTER SOUNDS PATCH DOWNLOAD

Kojuku, [Iconoclast] and EHEBrandon like this

Share this post


Link to post
Share on other sites

inb4"HALO 3 MAIN MENU WITH DUBSTEP PATCH DOWNLOAD""HALO 3 MAIN MENU WITH DIFFERENT DUBSTEP PATCH DOWNLOAD""HALO 3 MAIN MENU WITH HEAVY METAL PATCH DOWNLOAD""HALO 3 MAIN MENU WITH HALO 3 MENU MUSIC PATCH DOWNLOAD"

CRWALING IN MY SKIIIIIN, THESE WOUNDS THEY WILL NOT HEAL!

Share this post


Link to post
Share on other sites

That assembly does not work for me. It runs in the background for a while then disappears. 

Edited by matty45

Share this post


Link to post
Share on other sites

Halo 3 W/ CoD WaW Russian Soundtrack running in the backround? Might work with a different, darker colour scheme for the mainmenu backround.

Share this post


Link to post
Share on other sites

Quick test of something I've been making. This automates step 2 to 4 of this tutorial currently. Since I've encountered some issues this may not get much further anytime soon.

open the xma file that xma2encode has just given you
http://www.mediafire.com/download/cqr4byjvzphusr7/Halo3SoundTagCNamed.rar

EDIT:
automated converting from wav to xma (step 2), so now you just need to load your wav file (after making it mono channel) and itll give you a tagc ready to inject

(forgot to mention to put your xma2encode.exe into the asset folder)
http://www.mediafire.com/download/44iq2i3ne8g7ofa/Halo3SoundTagCConverting.rar

 

EDIT2:

fixed it so you still have the headerless xma file after so you can use it in the hash viewer

http://www.mediafire.com/download/bjdozimncm0916e/Halo3InjectionHelper2.rar

GruntyGunner likes this

Share this post


Link to post
Share on other sites

gosh darn that's a lot of steps

definitely not doing this for a while

Edited by Brick Cave

Share this post


Link to post
Share on other sites