A modern C++17 media player built on FFmpeg, SDL2, OpenGL and Dear ImGui: video and audio playback, YouTube and SoundCloud, MilkDrop visualizations, Winamp skins, real-time BPM detection, a waveform seek bar, smart resume, a stereo widener and a built-in format converter.
cursedprograms.github.io/PulseAmp-Media-Player
- Windows 10/11 (64-bit): installer, portable zip and MilkDrop presets. The files are also in
dist/. - Linux (x86-64): PulseAmp-x86_64.AppImage, built automatically from
mainwith everything included. Runchmod +x PulseAmp-x86_64.AppImageand start it. Needs a 2024-or-newer distro (Ubuntu 24.04, Fedora 40, Debian 13, Arch...); file dialogs usezenity.
MidnightNeon, a full player skin: playlist with cover art, now playing, visualizer and equalizer
| YouTube search + MilkDrop | Vaporwave theme + theme editor |
|---|---|
![]() |
![]() |
| Right-click the visualizer | Neon arcade: Invaders |
![]() |
![]() |
| Settings panel | About window |
![]() |
![]() |
Classic mode skins: PulseOrb (round) and NeonCapsule (shaped from its PNG), plus MidnightNeon above
- YouTube & SoundCloud: search and play from the Online tab, paste a link, or drag one in from your browser. Uses yt-dlp (bundled with the Windows build; "Update yt-dlp" in the Online tab keeps it working). YouTube plays with video up to 1080p, or audio only.
- MilkDrop visualizer: the classic Winamp visualizer through projectM, with the 9,795-preset "Cream of the Crop" pack. Switch presets with
[/], or right-click the visualizer to pick one from the list, choose a visualizer, and set presets to change automatically or only when you say so. - Classic mode & skins:
Ctrl+Mturns PulseAmp into a compact window in the shape of its skin. Load real Winamp 2.x.wszskins (thousands at skins.webamp.org) or PulseAmp skins you can design yourself. See skins/README.md. - Neon arcade: Games in the menu bar turns the player into a neon arcade with Snake, Runner and Invaders, played over the visualizer while the music keeps going: Runner obstacles land on the beat and Invaders march to it. Or play over the video: pick Games → Backdrop → Video (or Auto) to keep a movie running behind the game, with a slider for how much it's dimmed. Make your own with
.paggame files, see games/README.md. - Themes: 8 built-in colour themes plus a live Theme Editor to make and save your own.
- Scales with the window: text and controls grow and shrink with the window and adapt to high-DPI screens. Double-click the video or visualizer for fullscreen; the controls hide after a few seconds.
Your own folder is %APPDATA%\PulseAmp on Windows (paste that into Explorer's address bar) and ~/.pulseamp on Linux and macOS. Files there survive PulseAmp updates. The folders next to PulseAmp.exe work too.
- Get presets: MilkDrop preset files end in
.milk. Good sources are the projectM preset collections and the thousands shared on forums and archives for Winamp's MilkDrop 2. - Copy the
.milkfiles, or whole folders of them, intopresetsin your folder (%APPDATA%\PulseAmp\presets; right-click the visualizer → Open presets folder takes you there). Each folder shows up as a category in the preset list. - Some presets use images: put those in
texturesnext topresets. - In PulseAmp: right-click the visualizer → Rescan presets (or restart), then Presets in the same menu, and pick one.
The Windows installer already includes the 9,795-preset "Cream of the Crop" pack. With the portable zip, extract PulseAmp-milkdrop-presets.zip into the PulseAmp folder to get it.
- Download a classic Winamp 2.x skin (a
.wszfile). skins.webamp.org has tens of thousands; click one and use its download button. (Winamp 3/5 "modern".walskins aren't supported.) - Copy the
.wszintoskinsin your folder (%APPDATA%\PulseAmp\skins; View → Skins → Open skins folder takes you there). Don't unzip it: PulseAmp reads it as is. - In PulseAmp: View → Skins and pick it; PulseAmp switches to Classic mode (
Ctrl+Mswitches back). Or use Settings → Load skin file... to open a.wszfrom anywhere.
PulseAmp's own skins (skin.json plus images, in a folder or a .zip/.paskin) go in the same skins folder. skins/README.md explains how to make one.
| Dependency | Version | Notes |
|---|---|---|
| CMake | ≥ 3.20 | cmake.org |
| C++ compiler | C++17 | GCC 10+, Clang 12+, MSVC 2022 |
| FFmpeg dev libs | 6.x – 8.x | avformat, avcodec, avutil, swscale, swresample |
| SDL2 dev libs | ≥ 2.26 | libsdl.org |
| OpenGL | 3.3+ | Provided by your GPU driver |
| ImGui, miniz | v1.90, 3.1 | Auto-downloaded by CMake FetchContent |
| projectM (+ GLEW on Windows) | 4.1 | Optional (MilkDrop). Uses an installed projectM 4 if found, otherwise auto-downloaded and built |
| yt-dlp | latest | Runtime only, for YouTube / SoundCloud: next to the exe or on PATH |
sudo apt update
sudo apt install -y \
build-essential cmake git \
libavformat-dev libavcodec-dev libavutil-dev \
libswscale-dev libswresample-dev \
libsdl2-dev libgl1-mesa-dev libglu1-mesa-dev \
libx11-dev libxext-dev \
zenity # optional: file-open dialoggit clone https://github.com/CursedPrograms/media_player.git
cd media_player
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)./build/PulseAmp /path/to/movie.mkvgit clone https://github.com/microsoft/vcpkg C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
C:\vcpkg\vcpkg integrate installC:\vcpkg\vcpkg install ffmpeg[avcodec,avformat,avutil,swscale,swresample]:x64-windows
C:\vcpkg\vcpkg install sdl2:x64-windowsgit clone https://github.com/CursedPrograms/media_player.git
cd media_player
cmake -B build `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake `
-DPULSEAMP_BUNDLE_FFMPEG=ON `
-DFFMPEG_BIN_DIR="C:\vcpkg\installed\x64-windows\bin"
cmake --build build --config Releasebuild\Release\PulseAmp.exe C:\Videos\movie.mp4
# Collects the exe, DLLs, yt-dlp, MilkDrop presets/textures and skins into dist\PulseAmp
.\scripts\package-windows.ps1 -BuildDir build\Release -FFmpegBin C:\vcpkg\installed\x64-windows\bin
# Add -Installer to also build dist\PulseAmp-Setup.exe (needs NSIS: https://nsis.sourceforge.io/)
# Output (each under GitHub's 100 MB file limit): PulseAmp-win64.zip, PulseAmp-milkdrop-presets.zip, PulseAmp-Setup.exebrew install cmake ffmpeg sdl2cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(sysctl -n hw.logicalcpu)./build/PulseAmp ~/Movies/movie.mp4# Install MSYS2, then in MSYS2 MinGW64 shell:
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc \
mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-SDL2
cmake -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build build -j4MinGW builds link the GCC runtime statically, so PulseAmp.exe only needs SDL2.dll and the FFmpeg DLLs next to it (add -DPULSEAMP_BUNDLE_FFMPEG=ON -DFFMPEG_BIN_DIR=<ffmpeg bin folder> to copy them automatically).
Standalone MinGW (e.g. WinLibs, without MSYS2): download the SDL2 SDL2-devel-*-mingw.zip and a shared FFmpeg build (e.g. BtbN's win64-lgpl-shared), then:
$sdl = "D:/deps/SDL2-2.32.10/x86_64-w64-mingw32"
$ff = "D:/deps/ffmpeg-n8.1-latest-win64-lgpl-shared-8.1"
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release `
-DSDL2_DIR="$sdl/../cmake" -DCMAKE_PREFIX_PATH="$ff;$sdl" `
-DCMAKE_CXX_FLAGS="-I$sdl/include" -DCMAKE_C_FLAGS="-I$sdl/include" `
-DPULSEAMP_BUNDLE_FFMPEG=ON -DFFMPEG_BIN_DIR="$ff/bin" `
-DCMAKE_TLS_CAINFO="C:/Program Files/Git/mingw64/etc/ssl/certs/ca-bundle.crt"
cmake --build buildThe extra -I is needed because the code includes <SDL2/SDL.h> and the SDL2 package only adds include/SDL2. CMAKE_TLS_CAINFO is only needed if downloads fail with "SSL peer certificate … not OK" (WinLibs' CMake ships without CA certificates; Git's bundle works).
| Option | Default | Description |
|---|---|---|
PULSEAMP_BUNDLE_FFMPEG |
OFF |
Copy the FFmpeg and SDL2 DLLs next to the exe (Windows) |
FFMPEG_BIN_DIR |
(empty) | Path to FFmpeg bin/ containing .dll files |
PULSEAMP_WITH_PROJECTM |
ON |
MilkDrop visualizer (projectM) |
PULSEAMP_FETCH_PROJECTM |
ON |
Download and build projectM if it isn't installed |
CMAKE_BUILD_TYPE |
— | Release for optimized build, Debug for dev |
media_player/
├── CMakeLists.txt ← Build system
├── README.md ← This file
├── cmake/projectm.cmake ← projectM (+ GLEW) build integration
├── src/
│ ├── main.cpp ← Entry point, SDL2+GL window, UI scaling, main loop
│ ├── player.{h,cpp} ← FFmpeg decode pipeline (1-2 inputs, demux + audio/video threads)
│ ├── audio_output.{h,cpp}← SDL2 audio device (volume up to 200%, stereo widener, EQ)
│ ├── equalizer.{h,cpp} ← 10-band equalizer + presets
│ ├── video_renderer.{h,cpp}← OpenGL RGBA texture upload
│ ├── visualizer.{h,cpp} ← 6 built-in visualizer modes with FFT
│ ├── milkdrop.{h,cpp} ← MilkDrop via projectM
│ ├── online.{h,cpp} ← YouTube / SoundCloud via yt-dlp
│ ├── skin.{h,cpp} ← Winamp .wsz + PulseAmp skin loading
│ ├── skin_window.{h,cpp} ← Shaped windows
│ ├── ui_skin.cpp ← Classic mode (skinned window)
│ ├── ui_skin_pulse.cpp ← PulseAmp skin controls (lists, EQ, search, cover art)
│ ├── skin_draw.{h,cpp} ← Neon drawing helpers, vector icons
│ ├── media_cache.{h,cpp} ← Cover art + tag cache
│ ├── games.{h,cpp} ← Neon arcade (Snake, Runner, Invaders) + .pag loader
│ ├── logos.{h,cpp} ← Logos built into the exe
│ ├── single_instance.{h,cpp}← Files opened in Explorer go to the running window
│ ├── theme_manager.{h,cpp}← Colour themes + theme editor storage
│ ├── fonts.{h,cpp} ← Font atlas (symbols, CJK on demand)
│ ├── ui_manager.{h,cpp} ← Full ImGui interface
│ ├── converter.{h,cpp} ← FFmpeg format converter
│ ├── playlist.{h,cpp} ← Playlist + smart resume
│ ├── bpm_detector.{h,cpp}← Real-time BPM detection
│ ├── spatial_audio.{h,cpp}← Stereo widener
│ ├── waveform.{h,cpp} ← Async full-file waveform generator
│ ├── json.{h,cpp}, paths.{h,cpp}, screenshot.{h,cpp}
├── skins/ ← Bundled skins + skin format docs
├── games/ ← Example .pag games + game format docs
├── assets/logo/ ← Logos (also embedded in the exe)
├── scripts/package-windows.ps1 ← Portable zip / installer packaging
└── installer/
└── setup.nsi ← NSIS Windows installer script
| Container | Extensions |
|---|---|
| Video | .mkv .mp4 .avi .mov .webm |
| Audio | .mp3 .flac .wav .ogg .aac .opus .m4a |
Codec support depends on your installed FFmpeg build.
The bundled FFmpeg from vcpkg/apt/brew covers H.264, H.265/HEVC, VP8, VP9, AV1, MP3, AAC, Vorbis, FLAC, and more.
| Key | Action |
|---|---|
Space |
Play / Pause |
← / → |
Seek ±5 seconds |
↑ / ↓ / mouse wheel |
Volume ±5% (up to 200%) |
M |
Toggle mute |
N / P |
Next / Previous track |
O |
Open file |
Tab |
Toggle sidebar |
V |
Toggle visualizer |
F / double-click |
Toggle fullscreen |
Ctrl+M |
Classic mode (skins) |
[ / ] |
Previous / next MilkDrop preset |
| Right-click visualizer | Visualizer menu: modes, MilkDrop presets, auto / manual preset changes |
Esc |
Leave fullscreen / classic mode, otherwise quit |
| Theme | Palette | Inspired by |
|---|---|---|
| NeonAmp | Black + Electric Green | Winamp 2.x |
| ChromePlayer | Silver-Grey + Steel Blue | Windows Media Player 9 |
| MidnightFusion | Deep Purple + Molten Gold | PulseAmp original |
| Blood Moon | Near-black + Crimson | PulseAmp original |
| Vaporwave | Violet + Pink / Cyan | PulseAmp original |
| Arctic | Deep Teal + Ice Blue | PulseAmp original |
| Amber Terminal | Black + Amber | Retro terminals |
| Classic Silver | Light Grey + Navy (light theme) | Classic Windows |
Make your own with View → Theme → Theme Editor; custom themes are saved to themes.ini in your settings folder.
| Mode | Description | Unique |
|---|---|---|
| Spectrum Bars | Classic FFT bar graph with peak hold | — |
| Oscilloscope | Real-time waveform trace | — |
| Radial Spectrum | Rotating circular FFT ring | ✅ PulseAmp exclusive |
| BPM Pulse | Beat-reactive expanding rings + spectrum border | ✅ PulseAmp exclusive |
| Particle Storm | Frequency-driven particle field | ✅ PulseAmp exclusive |
| Neon Wave | Glowing waveform over pink-to-cyan LED bars | ✅ PulseAmp exclusive |
| MilkDrop | Winamp's MilkDrop through projectM, thousands of presets | — |
-
BPM Detection — Real-time energy-based beat tracking; BPM shown in menu bar
and used to drive visualizer timing. -
Waveform Scrubber — The seek bar displays the full-file RMS waveform
generated asynchronously on file open. Seek by clicking anywhere on the waveform. -
Smart Resume — Every file's playback position is saved to
~/.pulseamp/resume.dat(Linux/macOS) or%APPDATA%\PulseAmp\resume.dat(Windows).
Next time you open the same file, it picks up exactly where you left off, with a
Start over button for a few seconds if you'd rather begin again. Turn it off in
Settings → Playback → Smart Resume to always start from the beginning. -
Mood-Adaptive Color — Optional mode that analyzes the live frequency balance
(bass/mid/treble ratio) and continuously shifts the visualizer accent color
to reflect the "mood" of the music. -
Spatial Audio / Stereo Widener — Haas-effect cross-feed filter that expands
the stereo field for headphone listening. Width is adjustable from 0× (mono) to 2× (extreme). -
Radial Spectrum + BPM Pulse + Particle Storm + Neon Wave visualizers —
Four original visualization modes found nowhere else. -
Neon arcade — Snake, Runner and Invaders in the Games menu, played over the
visualizer or a playing video (watch a movie while you play) and moving to the music;
make your own levels with.paggame files.
"FFmpeg not found" → Make sure the dev libraries are installed and CMake can find them:
use the vcpkg toolchain file, or pass -DCMAKE_PREFIX_PATH=<ffmpeg folder containing include/ and lib/>.
No audio on Linux → Install libasound2-dev (ALSA) or libpulse-dev (PulseAudio)
and rebuild SDL2 with audio support.
Black video / no video decode → Your FFmpeg build may lack the codec.
Use a full build: ffmpeg -version should list H.264 and H.265 decoders.
ImGui font warnings → The app falls back to the built-in pixel font automatically;
this is harmless.
PulseAmp was created by Farica Kimora.
© 2026 Cursed Entertainment
Built with FFmpeg (LGPL), SDL2, Dear ImGui, projectM (LGPL), GLEW, miniz and yt-dlp. MilkDrop presets: "Cream of the Crop" collection curated by ISOSCELES.
YouTube and SoundCloud playback goes through yt-dlp; their terms of service don't allow third-party players, so treat it as a personal-use feature.
PulseAmp --screenshot out.png [--size 1280x780] [--frames 30] [--show about|themes|settings|online|milkdrop|fullscreen|skin:<path>|search:<query>] renders the UI offscreen and saves a PNG. Set PULSEAMP_DATA_DIR to use a separate settings folder.












