XML:SNDD: Difference between revisions

From OniGalore
Jump to navigation Jump to search
mNo edit summary
m (→‎Scripting music: tweaked the formatting and wording for clarity)
 
(40 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{XML_File_Header | type=SNDD | prev=PSUI | next=TRAC | name=Sound Data }}
{{XML_File_Header | prev=PSUI | type=SNDD | next=StNA | name=Sound Data}}
{{finish}}
{| border=0 cellspacing=20 cellpadding=0 style="margin-left:auto; margin-right:auto"
| 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'''
{{TOClimit|2}}
|}
 
__TOC__
 
 
: '''''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).'''


==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 the .oni files twice (one time from a WAV source and another time from an AIFF source). The AIFF .oni files will go in the mac_only/ folder and the WAV .oni files will go in the win_only/ folder as described on [[Making a mod package]].


==Source file creation==
==Source file creation==
These are the properties of the source files you want to create.
In Windows, SNDDs use WAV as their internal data format, but on Macs the AIFF format is used. Here are the details:


{|class="wikitable" width="100%"
{|class="wikitable" width="100%"
! PC retail
! Windows
! MAC
! Mac
|-
|-
|width=50% valign=top|
|width=50% valign=top|
: .wav
: .wav
: 22.05KHz (mono / stereo) or 44.1KHz (mono)
: '''22.05 kHz (mono / stereo)''' or 44.1 kHz (mono) (see "44.1 kHz" section below)
: 16-bit uncompressed (PCM) or compressed (MS-ADPCM)
: 16-bit uncompressed ('''PCM''') or compressed ('''MS-ADPCM''')
 
|valign=top|
|valign=top|
: .aif / .aifc / .afc
: .aif / .aifc / .afc
: 22.05KHz (mono / stereo)
: '''22.05 kHz (mono / stereo)'''
: compressed (ima4)
: compressed ('''ima4''')
|}
|}
[[Image:Audacity.png|right|300px]]
To create suitable files for importing into Oni, you could use [https://www.audacityteam.org/download/ Audacity] and its [https://manual.audacityteam.org/man/faq_installation_and_plug_ins.html#How_do_I_download_and_install_the_FFmpeg_Import.2FExport_Library.3F 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.


To create suitable files you could use audacity and its ffmpeg Export Library.
===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.
{|class="wikitable" width="100%"
!width=33%|
!PC version
!Mac version
|-
|width=33%|audacity
|[http://audacity.sourceforge.net/download/beta_windows#recdown link]
|[http://audacity.sourceforge.net/download/beta_mac#recdown link]
|-
|ffmpeg Export Library
|[http://manual.audacityteam.org/index.php?title=FAQ:Installation_and_Plug-Ins#installffmpeg link]
|[http://manual.audacityteam.org/index.php?title=FAQ:Installation_and_Plug-Ins#installffmpeg link]
|-
|mirror links
|[http://dl.dropbox.com/u/139715/OniGalore/audacity%2BFFmpeg_library_for_PC.zip audacity (1.3 beta) + library]
|[http://dl.dropbox.com/u/139715/OniGalore/audacity%2BFFmpeg_library_for_MAC.zip audacity (1.3 beta) + library]
|-
|valign=top|installation
|colspan=2|After you installed Audacity and the library goto '''Edit > Preferences... > Libraries''' - click on Locate... button and find the installed library file.
|-
|valign=top|source file creation
|'''wav''' for PC oni file
 


Open your sound file then goto File > Export... > Save As: '''''yourfile.<font color="#CC0000">wav</font>'''''; Format: Custom FFmpeg Export; Options... > wav; '''pcm_s16le'''; Sample Rate: 22050; OK and save the file<br>(adpcm_ms doesn't work with Audacity 1.3 Beta)
===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:


[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/Audacity_wav.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/Audacity_wav_tn.png]
ffmpeg -i input.wav -acodec adpcm_ima_qt -ar 22050 output.aif
|'''aif''' for Mac oni file


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 Unix shell script for converting a folder of sounds from WAV to the AIFF format suitable for importing. Save the script as "convert_sounds.sh", make sure that IN_DIR and OUT_DIR are set to the correct values, and run the script in Terminal with the command "sh convert_sounds.sh".


Open your sound file then goto File > Export... > Save As: '''''yourfile.<font color="#CC0000">aif</font>'''''; Format: Custom FFmpeg Export; Options... > aiff; adpcm_ima_qt; Sample Rate: 22050; OK and save the file
#!/bin/sh<br />
IFS="
"<br />
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


[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/Audacity.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/Audacity_tn.png]
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 <u>actual resource names</u> (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. Existing resources in Oni link to a sound titled "SNDDgears.aif", thus nothing will play. If you supply an AIFF file called "SNDDgears.aif.aif" or a WAV file called "SNDDgears.aif.wav", OniSplit will create the file "SNDDgears.aif.oni" and Oni will find the resource named "SNDDgears.aif" that it's seeking.


==Oni file creation==
==.oni file creation==
===via Vago===
===Via Vago===
Installation:
Installation:
* Oni/AE/[[Anniversary_Edition/Installer#Tools|AEInstaller2.exe > Tools > Manage Tools]]
* In Oni/AE/AEInstaller2.exe, choose Tools > [[Anniversary Edition/Installer#Tools|Manage Tools]].


Usage: Oni/AE/Tools/VagoGUI/[[Vago_%28tool%29|Vago.exe]]
Usage:
* Target Platform: choose the desired mode
* Open Oni/AE/Tools/VagoGUI/[[Vago (tool)|Vago.exe]]
* Target Platform > choose the desired target
* Tools > Sound Wizard
* Tools > Sound Wizard


 
===Via command line===
===via batch file===
Get them [http://dl.dropbox.com/u/139715/OniGalore/sound_creation_via_batch_files.zip HERE], includes a short readme.
 
 
===via command line===
For those who want to do it on their own.
For those who want to do it on their own.


onisplit
: OniSplit.exe -create output_directory_'''Mac''' input_directory/'''*.aif'''
: -create output_directory_'''MAC''' input_directory/'''*.aif'''
: OniSplit.exe -create output_directory_'''Win''' input_directory/'''*.wav'''
: -create output_directory_'''PC''' input_directory/'''*.wav'''
: OniSplit.exe -create output_directory input_directory/*.xml
: -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:
: <font color=#AAAAAA>SNDD</font>yourfile<font color=#AAAAAA>.oni</font>
: <font color=#AAAAAA>OSBD</font>yourfile<font color=#AAAAAA>'''.grp'''.oni</font>
: <font color=#AAAAAA>OSBD</font>yourfile<font color=#AAAAAA>'''.amb'''.oni</font>
 


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


* OSBD*.'''amb'''
* OSBD*.'''amb'''
** music (call OSBD from BSL)
** music (call the OSBD from BSL)
** sound dialogs (call OSBD from BSL)
** dialogue (call the OSBD from BSL)
** [[XML:BINA/PAR3|BINA3RAP]] <AmbientSound> (action type)
** [[XML:BINA/PAR3|BINA3RAP]] <AmbientSound> (action type)
** [[#BINACJBOSound.xml|BINACJBOSound.xml]] (area-fixed sounds)
** [[#BINACJBOSound.xml|BINACJBOSound.xml]] (area-fixed sounds)
** [[XML:ONCC|ONCC]] sounds (e.g. taunt)
** [[XML:TRIG|TRIG]] <ActiveSound>
** [[XML:TRIG|TRIG]] <ActiveSound>
** [[XML:TURR|TURR]] <ActiveSound>
** [[XML:TURR|TURR]] <ActiveSound>
Line 115: Line 89:
** [[XML:BINA/ONIE|BINA/ONIE]] <Sound><Name>
** [[XML:BINA/ONIE|BINA/ONIE]] <Sound><Name>
** [[XML:BINA/SABD|BINADBAS]] <Sound>
** [[XML:BINA/SABD|BINADBAS]] <Sound>
** [[XML:ONCC|ONCC]] hurt sounds (also indirectly with chr_pain) and <SoundConstants>
** [[XML:ONCC|ONCC]] <HurtSoundConstants>, BSL chr_pain
** [[XML:ONWC|ONWC]] <EmptyWeaponSound>
** [[XML:ONWC|ONWC]] <EmptyWeaponSound>
** [[XML:TRAM|TRAM]] <Sound><Name>
** [[XML:TRAM|TRAM]] <Sound><Name>
** [[XML:TRIG|TRIG]] <TriggerSound>
** [[XML:TRIG|TRIG]] <TriggerSound>


For simplicity's sake you should follow Oni's example and give all the files related to one sound the same base name:
: <font color=#AAAAAA>SNDD</font>yourfile<font color=#AAAAAA>.oni</font>
: <font color=#AAAAAA>OSBD</font>yourfile<font color=#AAAAAA>'''.grp'''.oni</font>
: <font color=#AAAAAA>OSBD</font>yourfile<font color=#AAAAAA>'''.amb'''.oni</font>


'''details on music'''
===Music .ambs===
: OSBD_newmusic.amb.oni (The main file, links to the group, intro and ending files)
: 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.grp.oni (links to the music files)
: OSBD_newmusic_in.grp.oni (Links to intro part of the music - Optional)
: 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)
: 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? --[[User:Paradox-01|Paradox-01]])
: SNDD_newmusic1.oni, SNDD_newmusic2.oni… (the individual music files)


Music parts between intro and outro are played in a random order.
Breaking the main loop of the music into parts allows Oni to more quickly transition to the ending part when the music is commanded to stop playing. The shorter segments you can break the music into, the better – both for the sake of reaching the outro sooner, and because long segments can be taxing on the game. Oni's music averages 9 seconds per segment, and a segment rarely goes above 20 seconds.


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).
The parts of the music between intro and outro are played in a randomized order 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, however this feature is effectively unused in Oni's music as all music segments have a <Weight> of 10.


grp files have a <Weight> tag under <Permutation>. [[wikipedia: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?
For information on permutations, see {{SectionLink||Permutations}}. For information on layering two music tracks with BaseTrack2, see {{SectionLink||Using BaseTrack2 to layer sound}}.


===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.
{| class="wikitable" width=100%
|width=120px| '''Tag'''
|width=100px| '''Type'''
| '''Description'''
|-
| <ImpulseSound>
| -
|
|-
| <Group>
| char[32]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used.
|-
|valign="top"| <Priority>
|valign="top"| 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]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.imp.oni</font>, file prefix and suffix aren't used.
|-
| <ImpactVelocity>
| float
|
|-
| <MinOcclusion>
| float
|
|}


===OSBDfile.amb.xml===
===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.  
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 code from the [http://mods.oni2.net/node/177 '''nyan cat mod'''].
: OSBDfile.grp.xml, OSBDfile.amb.xml, BINACJBOSound.xml are showing the markup from the [http://mods.oni2.net/node/177 '''Nyan Cat mod'''].
 


{| class="wikitable" width=100%
{| class="wikitable" width=100%
|width=120px| '''tag'''
|width=120px| '''Tag'''
|width=100px| '''type'''
|width=100px| '''Type'''
| '''description'''
| '''Description'''
|-
|-
| <AmbientSound>
| <AmbientSound>
| -
| parent tag
|
|
|-
|-
Line 160: Line 212:
|valign="top"| flag
|valign="top"| flag
|
|
: InterruptTracksOnStop - this flag must be set if you want to use BSL command ''sound_music_stop''
: InterruptTracksOnStop — Don't wait for current .grp element to finish before stopping sound; used for dialogue, a few sound effects, some music pieces. A music piece with this flag will immediately cut to its outro when <tt>sound_music_stop</tt> is called on it; see {{SectionLink||Scripting music}} for details.
: PlayOnce
: PlayOnce – Don't loop this sound; mostly applied to dialogue. A few sound effects have it as well (was this intentional?).
: CanPan
: CanPan
|-
|-
| <DetailTrackProperties>
| <DetailTrackProperties>
| -
| parent tag
|
|
|-
|-
| <SphereRadius>
| <SphereRadius>
| float
| float
|
| Size of area within which detail sounds can be heard.
|-
|-
| <ElapsedTime>
| <ElapsedTime>
| -
| parent tag
|
|
|-
|-
| <Min>
| <Min>
| float
| float
|
| The smallest amount of time that can elapse before playing another detail track sound.
|-
|-
| <Max>
| <Max>
| float
| float
|
| The longest we can go without playing a detail track sound.
|-
|-
| <Volume>
| <Volume>
| -
| parent tag
|
|
|-
|-
| <Distance>
| <Distance>
| -
| parent tag
|
|
|-
|-
| <Min>
| <Min>
| float
| float
|
| Near distance at which the sound rises to its maximum volume.
|-
|-
| <Max>
| <Max>
| float
| float
|
| Far distance at which the sound falls to its minimum volume.
|-
|-
| <DetailTrack>
| <DetailTrack>
| char[32]
| char[32]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used. See {{SectionLink||Using DetailTrack to add ambience}} for explanation.
|-
|-
| '''<BaseTrack1>'''
| '''<BaseTrack1>'''
| char[32]
| char[32]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used.
|-
|-
| <BaseTrack2>
| <BaseTrack2>
| char[32]
| char[32]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used. See {{SectionLink||Using BaseTrack2 to layer sound}} for explanation.
|-
|-
| <InSound>
| <InSound>
| char[32]
| char[32]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used.
|-
|-
| <OutSound>
| <OutSound>
| char[32]
| char[32]
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>OSBD</font>name<font color=#AAAAAA>.grp.oni</font>, file prefix and suffix aren't used.
|-
|-
| <Treshold>
| <Treshold>
Line 226: Line 278:
| <MinOcclusion>
| <MinOcclusion>
| float
| float
|
| This is the lowest volume (0.0-1.0) that a sound can have, even when the path between the sound-emitting area and the player is fully occluded by the environment. The name is misleading but should be thought of as "minimum (floor) value when calculating the volume of an occluded sound".
|}
|}


An example:
An example:
Line 259: Line 310:
     </AmbientSound>
     </AmbientSound>
  </Oni>
  </Oni>


===OSBDfile.grp.xml===
===OSBDfile.grp.xml===
{| class="wikitable" width=100%
{| class="wikitable" width=100%
|width=120px| '''tag'''
|width=120px| '''Tag'''
|width=100px| '''type'''
|width=100px| '''Type'''
| '''description'''
| '''Description'''
|-
|-
| <SoundGroup>
| <SoundGroup>
Line 281: Line 331:
| <Flags>
| <Flags>
| flag
| flag
| PreventRepeat - forces to play different sounds if there are more than one permutations
| PreventRepeat - Do not play the same permutation twice in a row, if there is more than one permutation.
|-
|-
|valign="top"| <NumberOfChannels>
|valign="top"| <NumberOfChannels>
|valign="top"| int32
|valign="top"| int32
| Here you tell Oni if your sound file is mono or stereo. Windows' 44.1 kHz is an exception.
|  
 
{|class="wikitable" width="100%"
{|class="wikitable" width="100%"
!
!
! 22.05 kHz, mono
! 22.05 kHz, mono
! 22.05 kHz, stereo
! 22.05 kHz, stereo
! 44.1 kHz, mono '''(PC-only)'''
! 44.1 kHz, mono '''(Windows-only)'''
|-
|-
|align="center"| NumberOfChannels
|align="center"| NumberOfChannels
|align="center"| 1
|align="center"| 1
|align="center"| 2
|align="center"| 2
|align="center"| '''2'''
|align="center"| '''1''' (with Pitch of 2)
|}
|}
;consequences of wrong imports:
: if grp's <NumberOfChannels> is 1 and sound file is 22.05 kHz, stereo then the sound won't get played
: if grp's <NumberOfChannels> is 1 and sound file is 44.1 kHz, mono then the sound will play distorted


|-
|-
| <Permutations>
| <Permutations>
| -
| -
| int32 array for the <Permutation> tags.
| int32 array for the <Permutation> tags; see {{SectionLink||Permutations}}.
|-
|-
| <Permutation>
| <Permutation>
Line 342: Line 387:
| <Sound>
| <Sound>
| char[32]
| char[32]
| <font color=#AAAAAA>SNDD</font>name<font color=#AAAAAA>.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>SNDD</font>name<font color=#AAAAAA>.oni</font>, file prefix and suffix aren't used.
|}
|}


An example:
An example:
  <?xml version="1.0" encoding="utf-8"?>
  <?xml version="1.0" encoding="utf-8"?>
  <Oni>
  <Oni>
Line 371: Line 414:
     </SoundGroup>
     </SoundGroup>
  </Oni>
  </Oni>


==BINACJBOSound.xml==
==BINACJBOSound.xml==
This is for area-fixed sounds.
This is for sounds anchored to a certain area.
 


{| class="wikitable" width=100%
{| class="wikitable" width=100%
|width=120px| '''tag'''
|width=120px| '''Tag'''
|width=100px| '''type'''
|width=100px| '''Type'''
| '''description'''
| '''Description'''
|-
|-
| <Objects>
| <Objects>
Line 388: Line 429:
| <SNDG Id="...">
| <SNDG Id="...">
| integer
| integer
| This tag marks the file as a sound list. ID doesn't matter at import time.
| This tag marks the file as a sound list. The ID doesn't matter at import time.
|-
|-
| <Header>
| <Header>
Line 396: Line 437:
|valign="top"| <Flags>
|valign="top"| <Flags>
|valign="top"| flag
|valign="top"| flag
| Ignore it. Those flags were used in the past.
| You can ignore these flags, as they are defunct:
: None  
: None  
: Locked  
: Locked  
Line 405: Line 446:
| <Position>
| <Position>
| float x3
| float x3
| here you tell Oni where you want the sound to be [[OBD_talk:BINA/OBJC|located]]
| Where the sound should be located (see [[OBD talk:BINA/OBJC|HERE]] for help with that).
|-
|-
| <Rotation>
| <Rotation>
Line 417: Line 458:
| <Class>  
| <Class>  
| char[32]
| char[32]
| <font color=#AAAAAA>SNDD</font>name<font color=#AAAAAA>.amb.oni</font>, file prefix and suffix aren't used
| <font color=#AAAAAA>SNDD</font>name<font color=#AAAAAA>.amb.oni</font>, file prefix and suffix aren't used.
|-
|-
| <Sphere>
| <Sphere>
Line 425: Line 466:
| <MinRadius>
| <MinRadius>
| float
| float
| between min radius and sound origin (<Position>) is the sound volume equally strong
| From the point of the sound's origin (<Position>) out to Min radius, the sound volume is equally strong.
|-
|-
| <MaxRadius>
| <MaxRadius>
| float
| float
| between max and min radius is a transition of the sound volume
| Between Min and Max radius, the sound volume will decrease; greater distance than Max makes the sound inaudible.
|-
|-
| <Box>
| <Box>
| -
| -
| alternative to <Sphere>
| You can use this alternative to <Sphere> if you want to limit a sound to a specific room.
|-
|-
| <Min>
| <Min>
Line 443: Line 484:
| X2 Y2 Z2
| X2 Y2 Z2
|}
|}


An example:
An example:
         <SNDG Id="8805">
         <SNDG Id="8805">
             <Header>
             <Header>
Line 464: Line 503:
         </SNDG>
         </SNDG>


==Scripting music==
===BSL commands===
'''sound_music_start name:string [volume:float]''', e.g. <code>sound_music_start mus_asian 0.75</code>


==sound-related BSL commands==
'''sound_music_stop name:string''', e.g. <code>sound_music_stop mus_asian</code><br>
* [[BSL:Functions#sound|on this wiki]]
If .amb file has InterruptTracksOnStop flag, music will proceed immediately to <OutSound>, otherwise current segment will finish playing and then <OutSound> will play.
* [http://ssg.oni2.net/commands.htm#sound on ssg's website]


'''sound_music_volume name:string volume:float [time:float]''', e.g. <code>sound_music_volume mus_asian 0.35 1.0</code><br>
Volume change takes effect instantly unless you specify a time as the third parameter.


sound_music_stop ''soundtrack'' - can only be used if .amb file has the InterruptTracksOnStop flag<br>
===Stopping the music===
sound_music_stop ''soundtrack'' 1 - soundtrack stop after 1 second while it gets quieter
When Oni's BSL scripting wants to stop some music, it will either:
# Call <code>sound_music_stop ''mus_name''</code>.
# Fade out the music with <code>sound_music_volume ''mus_name'' 0.0 4.0</code> and then call <code>sound_music_stop ''mus_name''</code> when the music has reached zero volume. (4.0 is a sample fade-out time. Oni uses values ranging from 0.25 to 6.0 in various situations.)


You need a custom function if you want to fade out a soundtrack over more than one seconds. It could look like this:
When setting up your .amb file, you have to think about the timing of how the music will be used. If a music track has an <OutSound> in its .amb, then the sequence of events will be:<br>
:<tt>sound_music_stop</tt> called → current body segment finishes playing → outro segment plays


var float x = 1;
Thus it can be quite a while before the music really stops. If this is a problem, you could:
var int y = 0;
# Leave out the <OutSound> so that <tt>sound_music_stop</tt> ends the music after the current segment finishes.
# Fade out the music over the desired amount of time with <tt>sound_music_volume</tt>. Use <tt>sound_music_stop</tt> on the track after its fade-out finishes so that the sound system can stop playing the music.
# don't test this function with the console, it could happen that the function stops working after 4 cycles
# Use the InterruptTracksOnStop flag so that <tt>sound_music_stop</tt> skips to playing <OutSound> immediately.
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
}
}


====InterruptTracksOnStop====
Oni contains many music OSBDs that come in two variants – with and without the InterruptTracksOnStop flag – such as OSBDmus_amasian.amb and OSBDmus_amasian_hd.amb; they play the same actual SNDDs, but the "_hd" variant has the InterruptTracksOnStop flag. When <tt>sound_music_stop</tt> is called on a "_hd" OSBD, you will hear it immediately jump to the outro, which is slightly jarring but can be useful in some cases. An easily observed example is OSBDmus_fiteb_hd, which plays in {{C2}} when combat starts after the opening cutscene in the lobby. When the final blow is delivered to the last standing Striker, the music will immediately jump to its outro. Any discontinuity in the rhythm is masked by the sound of the attack that triggers it, and in fact the hard transition serves to punctuate the end of the action. By contrast, if a track was interrupted in this way during a quiet moment in the game it would probably sound awkwardly abrupt.


==Registering sounds for characters==
...such as the sounds of heavy attacks and taunts.


'''Let's see how sounds get looked up:'''
: TRAM -> ONCC -> OSBD.amb -> OSBD.grp -> SNDD


