XML:SNDD

From OniGalore
Revision as of 13:57, 20 February 2023 by Iritscen (talk | contribs) (→‎Step 3: Preparing the OSBD.amb: section link fix)
Jump to navigation Jump to search
SNDD : Sound Data
XML modding tips
  • See HERE to start learning about XML modding.
  • See HERE if you are searching for information on how to handle object coordinates.
  • See HERE for some typical modding errors and their causes.
XML.png
XML

PSUI << Other file types >> StNA

switch to OBD page

Unfinished building-60px.jpg

This page is unfinished. Can you fill in any missing information?
If it is not clear which part of the page is unfinished, ask on the talk page.

Needed: More OSBD .grp / .amb information could be useful, and .imp is completely left out so far.

General information

  • The XML on this page is based on OniSplit v0.9.61.0.
  • In order to make your sounds work on both Windows and Mac, you need to create them twice (one time from a WAV source and another time from an AIFF source).

Source file creation

In Windows, SNDDs use WAV as their internal data format, but on Macs the AIFF format is used. Here are the details:

Windows Mac
.wav
22.05 kHz (mono / stereo) or 44.1 kHz (mono) (see "44.1 kHz" section below)
16-bit uncompressed (PCM) or compressed (MS-ADPCM)
.aif / .aifc / .afc
22.05 kHz (mono / stereo)
compressed (ima4)
Audacity.png

To create suitable files for importing into Oni, you could use Audacity and its ffmpeg Export Library. After you've installed Audacity and the ffmpeg library, go to Preferences > Libraries, click the "Locate…" button and find the installed library file. Open your sound file then go to File > Export… > Export Audio…. Choose to save it as type "Custom FFmpeg Export". Then click the button "Open custom FFmpeg format options", click "wav" in the Formats list, then "adpcm_ms" in the Codecs list. Enter a Sample Rate of 22050. Click "OK" and "Save".

Note: You may find that ima4 AIFF files exported by OniSplit do not play in Audacity, whether you are using it in Windows or on the Mac. This does not mean the files themselves are broken — they will actually play outside of Audacity, e.g. in Windows Media Player. The reason for this remains to be investigated.

44.1 kHz sounds

If you are importing a 44.1 kHz mono sound, you should use <Channels>1</Channels> and <Pitch>2</Pitch> in your .grp file to prevent Oni from playing the sound at half-speed. <Channels>2</Channels> and <Pitch>1</Pitch> will also work for the same source file, but only because Oni interprets this to mean that odd-numbered samples are meant for the left channel and even-numbered samples for the right channel. This is not recommended since it's an unorthodox solution, though the result will probably sound the same in-game.

Mac AIFF creation

If you want to convert sounds into the AIFF format for Macs, the major catch with Audacity is that its batch processing feature does not support AIFF exporting even though it's a part of the underlying ffmpeg program that Audacity uses. To convert a large number of sound files, you can install ffmpeg using your package manager of choice (MacPorts, Homebrew, etc.). Building can take a while, but you can also find pre-built ffmpeg binaries around the Web fairly easily. The basic command you want to use is:

ffmpeg -i input.wav -acodec adpcm_ima_qt -ar 22050 output.aif

The order of arguments is critical: the rate and encoding are being applied to the outputted file, whereas if they came before the input file's name they would be instructions on how to read the input sound. Here is a simple shell script for converting a folder of sounds from WAV to the AIFF format suitable for importing:

#!/bin/sh
IFS=" "
IN_DIR="/path/to/SNDD-wav" OUT_DIR="/path/to/SNDD-aif" for WAV in $(find $IN_DIR | grep ".wav$") do FILENAME=$(basename "$WAV") echo "Converting $FILENAME to IMA-compressed AIFF..." ffmpeg -i "$IN_DIR/$FILENAME" -acodec adpcm_ima_qt -ar 22050 "$OUT_DIR/${FILENAME%.wav}$aif.aif" done

Note the double ".aif" suffix applied to the outputted files….

