Page 1 of 1

[TUTORIAL] Custom SFX implementation

Posted: Sun Sep 20, 2020 4:59 am
by giftheck
Image

I'll be referring to the mod folder as MOD or DataMOD in this tutorial, but it'll be whatever you have named yours.

So, first off, there's two file formats you'll need to implement custom SFX:
SND - this is the actual configuration file that stores what samples are called, pitch, volume, etc.
ASFX - this is where the samples called by the SND are stored.
Create a folder inside DataMOD/Sounds/worlds and name it whatever you want (most likely the three letter MOD name)

Inside that, you'll also need two folders - effects, and samples.

Basically, this is what the folder will look like:
-base REQ file (the MOD id)
--REQ file for effects and streams called for CW (MODcw)
--ASFX file for effects and streams called for CW (MODcw)
--Same as above, but for GCW
--SND files - doesn't have to be for both, and you can have as many of these as you like. The best practice here is to have an SND file for shared SFX (in this instance it would be the LEGO brick explosions upon death) and a separate one for each era. These can be called whatever you want but for simplicity's sake I'll go with MODcw, MODgcw, and shared.
First, you'll need your sound effects placed into the effects folder. These sounds, ideally, should be saved as 22kHz mono wav files.

Next, you'll need to set up the REQ files. Open MOD.req. This is what needs to be inside:

Code: Select all

ucft
{
    REQN
    {
        "str"
        "align=2048"
    }
    REQN
    {
        "lvl"
        "MODcw"
        "MODgcw"
    }

 }
Now open MODgcw.req. This is what needs to be inside that:

Code: Select all

ucft
{
    REQN
    {
    "bnk"
    "align=2048"
    "MODgcw"
    }

    REQN
    {
    "config"
    "MODgcw"
    "shared"
    }
}
Same would go for MODcw.

The bnk section will look for ASFX and SFX files. However, SFX files are not useful in this instance since we're not making a new common.bnk, these sounds are to be munged and loaded directly from the sound.lvl

The next step is top open up the ASFX file in Notepad. It should be blank. All this will be is a list referring to the .wav files. All that needs to be is thus:
effects\whatever_the_sound_is_called.wav
You can also add -resample pc 22050 (changing 22050 to whatever you want) but if the wavs are already 22khz this is not needed.

Now comes the 'fun' part - the SND files. Open shared.snd. Windows will try to open these in Windows Media Player, but they are, in fact, just text files, so you open these with Notepad also.

This is the 'fun' part because you have to figure out which settings are appropriate for the sound you want to implement.
In this instance I find it much easier to just find one of the stock SND files, open it, look for a sound that is similar to the one you're looking for. In this example we are going to implement a custom death sound SFX.

So find imp_unit.snd in the sound/gcw folder Any of the sounds that inherit from "imp_inf_pain_vo" will be fine to copy into your snd file.

IE:

Code: Select all

SoundProperties()
{
    Name("imp_inf_com_chatter_death");
    Group("imp_inf_pain_vo");
    Inherit("pain_chatter_template");
    PlayInterval(0.0);
    PlayIntervalDev(0.0);
    PlayProbability(1.0);
    SampleList()
    {
        Sample("IICOM419", 0.33);
        Sample("IICOM420", 0.33);
        Sample("IICOM421", 0.33);
    }
}
Now, generally, the settings don't need to be messed with. You will need to change two things though:

-The 'name' of the sound
-The samples called in the list.

Name is easy. Just change it to whatever you want to. You can then paste that name into your ODF files' DeathSound line.

The sample list is a tad more complicated.
You have these values bracketed under it:

Code: Select all

        Sample("IICOM419", 0.33);
        Sample("IICOM420", 0.33);
        Sample("IICOM421", 0.33);
Sample is obvious as this refers to the file names as defined in the ASFX file. The number defines the 'weight' of the sound - basically, it randomizes the sound called. The number should always be 1 divided by the number of samples in the list, rounded to 2 decimal places.
Let's say this is what's in the ASFX file:
effects\LEGO_FALLAPART1.wav
effects\LEGO_FALLAPART2.wav
effects\LEGO_FALLAPART3.wav
effects\LEGO_FALLAPART4.wav
effects\LEGO_FALLAPART5.wav
You'll want all of those to be called into the SND, and all equally 'weighted'.
So your sample list will end up looking like this:

Code: Select all

        Sample("LEGO_FALLAPART1", 0.2);
        Sample("LEGO_FALLAPART2", 0.2);
        Sample("LEGO_FALLAPART3", 0.2);
        Sample("LEGO_FALLAPART4", 0.2);
        Sample("LEGO_FALLAPART5", 0.2);
That should conclude the setting up of the ASFX, SND and REQ files, but if you try to munge now, you'll get nothing. Unlike the SWBF1 mod tools, the SWBF2 Mod Tools aren't automatically set to allow for munging of custom sounds. So, there is a bit of tinkering left to do before you're ready.

Open up the soundmungedir.bat file
Find this line:

Code: Select all