==[http://oni.bungie.org/community/forum/viewtopic.php?id=798 OCF thread about new music]==
# A character performs a move/attack where the TRAM file holds an ID representing a type of sound (<Vocalization>).
# The character's ONCC has its <SoundConstants> field looked at. The subfield for this specific vocalization type contains a link in the form of an OSBD.amb name. Note that the ONCC file has also a probability value that decides whether a sound will be played or not.
# The OSBD.amb is looked up and has its <BaseTrack1> field read, which is the name of an OSBD.grp file.
# The OSBD.grp contains the link(s) to the actual SNDD(s).


===Permutations===
'''An OSBD.grp can hold multiple links to SNDD files, called <Permutation>s.''' That's why Konoko can have multiple taunt sounds. Each permutation has its own <Weight> which determines its probability of playing. This probability is figured in relation to the total weight of all permutations, so if an OSBD has four permutations and the first one has a <Weight> of 30 and the other three have <Weight>s of 10, the first sound has a 50% chance of being picked. This feature is used to define rare taunts for some characters, such as the [[Comguy]]'s [[Easter eggs|Easter egg]] taunt, "Okay, okay, ''don't'' frog blast the vent core!"


==How to register sounds to characters==
====PreventRepeat====
... such as sounds of heavy attacks and taunts.
The key to not hearing the same taunt or hurt sound twice in a row is to add PreventRepeat to <Flags>. Oni uses this flag in the OSBD.grp files for hurt sounds, material impact sounds like Konoko's click-clacks when running, and taunt sounds (see OSBDc17_99_28konoko.grp for Konoko's). The flag is also used on about half of Oni's soundtrack (most of the "mus_" pieces, but only a few of the "atm_" pieces) to prevent segments from repeating.


 
===Step 1: Preparing the TRAM===
'''Let's see how sounds become picked up:'''<br>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.<br>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.
'''Search for <Vocalization> in the TRAM file''' and give it an ID according to the following table.


