A real-time audio spectrum visualizer plugin for InfoPanel. Captures your system audio output and renders a customizable spectrum visualization that you can display on your USB LCD panel or desktop overlay.
Requires InfoPanel 1.4.x with plugin image support. v2.0.0+ uses shared memory rendering and will not work with older InfoPanel versions.
| Rounded + Neon + CenterOut | Classic + CenterOut + Reflection |
|---|---|
![]() |
![]() |
| Wave + Neon + Reflection | Wave + Fire | Dots + Classic + CenterOut |
|---|---|---|
![]() |
![]() |
![]() |
| VuMeter + FireInverted + CenterOut | VFD + CenterOut | Analog VU Meter |
|---|---|---|
![]() |
![]() |
![]() |
The plugin captures your PC's audio output (whatever you hear through your speakers/headphones) using Windows WASAPI loopback, runs it through a 4096-point FFT to extract frequency data, and renders a spectrum visualization directly onto a shared memory bitmap. InfoPanel reads the bitmap at full frame rate with zero-copy transfer.
Data flow:
System Audio -> WASAPI Loopback -> FFT Analysis -> Spectrum Rendering -> Shared Memory -> InfoPanel
The plugin also exposes per-band frequency sensors, peak level, and average level values that you can use in InfoPanel's sensor display items, gauges, or graphs.
- Download the latest release from the Releases page
- Extract the
InfoPanel.AudioSpectrumfolder into your InfoPanel plugins directory:C:\ProgramData\InfoPanel\plugins\InfoPanel.AudioSpectrum\ - Start (or restart) InfoPanel
- Go to the Plugins page and enable Audio Spectrum
See Building from Source below.
Once the plugin is running, it exposes:
- Spectrum Image - A live image rendered directly to shared memory (shown as a Plugin Image in InfoPanel)
- Per-band frequency sensors - Individual values for each frequency band (e.g. "63Hz", "250Hz", "4.0kHz")
- Peak Level / Average Level - Overall spectrum intensity as percentages
- Audio Input Level - Raw audio amplitude from the capture device
- Audio Device - Name of the currently captured audio device
- In your InfoPanel profile, add an Image display item
- Set the source to Plugin Image
- Select the Spectrum Image from the Audio Spectrum plugin
- Resize and position the image on your panel layout
The per-band sensors (e.g. "63Hz", "1.0kHz") can be used anywhere InfoPanel accepts sensor values: text display items, bar graphs, gauges, charts, etc. This lets you build custom visualizations beyond the built-in spectrum image.
All settings are stored in an INI file located next to the plugin DLL:
C:\ProgramData\InfoPanel\plugins\InfoPanel.AudioSpectrum\InfoPanel.AudioSpectrum.dll.ini
The config file is auto-generated with defaults on first run. Most settings can be changed live from the Plugins page in InfoPanel without restarting. You can also edit the INI file directly with a text editor (restart the plugin to apply).
[AudioSpectrum]
AudioDevice =
BandCount = 32
ImageWidth = 400
ImageHeight = 150
Style = Bars
ColorScheme = Neon
CustomColor1 = #00FF80
CustomColor2 = #0080FF
BackgroundColor = #FF000000
BarSpacing = 0.3
CornerRadius = 4
ShowPeaks = true
ShowReflection = false
Brightness = 1.0
Smoothing = 0.05
PeakDecay = 0.007
Alignment = Left
ContentWidth = 1.0
CenterOut = false
Gain = 1.5
EdgeBoost = 5
NoiseFloor = 0
TrimBands = 0
FollowWaveLink = false| Setting | Default | Range | Description |
|---|---|---|---|
AudioDevice |
(empty) | - | Audio device to capture. Leave empty for default output device, or set to a partial device name (e.g. Speakers, Realtek). Available devices are listed as comments in the config file. |
FollowWaveLink |
false |
true / false |
Capture all Elgato Wave Link virtual audio channels simultaneously and mix them to recreate the full audio mix for spectrum visualization. Requires Wave Link 3.x running on the same machine. Overrides AudioDevice when active. See Wave Link Integration. |
| Setting | Default | Range | Description |
|---|---|---|---|
ImageWidth |
400 |
100 - 3840 | Width of the rendered spectrum image in pixels. |
ImageHeight |
150 |
50 - 2160 | Height of the rendered spectrum image in pixels. |
BackgroundColor |
#FF000000 |
Hex color | Background color. Use Transparent for no background, or an ARGB hex value like #FF000000 (opaque black). |
| Setting | Default | Range | Description |
|---|---|---|---|
BandCount |
32 |
8 - 128 | Number of frequency bands. More bands = finer frequency resolution but thinner bars. |
Gain |
1.5 |
0.5 - 5.0 | Multiplier applied to band values after FFT. Higher values make bars taller / more reactive. |
Smoothing |
0.05 |
0.05 - 0.95 | How much the bars smooth between frames. Lower = snappier response, higher = smoother motion. |
PeakDecay |
0.007 |
0.005 - 0.1 | How fast peak indicators fall after reaching their highest point. Lower = slower decay. |
| Setting | Default | Values | Description |
|---|---|---|---|
Style |
Bars |
Bars, Rounded, Wave, Dots, Mirror, VuMeter, Lines, VFD, VFDOrange, VFDClassic, VFDOrangeRed, AnalogVU |
Rendering style (see Styles below). |
ColorScheme |
Neon |
Neon, Fire, FireInverted, Ice, Rainbow, Ocean, Monochrome, Classic, Custom |
Color scheme (see Color Schemes below). |
BarSpacing |
0.3 |
0.0 - 0.8 | Gap between bars as a fraction of bar width. 0 = no gap, 0.5 = gap equal to bar width. |
CornerRadius |
4 |
0 - 20 | Corner rounding in pixels. Mainly affects the Rounded style. |
ShowPeaks |
true |
true / false |
Show peak hold indicators that float above the bars and slowly decay. |
ShowReflection |
false |
true / false |
Show a faded mirror reflection below the spectrum. Mutually exclusive with ShowMirror. |
ShowMirror |
false |
true / false |
Show a perfect 1:1 mirror reflection below the spectrum. Mutually exclusive with ShowReflection. |
Brightness |
1.0 |
0.1 - 2.0 | Overall brightness multiplier. Values above 1.0 make colors more vivid. |
| Setting | Default | Range | Description |
|---|---|---|---|
Alignment |
Left |
Left, Center, Right |
Horizontal alignment of the spectrum within the image. |
ContentWidth |
1.0 |
0.1 - 1.0 | Fraction of the image width used by the spectrum. 0.5 = spectrum uses half the width. |
CenterOut |
false |
true / false |
Reorder bands so low frequencies are in the center and high frequencies are on the edges. Creates a symmetrical look. |
EdgeBoost |
5 |
1 - 15 | Multiplier for edge bands when CenterOut is enabled. High frequencies naturally have less energy; this compensates so edge bars are visible. Only applies when CenterOut = true. |
NoiseFloor |
0 |
0.0 - 1.0 | Minimum band level as a fraction of the average. Ensures all bands show some activity when audio is playing. 0 = off, 0.5 = half of average. |
TrimBands |
0 |
0 - 20 | Number of bands to cut from each side. Removes low-energy edge bands for a cleaner look. |
| Setting | Default | Format | Description |
|---|---|---|---|
CustomColor1 |
#00FF80 |
Hex color | Start color for the Custom color scheme gradient. |
CustomColor2 |
#0080FF |
Hex color | End color for the Custom color scheme gradient. |
- Bars - Classic vertical bars with gradient coloring. Clean and readable.
- Rounded - Same as Bars but with rounded corners on each bar. Uses the
CornerRadiussetting. - Wave - Smooth curve connecting the frequency bands with a glow effect and filled area beneath.
- Dots - Matrix-style dot display with 16 dots per column. Active dots glow, inactive dots are dimmed.
- Mirror - Bars extend both up and down from a center line, creating a symmetrical waveform effect.
- VuMeter - LED-style segmented bars with green/yellow/red coloring (24 segments). Supports Fire/FireInverted vertical gradients.
- Lines - VFD-style thin scan lines using the selected color scheme instead of hardcoded VFD colors.
- VFD - Vacuum fluorescent display with thin horizontal scan lines, cyan-green phosphor glow, bloom effect, and dim ghost grid. Matches real VFD hardware.
- VFDOrange - Amber phosphor variant of VFD.
- VFDClassic - Cyan-green with red top zone (top 2/3 of bars), classic VFD look.
- VFDOrangeRed - Orange phosphor with red peaks and top zone.
- AnalogVU - Two classic analog needle VU meters (Peak + Average) with retro cream face, dark bezel, dB and percentage scales, peak hold needle, and clip LED indicator.
- Neon - Cyan/green to magenta. Vibrant and modern.
- Fire - Vertical flame gradient: dark red at base, orange in the middle, yellow/white at the tips.
- FireInverted - Inverted flame: yellow/white at base, fading to dark red at the tips.
- Ice - Light blue to white. Cool and clean.
- Rainbow - Full spectrum HSL cycling across the frequency range.
- Ocean - Deep blue to cyan/turquoise. Subtle and calm.
- Monochrome - Grayscale gradient.
- Classic - Per-bar green-yellow-red gradient based on intensity (like a VU meter).
- Custom - Linear gradient between
CustomColor1andCustomColor2.
If you use Elgato Wave Link to manage your audio, enable the FollowWaveLink option to have the plugin automatically capture all Wave Link virtual channels (System, Music, Browser, Game, etc.) and mix them together. This recreates your full audio mix for spectrum visualization regardless of which physical output device you have selected in Wave Link.
How it works:
- The plugin connects to Wave Link's local WebSocket API and discovers all configured audio channels
- It opens a WASAPI loopback capture on each channel's virtual audio device simultaneously
- The audio from all channels is mixed together in real time for FFT analysis and spectrum rendering
- When the output device changes in Wave Link (e.g. switching from speakers to headphones), the display updates automatically
Requirements:
- Wave Link 3.x running on the same machine
- The setting can be toggled on/off live from the Plugins page in InfoPanel (no restart needed)
- When active, the Audio Device sensor shows "Wave Link Mix (device name)" where device name is the currently selected output
- .NET 8.0 SDK (x64)
- Windows 10/11
Clone the repository and build:
git clone https://github.com/emaspa/InfoPanel.AudioSpectrum.git
cd InfoPanel.AudioSpectrumIf you have the InfoPanel source code alongside this project:
dotnet publish -c Release -r win-x64 --self-contained falseIf your InfoPanel source is in a different location, pass the path to the Plugins project:
dotnet publish -c Release -r win-x64 --self-contained false \
-p:InfoPanelPluginsPath=/path/to/infopanel/InfoPanel.Plugins/InfoPanel.Plugins.csprojThe output will be in bin/Release/net8.0-windows/win-x64/publish/.
Copy the contents of the publish folder to your InfoPanel plugins directory:
C:\ProgramData\InfoPanel\plugins\InfoPanel.AudioSpectrum\
If you already have a config file (InfoPanel.AudioSpectrum.dll.ini) in that folder, copying just the DLL files will preserve your settings.
To produce a registry-compliant release ZIP, run:
.\build-release.ps1This publishes the plugin and packages the output into InfoPanel.AudioSpectrum-v<version>.zip, with all files inside a top-level InfoPanel.AudioSpectrum/ folder as required by the InfoPanel plugin registry. The version is read from PluginInfo.ini (override with -Version).
This plugin can serve as a reference for building InfoPanel plugins. Here's the basic structure:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\InfoPanel.Plugins\InfoPanel.Plugins.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Update="PluginInfo.ini">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>Key points:
EnableDynamicLoadingmust betrueso the plugin loads in an isolated context- The
InfoPanel.Pluginsreference must havePrivate=falseandExcludeAssets=runtimeso the DLL isn't duplicated - The folder name, DLL name, and
.csprojname must all match (e.g.InfoPanel.MyPlugin)
[PluginInfo]
Name=My Plugin
Description=What the plugin does
Author=Your Name
Version=1.0.0
Website=https://github.com/you/your-pluginusing InfoPanel.Plugins;
public class MyPlugin : BasePlugin
{
private readonly List<PluginContainer> _containers = [];
public MyPlugin() : base("my-plugin", "My Plugin", "Description of my plugin") { }
public override TimeSpan UpdateInterval => TimeSpan.FromSeconds(1);
public override void Initialize()
{
var container = new PluginContainer("Main");
// Add sensors (numeric values with units)
var sensor = new PluginSensor("my-sensor", "CPU Temp", 0, "C");
container.Entries.Add(sensor);
// Add text values
var text = new PluginText("my-text", "Status", "OK");
container.Entries.Add(text);
_containers.Add(container);
}
public override void Update()
{
// Update sensor values here on each tick
}
public override void Load(List<IPluginContainer> containers)
{
containers.AddRange(_containers);
}
public override void Close()
{
// Cleanup resources
}
}dotnet publish -c Release -r win-x64 --self-contained falseCopy the publish output to C:\ProgramData\InfoPanel\plugins\InfoPanel.MyPlugin\.
For more details, see the InfoPanel plugin documentation.
- Audio capture: WASAPI loopback via raw COM P/Invoke (no NAudio device capture, works in any .NET AssemblyLoadContext)
- FFT: 4096-point FFT with Hann windowing via NAudio.Dsp
- Frequency mapping: Logarithmic band spacing from 20 Hz to 20 kHz
- Rendering: SkiaSharp (Skia) for all drawing, direct shared memory bitmap output
- Image transfer: Zero-copy shared memory via
IPluginImageProvider/ memory-mapped files - Update rate: ~30 FPS (33ms interval)
If you find this plugin useful, consider supporting the project:
MIT