for /R %%A in (*.sfx) do @echo Munging %%~nA%%~xA & @soundflmunge -platform %4 -banklistinput %%A -bankoutput %MUNGEDIR%\ %CHECKDATE% -resample %CHECKID% noabort %SOUNDOPT% %BANKOPT% 2>>%MUNGE_LOG% 1>>%SOUNDLOGOUT%
Paste this under that line:

Code: Select all

for /R %%A in (*.asfx) do @echo Munging %%~nA%%~xA & @soundflmunge -platform %4 -banklistinput %%A -bankoutput %MUNGEDIR%\ %CHECKDATE% -resample -checkid noabort %SOUNDOPT% 2>>%MUNGE_LOG% 1>>%SOUNDLOGOUT%
You will also need to do this for the original Data folder (BF2_ModTools\Data)

Next find BF2_ModTools\data\ _BUILD\sound\munge.bat, open that, find this line:

Code: Select all

@for /R %%A in (*.sfx) do @set BANKLIST=!BANKLIST! %%A
Under that, pop this in:

Code: Select all

@for /R %%A in (*.asfx) do @set BANKLIST=!BANKLIST! %%A
Lastly, you'll need to edit an entry in soundmunge.bat inside your DataMOD folder. Find this line:

Code: Select all

@call soundmungedir _BUILD\sound\worlds\snd\%MUNGE_DIR% sound\worlds\snd sound\worlds\snd\%MUNGE_PLATFORM% %MUNGE_PLATFORM% _BUILD _LVL_%MUNGE_PLATFORM%\sound _BUILD\sound snd
Change snd to whatever your base REQ file is (which assumedly is your MOD id)

The last step is calling it in your LUA. Find this:

Code: Select all

    ReadDataFile("sound\\tat.lvl;tat2gcw")
Then add this above

Code: Select all

    ReadDataFile("dc:sound\\MOD.lvl;MODgcw")
One other thing is that it seems the Sound folder won't copy over to the addon folder, at least not when I test munged, so you will have to do that manually.

Munge, test... and if your sounds work (there is a chance that a sound will not play if it's not in the correct format but usually the munger catches that), then that's it!

(NOTE: I am not able to test the munged sounds directly myself since I cannot get munged maps to even run in SWBF2 - however, the steps I have outlined produce a functioning sound file)

Re: [TUTORIAL] Custom SFX implementation

Posted: Sun Sep 20, 2020 11:43 am
by Sporadia
Really like the tutorial. Dumping some extra info here:

1) For higher file size sound effects (when you're using around a 40KHz sample rate, or when you have like minute of audio) use streams, which go in .stm files instead of .asfx files. Surround sound streams go in .st4 files. Then in the .snd file use SoundStreamProperties() instead of SoundProperties(). Ambient sound effects typically use streams. EDIT: Also you'll need an extra OpenAudioStream() line in the mission lua eg

Code: Select all

OpenAudioStream("dc:sound\\MOD.lvl", "name_of_the_stm_file")
OpenAudioStream("dc:sound\\MOD.lvl", "name_of_the_st4_file")
Another thing to note, stream banks (.stm and .st4) go under "str" in the .req file, not "bnk"

2) You can make a stream play in a specific part of the map, by making a soundspace region in Zeroeditor then setting it up in the .snd file. Pretty sure there's a full tutorial on soundspace regions on the sticky.

3) I like Marvel4's improved batch files (see here). They're reliable and they put the meaningful munge error information in text files called configmunge.txt and levelpack.txt, which appear in the sound/worlds/MOD folder. EDIT: This might be a good thread to read if you use them.

4) There's a limit on how many sounds you can load in a mission before it just stops loading any more. If you think you might be close to this, play your mission in BF2ModTools.exe, go in the debug console and type mem. It will show you how much free space you have left. Consoles have a smaller sound limit than PC. EDIT: Worry if you see a small proportion of free space; filling the memory won't reduce the free space to 0; it just starts skipping files.

5) You don't have to hack your new sounds in front of a stock world's sounds using two ReadDataFile() lines. If you want (and this does save space), you can remunge all the stock sounds along with your new sounds into a single sound lvl, then load everything at once from a single ReadDataFile(). This is a bit more tedious and will require copies of some (not many) stock sound effects, the vast majority of which have been ripped by Marth and WULFMAN here

6) In the .asfx, .stm or .st4 files, you can give your wav files aliases so you don't have to write the full wav file name in all your odfs (also useful if you change a wav file later). Here's an example:

Code: Select all

effects\crtr_gamorrean_chatter_01.wav gam_chatter_01
The above wav file is aliased as gam_chatter_01, so you can write that in an odf and it will know what sound to use. The aliases also work in the .snd file. EDIT: You can use -alias to make console specific aliases like this:

Code: Select all

effects\crtr_gamorrean_chatter_01.wav -alias ps2 gam_chatter_01

7) EDIT: .ffx is a special config file for foley, .mus is a special config file for music, and .tsr is a rare config file for mission VO. The music settings are actually split between .mus and .snd.