{|class="wikitable" width="100%"  
{|class="wikitable" width="100%"  
Line 527: Line 556:
|-
|-
| 0
| 0
| <TauntProbability> - '''taunt(s)'''
| <TauntProbability> '''taunt(s)'''
|-
|-
| 1
| 1
| <AlertProbability> - AI being surprised by a sound
| <AlertProbability> AI being surprised by a sound
|-
|-
| 2
| 2
| <StartleProbability> - AI being surprised by an enemy
| <StartleProbability> AI being surprised by an enemy
|-
|-
| 3
| 3
| <CheckBodyProbability> - (AI only?) death taunt (when enemy / player dies)
| <CheckBodyProbability> AI death taunt, played when enemy dies
|-
|-
| 4
| 4
| <PursueProbability> - sound when character lost track of enemy
| <PursueProbability> — Play this sound when AI loses track of enemy
|-
|-
| 5
| 5
| <CoverProbability> - being afraid (E.g. "Dont't hurt me.")
| <CoverProbability> — Play this sound when afraid (e.g. "Don't hurt me!")
|-
|-
| 6
| 6
| <SuperPunchSound> - '''sound of ######punch_heavy.oni''', super punches don't have sound IDs
| <SuperPunchSound> '''Sound of ######punch_heavy.oni'''; super punches don't have sound IDs
|-
|-
| 7
| 7
| <SuperKickSound> - '''sound of ######kick_heavy.oni''', super kicks don't have sound IDs
| <SuperKickSound> '''Sound of ######kick_heavy.oni'''; super kicks don't have sound IDs
|-
|-
| 8
| 8
| <Super3Sound> - AI specialty, Mukade use it for his devil star attack (TRAMNINCOMfireball)
| <Super3Sound> AI specialty; Mukade uses it for his Devil Star attack (TRAMNINCOMfireball)
|-
|-
| <font color=#777777>9</font>
| <font color=#777777>9</font>
Line 557: Line 586:
|}
|}


