XML:SNDD
SNDD : Sound Data | ||
---|---|---|
XML
PSUI << Other file types >> TRAC |
This page is unfinished. Can you fill in any missing information? |
More OSBD .grp / .amb information could be useful and .imp is completely left out so far.
The xml code on this page is based on onisplit v0.9.61.0 |
- How do I get sounds into Oni?
In order to make your sounds available on both sides - pc and mac - you need to create them twice (one time from a wav source and another time from an aif/aifc/afc 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 |
---|---|
|
|
To create suitable files for importing into Oni using a GUI program, you could use Audacity and its ffmpeg Export Library. After you've installed Audacity and the ffmpeg library, go to Edit > Preferences... > Libraries, click the Locate... button and find the installed library file. Open your sound file then go to File > Export... > Save As: yourfile.wav; Format: Custom FFmpeg Export; Options... > wav; pcm_s16le; Sample Rate: 22050; OK and save the file (adpcm_ms doesn't work as of Audacity 1.3 Beta).
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
Note that 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. If you are replacing existing Oni sounds, this is necessary due to Oni's sound resources possessing 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 be looking for a sound titled "SNDDgears.aif", and won't find it. Hence, we title the AIFF file "SNDDgears.aif.aif" so that OniSplit yields "SNDDgears.aif.oni" upon importing, which in turn produces the resource named "SNDDgears.aif" that Oni desires.
If you're using Windows, you may find out that your newly-converted ima4 AIFF files will not play. This does not mean the files themselves are broken — they will actually play on Macs, but not in Windows, despite having been created in Windows. The reason for this remains to be investigated.
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_PC_files input/*.wav onisplit -create output_PC_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_PC input_directory/*.wav
- -create output_directory input_directory/*.xml
For fast xml text changes and naming give them all yourfile as name if you have only one sound:
- SNDDyourfile.oni
- OSBDyourfile.grp.oni
- OSBDyourfile.amb.oni
OSBD information
OSBD files are stored globally (in level0_Final).
when use what
- OSBD*.amb
- music (call OSBD from BSL)
- sound dialogs (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 (Contain 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 - Its 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 -- EdT) (What are the limits? --Paradox-01)
Music parts between intro and outro are played in a random order.
Why would Bungie have wanted random parts? A fair guess can be made with the songs' purpose: giving fights more atmosphere. But every player finishes the enemies in a different time: one wins in 2 minutes, the other in 6 minutes, etc. So 1) modular parts seem perfect to delay the outro part when it's necessary and 2) a random order adds more variety (making the loop less boring).
grp files have a <Weight> tag under <Permutation>. Permutation should have something to do how music parts get repeated. However, it's not clear what influence <Weight> has on the repetitions. Is it like TRAC's <Weight> used for probability?
OSBDfile.imp.xml
What is an impulse? Looking at the XML it seems unique in its spacial features: <Volume><Angle> / <Volume><MinAttenuation> / <ImpactVelocity> / <MinOcclusion>
Hypothesis:
- Impulses are preferably used by moving sources.
- They cannot be stopped by BSL once triggered to play.
- AI can hear them
- Minimum and maximum volume angle seems to be always 360 degrees. Maybe artifact properties since sound should propagate through space in all directions and area of effect is mostly made by their volume distance.
- File structure is always the same.
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?
|
<Volume> | - | |
<Distance> | - | |
<Min> | float | between min radius (distance) and sound origin the sound volume is equally strong |
<Max> | float | between max and min radius (distance) there's a transition of the sound volume, greater distance than max makes the sound unhearable |
<Angle> | - | Space 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 code and change the red marked stuff in the examples.
- OSBDfile.grp.xml, OSBDfile.amb.xml, BINACJBOSound.xml are showing the code from the nyan cat mod.
tag | type | description |
<AmbientSound> | - | |
<Priority> | flag |
|
<Flags> | flag |
|
<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 - forces to play different sounds if there are more than one permutations | ||||||||
<NumberOfChannels> | int32 | Here you tell Oni if your sound file is mono or stereo. Windows' 44.1 kHz is an exception.
| ||||||||
<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 area-fixed sounds.
tag | type | description |
<Objects> | - | This tag marks the file as BINACJBO. |
<SNDG Id="..."> | integer | This tag marks the file as a sound list. ID doesn't matter at import time. |
<Header> | - | |
<Flags> | flag | Ignore it. Those flags were used in the past.
|
<Position> | float x3 | here you tell Oni where you want the sound to be located |
<Rotation> | float x3 | Not really important. |
<OSD> | - | |
<Class> | char[32] | SNDDname.amb.oni, file prefix and suffix aren't used |
<Sphere> | - | |
<MinRadius> | float | between min radius and sound origin (<Position>) the sound volume is equally strong |
<MaxRadius> | float | between max and min radius there is a transition of the sound volume, greater distance than max makes the sound unhearable |
<Box> | - | alternative to <Sphere>, a box would be a better choice 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_music_stop soundtrack - can only be used if .amb file has the InterruptTracksOnStop flag
sound_music_stop soundtrack 1 - soundtrack stop after 1 second while it gets quieter
You need a custom function if you want to fade out a soundtrack over more than one seconds. It could look like this:
var float x = 1; var int y = 0; # don't test this function with the console, it could happen that the function stops working after 4 cycles func fade_music { # 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 new music
How to register sounds to characters
... such as 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 whereby the TRAM file holds a sound ID (<Vocalization>).
- A link (OSBD.amb name) in ONCC file becomes looked up based on the sound ID.
Note that the ONCC file has also a probability value that decides whether a sound becomes 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 only?) death taunt (when enemy / player dies) |
4 | <PursueProbability> - sound when character lost track of enemy |
5 | <CoverProbability> - being afraid (E.g. "Dont'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 use 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 will make the engine play a sound always the taunt animation is played.
Let's compare with Konoko (and in the following steps especially the with her taunt files.) In ONCCkonoko_generic.xml it looks like 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
You basically need such a file...
Do you see the <BaseTrack1> tag? In this case it holds the link OSBDc17_99_28konoko.grp.oni.
<?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
Since <NumberOfChannels> is only once presented all the SNDD files must have the same number of channels.
22.05 kHz, mono | 22.05 kHz, stereo | 44.1 kHz, mono (PC-only) | |
---|---|---|---|
NumberOfChannels | 1 | 2 | 2 |
(It's possible to speed up sounds with <Pitch>. E.g. Fury's taunt is speeded up by 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 uses multiple sounds.
- SNDDc17_99_28konoko.aif.oni ("You're gonna get beat(en) by a girl!")
- SNDDc17_99_29konoko.aif.oni ("Ready to lose?") (You can play sounds with (PC) onisplit GUI or (Mac) AETools.
- [...]
"aif" is here part of the name, don't get bothered by it.
Permutations in .grp files are the reason why Konoko has multiple sounds through one and the same taunt animation.
step 5: everything else what's left
- create your SNDD if you haven't yet
- put your files into a package
- test your stuff in-game