The .aif suffix

When you are replacing existing Oni sounds, note that all of Oni's SNDD resources possess a ".aif" suffix as part of their actual resource names (yes, even the WAV-encoded sounds in Windows Oni). So if you import them with a name like "SNDDgears.aif", the file suffix gets changed to ".oni" upon import by OniSplit, and you end up with a resource simply titled "SNDDgears" in-game. Oni will look for a sound titled "SNDDgears.aif", and nothing will play. Hence, you want to title an AIFF file "SNDDgears.aif.aif" and a WAV file "SNDDgears.aif.wav" – OniSplit will produce the file "SNDDgears.aif.oni" upon importing it, which in turn provides the resource named "SNDDgears.aif" that Oni desires.

.oni file creation

Via Vago

Installation:

Usage: Oni/AE/Tools/VagoGUI/Vago.exe

  • Target Platform: choose the desired mode
  • Tools > Sound Wizard

Via batch file

SNDD for Windows

onisplit -create output_Win_files input/*.wav
onisplit -create output_Win_files input/*.xml
pause

SNDD for Mac

onisplit -create output_Mac_files input/*.aif
onisplit -create output_Mac_files input/*.aiff
onisplit -create output_Mac_files input/*.afc
onisplit -create output_Mac_files input/*.xml
pause

Via command line

For those who want to do it on their own.

OniSplit

-create output_directory_Mac input_directory/*.aif
-create output_directory_Win input_directory/*.wav
-create output_directory input_directory/*.xml

For simplicity's sake you can give them all the same base name, assuming you have only one sound:

SNDDyourfile.oni
OSBDyourfile.grp.oni
OSBDyourfile.amb.oni

OSBD information

OSBD files are stored globally (in level0_Final). Here's when to use each type of OSBD:

  • OSBD*.amb
    • music (call OSBD from BSL)
    • dialogue (call OSBD from BSL)
    • BINA3RAP <AmbientSound> (action type)
    • BINACJBOSound.xml (area-fixed sounds)
    • ONCC sounds (e.g. taunt)
    • TRIG <ActiveSound>
    • TURR <ActiveSound>
  • OSBD*.imp


Details on music

OSBD_newmusic.amb.oni (The main file — links to the group, intro and ending files)
OSBD_newmusic.grp.oni (Links to the music files)
OSBD_newmusic_in.grp.oni (Links to intro part of the music — optional)
OSBD_newmusic_out.grp.oni (Links to the ending of the music — optional)
SNDD_newmusic1.oni (The individual music files; it's best to break up the music into segments of perhaps 30 secs to a minute each — Oni may crash or become sluggish if you use a single file for the music)

Breaking the main loop of the music into parts allows Oni to more smoothly transition to the ending part when necessary; the amount of time that a track will play cannot be predicted, after all, since players will take varying amounts of time to clear that segment of the level.

The parts of the music between intro and outro are played in a randomized order, probably to add more variety to the playback. Note that .grp files have a <Weight> tag under each <Permutation>. As with TRAC's <Weight> field, this can be used to set the relative probability that a music segment will be picked. Each permutation's weight is figured in relation to the total weight of all segments, so if a piece of music has four permutations and the first one has a <Weight> of 30 and the other three have <Weight>s of 10, the first segment has a 50% chance of being played. This feature is effectively unused in Oni's music, as all music OSBDs assign a weight of 10 to all <Permutation>s.

OSBDfile.imp.xml

What is an impulse? Looking at the XML, it has these special features: <Volume><Angle> / <Volume><MinAttenuation> / <ImpactVelocity> / <MinOcclusion>. This is because impulses are the preferred choice for moving sound sources. A few more facts:

  • They cannot be stopped by BSL once triggered to play.
  • AIs can hear them.
  • The minimum and maximum volume angle seem to be always 360 degrees. These properties might be a development artifact, since sound should propagate through space in all directions, and the area of effect is mostly determined by their volume distance.
Tag Type Description
<ImpulseSound> -
<Group> char[32] OSBDname.grp.oni, file prefix and suffix aren't used
<Priority> flag When are these different flags used?
Low (default for impacts? (ONIE concrete) + shell (ammunition)?)
Normal (AI, animation and impact related?)
High (OSBDtrigger_hit.imp.xml only?)
Highest (OSBDkonoko_gruesome_death.imp.xml only?)
<Volume> -
<Distance> -
<Min> float From the sound's origin point out to Min radius (distance), the sound volume is equally strong.
<Max> float Between Min and Max radius (distance) the sound volume decreases; a greater distance than Max makes the sound inaudible.
<Angle> - Spatial angle? Does this work like the <Distance> tag?
<Min> -
<Max> -
<AlternateImpulse> -
<Treshold> int32
<Impulse> char[32] OSBDname.imp.oni, file prefix and suffix aren't used
<ImpactVelocity> float
<MinOcclusion> float

OSBDfile.amb.xml

In case you want to create a simple sound file, you can basically copy the examples below and change the portions marked in red.

OSBDfile.grp.xml, OSBDfile.amb.xml, BINACJBOSound.xml are showing the markup from the Nyan Cat mod.
Tag Type Description
<AmbientSound> -
<Priority> flag
Low
Normal
High
Highest
<Flags> flag
InterruptTracksOnStop — this flag must be set if you want to use the BSL command sound_music_stop
PlayOnce
CanPan
<DetailTrackProperties> -
<SphereRadius> float
<ElapsedTime> -
<Min> float
<Max> float
<Volume> -
<Distance> -
<Min> float
<Max> float
<DetailTrack> char[32] OSBDname.grp.oni, file prefix and suffix aren't used
<BaseTrack1> char[32] OSBDname.grp.oni, file prefix and suffix aren't used
<BaseTrack2> char[32] OSBDname.grp.oni, file prefix and suffix aren't used
<InSound> char[32] OSBDname.grp.oni, file prefix and suffix aren't used
<OutSound> char[32] OSBDname.grp.oni, file prefix and suffix aren't used
<Treshold> int32
<MinOcclusion> float

An example:

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <AmbientSound>
       <Priority>Normal</Priority>
       <Flags>InterruptTracksOnStop</Flags>
       <DetailTrackProperties>
           <SphereRadius>10</SphereRadius>
           <ElapsedTime>
               <Min>0</Min>
               <Max>0</Max>
           </ElapsedTime>
       </DetailTrackProperties>
       <Volume>
           <Distance>
               <Min>10</Min>
               <Max>50</Max>
           </Distance>
       </Volume>
       <DetailTrack></DetailTrack>
       <BaseTrack1>nyan</BaseTrack1>
       <BaseTrack2></BaseTrack2>
       <InSound></InSound>
       <OutSound></OutSound>
       <Treshold>3</Treshold>
       <MinOcclusion>0</MinOcclusion>
   </AmbientSound>
</Oni>

OSBDfile.grp.xml

Tag Type Description
<SoundGroup> -
<Volume> float
<Pitch> float
<Flags> flag PreventRepeat - Oni will play different permutations of the sound, if there is more than one permutation
<NumberOfChannels> int32 Here you tell Oni if your sound file is mono or stereo.
22.05 kHz, mono 22.05 kHz, stereo 44.1 kHz, mono (Windows-only)
NumberOfChannels 1 2 1
<Permutations> - int32 array for the <Permutation> tags
<Permutation> -
<Weight> int32
<Volume> -
<Min> float
<Max> float
<Pitch> -
<Min> float
<Max> float
<Sound> char[32] SNDDname.oni, file prefix and suffix aren't used

An example:

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <SoundGroup>
       <Volume>1</Volume>
       <Pitch>1</Pitch>
       <Flags>PreventRepeat</Flags>
       <NumberOfChannels>2</NumberOfChannels>
       <Permutations>
           <Permutation>
               <Weight>10</Weight>
               <Volume>
                   <Min>1</Min>
                   <Max>1</Max>
               </Volume>
               <Pitch>
                   <Min>1</Min>
                   <Max>1</Max>
               </Pitch>
               <Sound>nyan</Sound>
           </Permutation>
       </Permutations>
   </SoundGroup>
</Oni>

BINACJBOSound.xml

This is for sounds fixed to a certain area.

Tag Type Description
<Objects> - This tag marks the file as BINACJBO.
<SNDG Id="..."> integer This tag marks the file as a sound list. The ID doesn't matter at import time.
<Header> -
<Flags> flag You can ignore these flags, as they are defunct:
None
Locked
PlacedInGame
Temporary
Gunk
<Position> float x3 Here you tell Oni where you want the sound to be located (see HERE for help with that).
<Rotation> float x3 Not really important.
<OSD> -
<Class> char[32] SNDDname.amb.oni, file prefix and suffix aren't used
<Sphere> -
<MinRadius> float From the point of the sound's origin (<Position>) out to Min radius, the sound volume is equally strong.
<MaxRadius> float Between Min and Max radius, the sound volume will decrease; greater distance than Max makes the sound inaudible.
<Box> - You can use this alternative to <Sphere> if you want to limit a sound to a specific room.
<Min> float x3 X1 Y1 Z1
<Max> float x3 X2 Y2 Z2

An example:

       <SNDG Id="8805">
           <Header>
               <Flags></Flags>
               <Position>125 10 2231</Position>
               <Rotation>0 0 0</Rotation>
           </Header>
           <OSD>
               <Class>nyan</Class>
               <Sphere>
                   <MinRadius>7</MinRadius>
                   <MaxRadius>21</MaxRadius>
               </Sphere>
               <Volume>0.75</Volume>
               <Pitch>1</Pitch>
           </OSD>
       </SNDG>

Sound-related BSL commands

sound_music_stop soundtrack — can only be used if .amb file has the InterruptTracksOnStop flag
sound_music_stop soundtrack 1 — music drops to zero volume over 1 second

You need a custom function if you want to fade out a soundtrack over more than one second. It could look like this:

var float x = 1;
var int y = 0;

# Don't test this function with the console or the function might stop working after 4 cycles
func fade_music
{
 	# An 'if' statement with float values doesn't seem to work, therefore the int y
	y = y + 1
	x = x - .01
	sound_music_volume (soundtrack, x)
	sleep 10
 	if (y eq 99)
	{
		# dmsg "stop music"
		sound_music_stop soundtrack
	}
	if (y < 99)
	{
		fork fade_music
	}
}

OCF thread about making new music

See here.

How to register sounds to characters

...such as the sounds of heavy attacks and taunts.

Let's see how sounds become picked up:
Schemata:

TRAM -> ONCC -> OSBD.amb -> OSBD.grp -> SNDD

Explanation:

  • The character performs a move/attack where the TRAM file holds a sound ID (<Vocalization>).
  • A link (OSBD.amb name) in the ONCC file will be looked up based on the sound ID. Note that the ONCC file has also a probability value that decides whether a sound will be played or not.
  • The game engine looks into OSBD.amb and follows the link into OSBD.grp.
  • OSBD.grp can hold multiple links to SNDD files. That's why Konoko can have multiple taunt sounds.

Step 1: Preparing the TRAM

Search for <Vocalization> in the TRAM file and give it an ID according to the following table.

TRAM <Vocalization> IDs refer to these ONCC SoundConstants tags
ID link to ...
0 <TauntProbability> — taunt(s)
1 <AlertProbability> — AI being surprised by a sound
2 <StartleProbability> — AI being surprised by an enemy
3 <CheckBodyProbability> — AI death taunt, played when enemy dies
4 <PursueProbability> — Play this sound when AI loses track of enemy
5 <CoverProbability> — Play this sounds when afraid (e.g. "Don't hurt me!")
6 <SuperPunchSound> — Sound of ######punch_heavy.oni; super punches don't have sound IDs
7 <SuperKickSound> — Sound of ######kick_heavy.oni; super kicks don't have sound IDs
8 <Super3Sound> — AI specialty; Mukade uses it for his Devil Star attack (TRAMNINCOMfireball)
9 <Super4Sound> - unused

Step 2: Preparing the ONCC

Search for <SoundConstants> and set a value between 0 and 100. 100 means "always play this sound".

Let's look at Konoko's settings, with a focus on her taunt sound. In ONCCkonoko_generic.xml, we see this:

           <SoundConstants>
               <TauntProbability>100</TauntProbability>
               <AlertProbability>0</AlertProbability>
               <StartleProbability>0</StartleProbability>
               <CheckBodyProbability>0</CheckBodyProbability>
               <PursueProbability>0</PursueProbability>
               <CoverProbability>0</CoverProbability>
               <SuperPunchProbability>100</SuperPunchProbability>
               <SuperKickProbability>100</SuperKickProbability>
               <Super3Probability>0</Super3Probability>
               <Super4Probability>0</Super4Probability>
               <TauntSound>c17_99_28konoko</TauntSound>
               <AlertSound></AlertSound>
               <StartleSound></StartleSound>
               <CheckBodySound></CheckBodySound>
               <PursueSound></PursueSound>
               <CoverSound></CoverSound>
               <SuperPunchSound>c18_79_14konoko</SuperPunchSound>
               <SuperKickSound>c18_79_15konoko</SuperKickSound>
               <Super3Sound></Super3Sound>
               <Super4Sound></Super4Sound>
           </SoundConstants>

Step 3: Preparing the OSBD.amb

Do you see the <BaseTrack1> tag? In this case it holds the link OSBDc17_99_28konoko.grp.oni. (See the "BaseTrack2" section below for info on that tag.)

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <AmbientSound>
       <Priority>Highest</Priority>
       <Flags>InterruptTracksOnStop PlayOnce</Flags>
       <DetailTrackProperties>
           <SphereRadius>10</SphereRadius>
           <ElapsedTime>
               <Min>0</Min>
               <Max>0</Max>
           </ElapsedTime>
       </DetailTrackProperties>
       <Volume>
           <Distance>
               <Min>10</Min>
               <Max>50</Max>
           </Distance>
       </Volume>
       <DetailTrack></DetailTrack>
       <BaseTrack1>c17_99_28konoko</BaseTrack1>
       <BaseTrack2></BaseTrack2>
       <InSound></InSound>
       <OutSound></OutSound>
       <Treshold>3</Treshold>
       <MinOcclusion>0</MinOcclusion>
   </AmbientSound>
</Oni>

Step 4: Preparing the OSBD.grp

Note that <NumberOfChannels> occurs once at the top level, meaning that all the SNDD files must have the same number of channels.

22.05 kHz, mono 22.05 kHz, stereo 44.1 kHz, mono (Windows-only)
NumberOfChannels 1 2 1

(It's possible to speed up sounds with <Pitch>, e.g. the Fury's taunt is sped up with 1.14 to "brighten" the voice. But in most cases you probably want to keep it as "1".)

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <SoundGroup>
       <Volume>1</Volume>
       <Pitch>1</Pitch>
       <Flags>PreventRepeat</Flags>
       <NumberOfChannels>1</NumberOfChannels>
       <Permutations>
           <Permutation>
               <Weight>10</Weight>
               <Volume>
                   <Min>1</Min>
                   <Max>1</Max>
               </Volume>
               <Pitch>
                   <Min>1</Min>
                   <Max>1</Max>
               </Pitch>
               <Sound>c17_99_28konoko.aif</Sound>
           </Permutation>
           <Permutation>
               <Weight>10</Weight>
               <Volume>
                   <Min>1</Min>
                   <Max>1</Max>
               </Volume>
               <Pitch>
                   <Min>1</Min>
                   <Max>1</Max>
               </Pitch>
               <Sound>c17_99_29konoko.aif</Sound>
           </Permutation>
           [...]
       </Permutations>
   </SoundGroup>
</Oni>

As you can see, Konoko has multiple sounds to choose from.

  • SNDDc17_99_28konoko.aif.oni ("You're gonna get beat by a girl!")
  • SNDDc17_99_29konoko.aif.oni ("Ready to lose?") (You can play sounds in Simple OniSplit GUI (Windows only).
  • [...]

"aif" is here part of the name, as explained under the section "The .aif suffix" above.

Permutations in .grp files are the reason why Konoko has multiple sounds that can play during the same taunt animation.

Step 5: Everything else that's left

  • Create your SNDD if you haven't yet.
  • Put your files into a mod package.
  • Test your stuff in-game!

Using BaseTrack2 to mix music and sound effects

You can place a sound in the OSBD.amb's <BaseTrack2> and it will play in parallel with <BaseTrack1>.

Mixing music tracks

Oni uses this feature in order to layer one music track over another, but only in one functioning OSBD: OSBDmus_xtr2, the sorrowful string piece which plays in the Shinatama farewell scene in CHAPTER 08 . AN INNOCENT LIFE and at the conclusion of Hasegawa's monologue at the start of CHAPTER 11 . DREAM DIVER. The OSBD's use of <BaseTrack1> and <BaseTrack2> leads to the high string note SNDDmus_xtr2hi.aif playing continuously over the melody in SNDDmus_xtr2_[1-6].aif.

The benefit of this live-mix approach is that you can also use one of the tracks on its own in other places, or in combination with a different second track; for instance, OSBDmus_choral1 calls for SNDDmus_xtr2_[1-6].aif to be mixed with SNDDmus_choral1.aif (except that SNDDmus_choral1.aif doesn't exist and the OSBD is never called…).

Note that when mixing two tracks in this way, both tracks will have to share the same <InSound> and <OutSound>. For this reason, SNDDmus_xtr2endmx.aif was created to end the mix of SNDDmus_xtr2hi.aif and SNDDmus_xtr2_[1-6].aif, as opposed to SNDDmus_xtr2_end.aif which provides an end for only SNDDmus_xtr2_[1-6].aif when playing on its own.

There is no requirement that the <Sound>s in BaseTrack1's .grp file have the same length as BaseTrack2's; each base track will keep looping its specified <Sound>s independently until the music ends. However, if the two tracks do not have segments of the same length (or at least, if one track's segments do not evenly divide into the other's), it might be very noticeable when one base track cleanly transitions to the shared <OutSound> and the other base track cuts abruptly to it. OSBDmus_xtr2 showcases a solution to this: mixing an "unstructured" track with a "structured" track; because SNDDmus_xtr2hi.aif is a continuous note, it doesn't matter that it's 5 seconds long and the SNDDmus_xtr2_[1-6].aif segments are 14-24 seconds long; the OSBD can cut to its outro at the end of any SNDDmus_xtr2_*.aif segment without audible disruption in SNDDmus_xtr2hi.aif.

A second solution to the problem of mismatched lengths is simply to fade out the piece using sound_music_volume instead of relying on the base tracks to line up going into the outro. Oni does this with OSBDmus_xtr2 at the end of the Shinatama cutscene in order to cross-fade into atm_cl10, though it does rely on the .amb's <OutSound> to bring the music to a graceful close in the Dream Lab cutscene by calling sound_music_stop.

Layering ambience

The, uh, room with the oval things.

Another use of <BaseTrack2> in Oni is for ambient environmental sound; an example is found in Musashi Manufacturing Plant, where OSBDMP_ovalthings is used to play SNDDtransroom1lp2.aif on top of SNDDac3lp[1-3].aif when you get close to each of the, uh, oval things.

Doubling a sound effect

<BaseTrack2> is even used in OSBDbarab_recharge to beef up Barabas' recharging effect by playing his recharge sound twice at the same time.