===Step 2: Preparing the ONCC===
Search for <SoundConstants> and set a value between 0 and 100. 100 means "always play this sound".


===step 2: preparing the ONCC===
Let's look at Konoko's settings, with a focus on her taunt sound. In ONCCkonoko_generic.xml, we see this:
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>
             <SoundConstants>
Line 587: Line 614:
             </SoundConstants>
             </SoundConstants>


 
===Step 3: Preparing the OSBD.amb===
===step 3: preparing the OSBD.amb===
Do you see the <BaseTrack1> tag? In this case it holds the link <font color=#AAAAAA>OSBD</font>c17_99_28konoko<font color=#AAAAAA>.grp.oni</font>. (See {{SectionLink||Using BaseTrack2 to layer sound}} below for info on that tag.)
You basically need such a file...
 
Do you see the <BaseTrack1> tag? In this case it holds the link <font color=#AAAAAA>OSBD</font>c17_99_28konoko<font color=#AAAAAA>.grp.oni</font>.
 


  <?xml version="1.0" encoding="utf-8"?>
  <?xml version="1.0" encoding="utf-8"?>
Line 622: Line 645:
  </Oni>
  </Oni>


 
===Step 4: Preparing the OSBD.grp===
===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.
Since <NumberOfChannels> is only once presented all the SNDD files must have the same number of channels.


