A cross-platform soundboard for CS2 and general voice chat apps (TeamSpeak, Discord, etc.). Play music and audio clips through your microphone (micspam) using a virtual audio cable. Works on Linux and Windows.
This is a rewrite of Skintillion/SLAM built with .NET 8 and Avalonia UI.
CS2 mode: SLAM writes CS2 config files that use voice_device_override to switch your active mic to a virtual audio cable when you play a sound, then switches back to your real mic when it stops. Other players hear it through your voice channel.
Stream to Mic mode: Plays audio directly into a virtual microphone that any app (TeamSpeak, Discord, etc.) can use as a capture device. Your real mic is mixed in simultaneously so you can talk while sounds play.
This does not inject into CS2 or modify game memory. It only writes .cfg files and routes system audio, which is VAC safe.
- .NET 8 SDK
- ffmpeg
- PipeWire with PulseAudio compatibility (pactl must be available)
- yt-dlp (optional, for YouTube import)
Install on Fedora/Nobara:
sudo dnf install dotnet-sdk-8.0 ffmpegInstall on Ubuntu/Debian:
sudo apt install dotnet-sdk-8.0 ffmpeg- .NET 8 SDK or Runtime
- ffmpeg on PATH
- VB-Audio Virtual Cable or similar
This is the most involved part. You need a virtual audio sink that SLAM plays into, a virtual microphone source that apps like TeamSpeak can capture from, and a loopback so your real voice is mixed in alongside the soundboard audio.
Create ~/.config/pipewire/pipewire-pulse.conf.d/virtual-mic.conf with:
context.exec = [
{ path = "pactl" args = "load-module module-null-sink sink_name=VirtualMic sink_properties=device.description=VirtualMic" }
{ path = "pactl" args = "load-module module-virtual-source source_name=VirtualMicInput master=VirtualMic.monitor source_properties=device.description=VirtualMicInput" }
]
This creates:
VirtualMic-- a virtual sink SLAM plays audio intoVirtualMicInput-- a virtual microphone source apps like TeamSpeak see as a capture device
To apply without rebooting:
mkdir -p ~/.config/pipewire/pipewire-pulse.conf.d
# (create the file above, then:)
systemctl --user restart pipewire-pulseWithout this step, only soundboard audio goes through VirtualMic. With it, your voice and the soundboard are mixed together so you can talk and stream sounds at the same time.
Create a systemd user service at ~/.config/systemd/user/slam-mic-loopback.service:
[Unit]
Description=SLAM mic loopback (your mic -> VirtualMic)
After=pipewire.service pipewire-pulse.service
BindsTo=pipewire.service
[Service]
ExecStartPre=/bin/bash -c 'until pactl list sinks short | grep -q VirtualMic; do sleep 0.5; done'
ExecStart=/bin/bash -c 'pacat --record \
--device=YOUR_MIC_PACTL_ID \
--channels=2 --format=s32le --rate=48000 \
--latency-msec=20 --process-time-msec=10 \
--stream-name=slam-mic-loopback | \
pacat --playback \
--device=VirtualMic \
--channels=2 --format=s32le --rate=48000 \
--latency-msec=20 --process-time-msec=10 \
--stream-name=slam-mic-loopback'
Restart=on-failure
RestartSec=2
[Install]
WantedBy=default.targetReplace YOUR_MIC_PACTL_ID with your microphone's pactl name. Find it with:
pactl list sources | grep -E "Name:|Description:" | grep -v monitorEnable and start it:
systemctl --user daemon-reload
systemctl --user enable --now slam-mic-loopback.serviceIn TeamSpeak 3: Settings -> Options -> Capture -> set Capture Device to VirtualMicInput.
In TeamSpeak 5: Settings -> Audio -> Microphone -> select VirtualMicInput.
Restart the app after creating VirtualMicInput so the device list refreshes.
Clone the repo and run from the SLAM-Cross directory:
cd SLAM-Cross
dotnet runTo build a release binary:
dotnet publish -c Release -r linux-x64 --self-containedThe output will be in bin/Release/net8.0/linux-x64/publish/.
- Launch the app.
- In the three dropdowns at the top, select your audio devices:
- Virtual Cable In: the sink you play audio into (
VirtualMicon Linux, CABLE Input on Windows) - Cable Out (mic): the monitor source CS2 uses as your mic (
Monitor of VirtualMicon Linux) - Regular Mic: your actual microphone to switch back to after sounds finish
- Virtual Cable In: the sink you play audio into (
- Click Import Files to add audio files. Supported formats: mp3, wav, aac, flac, ogg, m4a, mp4, and others supported by ffmpeg.
- Click Start. SLAM will search for your CS2 installation.
- In CS2, open the console and type
exec slam. - Use the relay key (default
=) to select a track by number or tag, then press the play key (defaultMOUSE4) to play it.
Example: type 3 in console, press MOUSE4 to play track 3. Type slam_listtracks to see all tracks.
Select a track in the list and click Stream to Mic. The audio plays directly into VirtualMic without needing CS2. If you set up the mic loopback service above, your voice is mixed in simultaneously.
Click Stream to Mic again (it becomes a stop button while streaming) or double-click another track to switch.
| Command | What it does |
|---|---|
exec slam |
Loads all SLAM binds |
slam_listtracks |
Prints track list to console |
slam_play |
Toggle play/stop |
slam_curtrack |
Echoes the current track name |
slam_saycurtrack |
Says current track name in chat |
slam_sayteamcurtrack |
Says current track name in team chat |
Click the Settings button to configure:
- Start polling on launch: automatically start when the app opens
- Hold key to play: hold the play key instead of toggling
- Relay key: the key CS2 uses to pass track selection back to SLAM (default
=) - Override Steam folder detection: manually set your steamapps and userdata paths if auto-detection fails
Settings are saved to ~/.config/SLAM/settings.json on Linux or %AppData%\SLAM\settings.json on Windows.
Right-click any track in the list for options:
- Play: stream the track immediately (works in both CS2 mode and standalone)
- Set Hotkey: bind a keyboard key to load this track directly
- Set Volume: adjust playback volume (1-100)
- Trim: set start and end points
- Rename: rename the track file
- Show in Files: open the track's folder in your file manager
- Delete: remove the track file
Click Import from YouTube. Requires yt-dlp installed and on your PATH.
Install yt-dlp:
pip install yt-dlpOr on Fedora:
sudo dnf install yt-dlpSLAM is stuck on "Searching..."
CS2 is not running, or auto-detection failed. Enable "Override Steam folder detection" in Settings and set the paths manually. On Linux the steamapps path is typically ~/.local/share/Steam/steamapps and userdata is ~/.local/share/Steam/userdata.
Audio goes to the wrong device or does not reach TeamSpeak
Make sure VirtualMicInput appears in TeamSpeak's device list. If it was created after TeamSpeak was already open, restart TeamSpeak. Also verify the Virtual Cable In dropdown in SLAM is set to VirtualMic.
Mic loopback has too much delay
Lower the --latency-msec values in the service file (e.g. 10 instead of 20). If you get crackling, increase them slightly.
Mic loopback crackles
Increase --latency-msec in the service file. Values between 20 and 50 are usually stable.
No audio reaches other players in CS2
Make sure the Cable Out (mic) dropdown matches what CS2 uses for voice. On Linux this is typically Monitor of VirtualMic. The device name must match what CS2 reports in voice_device_override.
Sounds play but cut off immediately
The virtual sink may be suspending due to inactivity. Keep it alive with:
paplay --device=VirtualMic /dev/zero &Audio distortion or wrong speed
The app converts files to 22050 Hz mono WAV before playback. If conversion fails, check that ffmpeg is installed with ffmpeg -version.
errorlog.txt
If "Log errors to errorlog.txt" is enabled in settings, errors are written to errorlog.txt in the directory you run the app from.