Skip to main content

Extracting Sounds

In-depth guide to .stream file locating, extraction and playback with the aid of Wwiser.

Resources needed

For voiceline extracting:

Wwise Overview

Wwise is Payday 2's audio engine. For any sound to play, the game uses events that the sound designers set up in their Wwise project. These events are contained inside soundbanks, and can perform diverse actions on objects which can play the actual sounds. Audio can be either embedded inside the soundbanks or streamed from individual files (.stream, which is a rename of the proprietary .wem format).

  • Soundbanks (version 2013.2.10) -> Event -> Actions -> Objects -> Audio (embedded/streamed)

Some other factors to consider are switches, real-time parameter controls (RTPCs) and random containers.

  • Switches literally switch the sound that plays for one or more events. An excellent example are the control/assault voicelines, which are under the same events but can change dinamically. Another example are footstep sounds, which, depending on the material stepped on, change accordingly.
  • RTPCs literally control in real time some amount of parameters for their respective objects. Say for instance the pitch for the sound of vehicles.
  • Random containers make individual events able to play different sounds, well, at random. All voicelines use random containers. Footstep sounds are also a good example.

Embedded soundbank audio can easily be extracted and replaced with Hoppip's Soundbank Editor. For .streamed files, however, it's a different story. If you have previously tried to find specific sounds in the game's files, you'll have noticed that they have no name and are instead a bunch of numbers. This is a non-negotiable fact; Wwise strips every string that the game wouldn't need to use. However, audio files can still be referenced semi-efficiently from the events that play them, which we do have the names of.

TL;DR: We as modders can't obtain the audio file names directly, but we can get to them from the event names.

Initial setup

Generating TXTPs with Wwiser:

  1. Place wwnames.txt in the folder containing Wwiser.
  2. Inside Wwiser, select all the extracted soundbanks and wait for them to load.
  3. Set repeats to auto (for individual files for each of the random container variations). You can experiment with other values.
  4. Set language to english.
  5. Set the wem subdir to audio/
  6. Click on Generate TXTPs.
  7. Wait for magic.

Populating the audio folder:

  1. Create the path if it doesn't exist already, inside the txtp directory.
  2. Copy the game's streamed folder's content inside audio.
  3. Place the renamer/structurer batch script inside audio, run it, then delete the empty folder.
  4. You should now have a folder full of numbered .wem files.
  5. Copy the extracted soundbanks to the audio folder too.. just in case there's some embedded sound you want to play!

Video guide if you prefer, may be incorrect since its a bit old now

Searching for sounds

Note on TXTPs: TXTP is a plaintext format used by vgmstream to export audio files that resemble the original events that play them. So for instance, if an event plays a sequence of .streamed files, vgmstream will join them all together when you open that event's exported TXTP.

Finding .stream files from the events is easy with TXTPs. Wwiser exports TXTP with the following name formatting:

  • EVENT_NAME [switch1=value1] [switch2=value2] [switchN=valueN] {rRANDOM_VARIATION} {l=LANGUAGE}
    • Example: a01x_any [int_ext=first] (wave_flag=assault) [robber=rb1] {r14} {l=en}

So let's see how to find an example sound. This example will use Bain's assault announcement lines.

  1. Look for references in the voiceline ID spreadsheet; we find that the ID is Play_ban_b02c. If the sound wasn't in this list, maybe it would be referenced inside the map it's used in (use the Beardlib Editor), or the sequence manager of the unit that it plays with, or in the game's Lua. Either way, if it plays in the game, there is an event for it!
  2. Search for Play_ban_b02c inside the directory containing all the TXTPs. Once done, a singular result presents itself: Play_ban_b02c {r} {l=en}.txtp. Here, Wwiser has only generated a single TXTP with a {r} in the name because the event is mixing two different sounds; Bain speaking and the radio effect that always plays when he finishes talking. If the event were simpler, Wwiser would generate its variations automatically, but this doesn't matter to us because we want the source files. We open up the TXTP:
 audio/366400.wem #i
  audio/1051727284.wem #i
  audio/817518946.wem #i
  audio/590675679.wem #i
  audio/566302272.wem #i
  audio/245106306.wem #i
  audio/827980714.wem #i
  audio/321568525.wem #i
  audio/105276389.wem #i
  audio/518332048.wem #i
  audio/408167668.wem #i
  audio/440903212.wem #i
  audio/614416474.wem #i
  audio/384550902.wem #i
  audio/860485077.wem #i
  audio/1030203005.wem #i
  audio/13654407.wem #i
  audio/378925786.wem #i
  audio/758037986.wem #i
  audio/603051159.wem #i
  audio/614825143.wem #i
 group = -R20>1
 audio/5017674.wem #i
group = -S3

... wwiser helper info below ...

And there we go! Those are all the lines for Bain saying his assault intro variations. If you search for any of these in the audio folder and open them with vgmstream, you'll be able to play them. If you open the TXTP with vgmstream instead, you'll get a close representation of what the event in its entirety sounds like. In this case you can change the number in group = -R20>1 <-- THIS LAST NUMBER to choose the audio to generate the output with.

Scrolling down a few lines below this, you'll find the soundbank that contains this event. In the case of .streamed files, this would be the directory name where it lives: soundbanks/streamed/{BANK_NAME}/{THE_SOUND}.stream.

If the TXTP points to a soundbank, that means the audio is embedded inside it. Use the soundbank editor in that case.

  • robber: the character that is speaking.
Character Voice
Dallas rb4
Wolf rb3
Chains rb1
Houston rb2
John Wick rb6
Hoxton rb5
Clover rb7
Dragan rb8
Jacket rb9
Bonnie rb10
Sokol rb11
Jiro rb12
Bodhi rb13
Jimmy rb14
Sydney rb15
Rust rb16
Scarface rb17
Sangres rb18
Joy rb19
Duke rb22
Ethan rb20
Hila rb21
  • wave_flag: either Control or assault.