{|class="wikitable" width="100%"
{|class="wikitable" width="100%"
Line 630: Line 652:
! 22.05 kHz, mono
! 22.05 kHz, mono
! 22.05 kHz, stereo
! 22.05 kHz, stereo
! 44.1 kHz, mono '''(PC-only)'''
! 44.1 kHz, mono '''(Windows-only)'''
|-
|-
|align="center"| NumberOfChannels
|align="center"| NumberOfChannels
|align="center"| 1
|align="center"| 1
|align="center"| 2
|align="center"| 2
|align="center"| '''2'''
|align="center"| '''1''' (with Pitch of 2)
|}
|}


 
(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".)
(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"?>
  <?xml version="1.0" encoding="utf-8"?>
Line 678: Line 699:
  </Oni>
  </Oni>


As you can see, [[#Permutations|permutations]] in .grp files are the reason why Konoko has multiple sounds that can play during the same taunt animation.
* <font color=#AAAAAA>SNDD</font>c17_99_28konoko.aif<font color=#AAAAAA>.oni</font> ("You're gonna get beat by a girl!")
* <font color=#AAAAAA>SNDD</font>c17_99_29konoko.aif<font color=#AAAAAA>.oni</font> ("Ready to lose?") (You can play sounds in Simple OniSplit GUI (Windows only).
* ''[...]''
"aif" is here part of the name, as explained under {{SectionLink||The .aif suffix}}.
===Step 5: Everything else that's left===
* Create your SNDDs if you haven't yet (see {{SectionLink||Source file creation}}).
* Put your files into a mod package.
* Test your stuff in-game!
==Using DetailTrack to add ambience==
Oni makes extensive use of DetailTrack to add ambient noises that punctuate larger ambient tracks. Examples include electronic beeps when near computer systems, zap sounds near electrical fires, plane sounds on the airport tarmac, and the horn beeps and sirens heard in city environments. The OSBD.grp files used as detail tracks are airport_detail, city_detail, citydetail_rooftop, citygarage, elec_detail, elecfire_detail, exthangar_detail, hangar_detail, idustry_detail, normcompdetail, spacecompdetail if you want to see the sounds they collect.


As you can see
To see the attributes assigned to these detail tracks and get a sense of normal values for <SphereRadius> and <ElapsedTime>, see the OSBD.amb files that call them: ATM, AiportMonitors, ElecFire, LargerElecFire, airport_exterior, airport_interior, bigroom2_airport, city_amb01, city_amb02, city_amb03, city_amb04, city_amb06rooftop, citydetail, elecdetail, elecfirelwflm, ext_hangar, indus_heavy1, indus_heavy3, indus_light1, largeElecFire, medcomp1, parkgarage, scomp01, scomp02, scomp3, scomp6, smallcomp1, smallcomp2, tranroomlowwdet, transboxwdet, transroomwdetail.
* <font color=#AAAAAA>SNDD</font>c17_99_28konoko.aif<font color=#AAAAAA>.oni</font> ("You're gonna get beat(en) by a girl!")
 
* <font color=#AAAAAA>SNDD</font>c17_99_29konoko.aif<font color=#AAAAAA>.oni</font> ("Ready to lose?") (You can play sounds with (PC) onisplit GUI or (Mac) AETools.
==Using BaseTrack2 to layer sound==
* ''[...]''
You can place a link to an OSBD.grp in the OSBD.amb's <BaseTrack2> and it will play in parallel with <BaseTrack1>.
are used for Konoko. ("aif" is here part of the name, don't get bothered by it.)
 
This file is the magic why Konoko has multiple sounds through one and the same taunt animation.
===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 {{C8}} and at the conclusion of Hasegawa's monologue at the start of {{C11}}. 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 the individual tracks in other places, or in combination with a different second track; for instance, '''OSBDmus_choral1''' calls for the same 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. Based on the example of OSBDmus_xtr2, it's BaseTrack2 (when present) which will finish out its current segment and BaseTrack1 that will cut abruptly at the same time.
 
Because of this, it may seem unacceptable to mix tracks with different segment lengths, but OSBDmus_xtr2 showcases a working solution: 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 <code>sound_music_volume</code> 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 <code>sound_music_stop</code>.


===Layering ambience===
[[Image:Ch. 2 dynamo room.jpg|200px|thumb|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.


===step 5: everything else what's left===
===Doubling a sound effect===
* [[#Source_file_creation|create your SNDD]] if you haven't yet
<BaseTrack2> is even used in '''OSBDbarab_recharge''' to beef up Barabas' recharging effect by playing his recharge sound twice at the same time.
* put your files into a package
* test your stuff in-game


{{XML}}
{{XML}}

Latest revision as of 15:13, 31 December 2023

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

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 the .oni files twice (one time from a WAV source and another time from an AIFF source). The AIFF .oni files will go in the mac_only/ folder and the WAV .oni files will go in the win_only/ folder as described on Making a mod package.

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 Unix shell script for converting a folder of sounds from WAV to the AIFF format suitable for importing. Save the script as "convert_sounds.sh", make sure that IN_DIR and OUT_DIR are set to the correct values, and run the script in Terminal with the command "sh convert_sounds.sh".

#!/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. Existing resources in Oni link to a sound titled "SNDDgears.aif", thus nothing will play. If you supply an AIFF file called "SNDDgears.aif.aif" or a WAV file called "SNDDgears.aif.wav", OniSplit will create the file "SNDDgears.aif.oni" and Oni will find the resource named "SNDDgears.aif" that it's seeking.

.oni file creation

Via Vago

Installation:

Usage:

  • Open Oni/AE/Tools/VagoGUI/Vago.exe
  • Target Platform > choose the desired target
  • Tools > Sound Wizard

Via command line

For those who want to do it on their own.

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

OSBD information

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

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

For simplicity's sake you should follow Oni's example and give all the files related to one sound the same base name:

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

Music .ambs

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, SNDD_newmusic2.oni… (the individual music files)

Breaking the main loop of the music into parts allows Oni to more quickly transition to the ending part when the music is commanded to stop playing. The shorter segments you can break the music into, the better – both for the sake of reaching the outro sooner, and because long segments can be taxing on the game. Oni's music averages 9 seconds per segment, and a segment rarely goes above 20 seconds.

The parts of the music between intro and outro are played in a randomized order 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, however this feature is effectively unused in Oni's music as all music segments have a <Weight> of 10.

For information on permutations, see § Permutations. For information on layering two music tracks with BaseTrack2, see § Using BaseTrack2 to layer sound.

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> parent tag
<Priority> flag
Low
Normal
High
Highest
<Flags> flag
InterruptTracksOnStop — Don't wait for current .grp element to finish before stopping sound; used for dialogue, a few sound effects, some music pieces. A music piece with this flag will immediately cut to its outro when sound_music_stop is called on it; see § Scripting music for details.
PlayOnce – Don't loop this sound; mostly applied to dialogue. A few sound effects have it as well (was this intentional?).
CanPan
<DetailTrackProperties> parent tag
<SphereRadius> float Size of area within which detail sounds can be heard.
<ElapsedTime> parent tag
<Min> float The smallest amount of time that can elapse before playing another detail track sound.
<Max> float The longest we can go without playing a detail track sound.
<Volume> parent tag
<Distance> parent tag
<Min> float Near distance at which the sound rises to its maximum volume.
<Max> float Far distance at which the sound falls to its minimum volume.
<DetailTrack> char[32] OSBDname.grp.oni, file prefix and suffix aren't used. See § Using DetailTrack to add ambience for explanation.
<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. See § Using BaseTrack2 to layer sound for explanation.
<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 This is the lowest volume (0.0-1.0) that a sound can have, even when the path between the sound-emitting area and the player is fully occluded by the environment. The name is misleading but should be thought of as "minimum (floor) value when calculating the volume of an occluded sound".

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 - Do not play the same permutation twice in a row, if there is more than one permutation.
<NumberOfChannels> int32
22.05 kHz, mono 22.05 kHz, stereo 44.1 kHz, mono (Windows-only)
NumberOfChannels 1 2 1 (with Pitch of 2)
<Permutations> - int32 array for the <Permutation> tags; see § Permutations.
<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 anchored 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 Where the sound should 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>

Scripting music

BSL commands

sound_music_start name:string [volume:float], e.g. sound_music_start mus_asian 0.75

sound_music_stop name:string, e.g. sound_music_stop mus_asian
If .amb file has InterruptTracksOnStop flag, music will proceed immediately to <OutSound>, otherwise current segment will finish playing and then <OutSound> will play.

sound_music_volume name:string volume:float [time:float], e.g. sound_music_volume mus_asian 0.35 1.0
Volume change takes effect instantly unless you specify a time as the third parameter.

Stopping the music

When Oni's BSL scripting wants to stop some music, it will either:

  1. Call sound_music_stop mus_name.
  2. Fade out the music with sound_music_volume mus_name 0.0 4.0 and then call sound_music_stop mus_name when the music has reached zero volume. (4.0 is a sample fade-out time. Oni uses values ranging from 0.25 to 6.0 in various situations.)

When setting up your .amb file, you have to think about the timing of how the music will be used. If a music track has an <OutSound> in its .amb, then the sequence of events will be:

sound_music_stop called → current body segment finishes playing → outro segment plays

Thus it can be quite a while before the music really stops. If this is a problem, you could:

  1. Leave out the <OutSound> so that sound_music_stop ends the music after the current segment finishes.
  2. Fade out the music over the desired amount of time with sound_music_volume. Use sound_music_stop on the track after its fade-out finishes so that the sound system can stop playing the music.
  3. Use the InterruptTracksOnStop flag so that sound_music_stop skips to playing <OutSound> immediately.

InterruptTracksOnStop

Oni contains many music OSBDs that come in two variants – with and without the InterruptTracksOnStop flag – such as OSBDmus_amasian.amb and OSBDmus_amasian_hd.amb; they play the same actual SNDDs, but the "_hd" variant has the InterruptTracksOnStop flag. When sound_music_stop is called on a "_hd" OSBD, you will hear it immediately jump to the outro, which is slightly jarring but can be useful in some cases. An easily observed example is OSBDmus_fiteb_hd, which plays in CHAPTER 02 . ENGINES OF EVIL when combat starts after the opening cutscene in the lobby. When the final blow is delivered to the last standing Striker, the music will immediately jump to its outro. Any discontinuity in the rhythm is masked by the sound of the attack that triggers it, and in fact the hard transition serves to punctuate the end of the action. By contrast, if a track was interrupted in this way during a quiet moment in the game it would probably sound awkwardly abrupt.

Registering sounds for characters

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

Let's see how sounds get looked up:

TRAM -> ONCC -> OSBD.amb -> OSBD.grp -> SNDD
  1. A character performs a move/attack where the TRAM file holds an ID representing a type of sound (<Vocalization>).
  2. The character's ONCC has its <SoundConstants> field looked at. The subfield for this specific vocalization type contains a link in the form of an OSBD.amb name. Note that the ONCC file has also a probability value that decides whether a sound will be played or not.
  3. The OSBD.amb is looked up and has its <BaseTrack1> field read, which is the name of an OSBD.grp file.
  4. The OSBD.grp contains the link(s) to the actual SNDD(s).

Permutations

An OSBD.grp can hold multiple links to SNDD files, called <Permutation>s. That's why Konoko can have multiple taunt sounds. Each permutation has its own <Weight> which determines its probability of playing. This probability is figured in relation to the total weight of all permutations, so if an OSBD has four permutations and the first one has a <Weight> of 30 and the other three have <Weight>s of 10, the first sound has a 50% chance of being picked. This feature is used to define rare taunts for some characters, such as the Comguy's Easter egg taunt, "Okay, okay, don't frog blast the vent core!"

PreventRepeat

The key to not hearing the same taunt or hurt sound twice in a row is to add PreventRepeat to <Flags>. Oni uses this flag in the OSBD.grp files for hurt sounds, material impact sounds like Konoko's click-clacks when running, and taunt sounds (see OSBDc17_99_28konoko.grp for Konoko's). The flag is also used on about half of Oni's soundtrack (most of the "mus_" pieces, but only a few of the "atm_" pieces) to prevent segments from repeating.

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 sound 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 § Using BaseTrack2 to layer sound 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 (with Pitch of 2)

(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, permutations in .grp files are the reason why Konoko has multiple sounds that can play during the same taunt animation.

  • 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 .aif suffix.

Step 5: Everything else that's left

Using DetailTrack to add ambience

Oni makes extensive use of DetailTrack to add ambient noises that punctuate larger ambient tracks. Examples include electronic beeps when near computer systems, zap sounds near electrical fires, plane sounds on the airport tarmac, and the horn beeps and sirens heard in city environments. The OSBD.grp files used as detail tracks are airport_detail, city_detail, citydetail_rooftop, citygarage, elec_detail, elecfire_detail, exthangar_detail, hangar_detail, idustry_detail, normcompdetail, spacecompdetail if you want to see the sounds they collect.

To see the attributes assigned to these detail tracks and get a sense of normal values for <SphereRadius> and <ElapsedTime>, see the OSBD.amb files that call them: ATM, AiportMonitors, ElecFire, LargerElecFire, airport_exterior, airport_interior, bigroom2_airport, city_amb01, city_amb02, city_amb03, city_amb04, city_amb06rooftop, citydetail, elecdetail, elecfirelwflm, ext_hangar, indus_heavy1, indus_heavy3, indus_light1, largeElecFire, medcomp1, parkgarage, scomp01, scomp02, scomp3, scomp6, smallcomp1, smallcomp2, tranroomlowwdet, transboxwdet, transroomwdetail.

Using BaseTrack2 to layer sound

You can place a link to an OSBD.grp 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 the individual tracks in other places, or in combination with a different second track; for instance, OSBDmus_choral1 calls for the same 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. Based on the example of OSBDmus_xtr2, it's BaseTrack2 (when present) which will finish out its current segment and BaseTrack1 that will cut abruptly at the same time.

Because of this, it may seem unacceptable to mix tracks with different segment lengths, but OSBDmus_xtr2 showcases a working solution: 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.