foo_vis_vumeter is modern reimplementation of the analog VU meter component by DRON. It renders using DirectX 12.
- Supports VUEditor-generated
.bin
files. Refer to the ".bin
File Specification" and "foobar2000.rar
Specification" sections below. - Supports AIMP analog
.zip
skins. Refer to the "AIMP Analog.zip
Specification" below. - Supports AIMP LED
.zip
skins. Refer to the "AIMP LED.zip
Specification" below. - Includes many fine-tuning options and modes.
- Controls through the context menu and using the mouse.
- Compatible with the Default User Interface (Default UI) and the Columns User Interface (Columns UI).
- Tested on foobar2000 v2.24 (x86 32-bit and x86 64-bit) and Microsoft Windows 11 (Build 26100).
- Requires Windows 10 or later due to DirectX 12.
- Falls back to the WARP software rasterizer if no DirectX 12-compatible adapter found.
- Install the component using the
foo_vis_vumeter.fb2k-component
file that can be downloaded from the official component page. - Download and extract panels/skins into this component's folder of foobar2000. This should be
<foobar2000 profile folder>\vumeter
.- A large number of these can be downloaded from tom2tec's "The Audio File" Gallery.
- Create custom panels using DRON's VUEditor.
- Another collection of skins collected and curated by Artem (AIMP main developer).
- LED skins gallery and creation tool by xrEngine.
- Some newly developed panels have been posted to the foo_vis_vumeter thread in the HydrogenAudio Forum.
- Does not implement any Windows Script Host or ActiveX features.
The component is controlled via the context menu, accessible by right-clicking anywhere on the component window. In addition, fine tuning can be performed by using the mouse wheel.
What the mouse wheel controls is selected through the "Tuning" menu. If the changes result in bad state, use the "Options > Reset" option. The selected tuning mode value can be reset to its default using middle click.
In the context menu there are a few symbols placed next to some options. These are their meaning:
- Circle: an option that is mutually exclusive with its neighbors.
- Square: a selection that is mutually exclusive with its neighbors that is currently tunable by the mouse wheel.
- Check Mark: a Boolean option that is enabled when checked and disabled when unchecked.
- Right Caret: there is a nested menu that will open on mouse hover.
- Grayed Text: this option is invalid at the present time or disabled.
What follows are the different menu categories with a short explanation of each option.
Layout:
- Left + Right (H): displays the left panel and right panel abutted side-by-side.
- Left + Right (V): displays the left panel abutted above the right panel.
- Left: displays only the left panel.
- Right: displays only the right panel.
- Mono: displays only the left panel and the needle shows a mixed-down version of the audio.
- Lock Aspect Ratio: locks the panel or skin to the native dimensions' ratio instead of filling the window.
Mode:
- Stereo: shows discrete left and right channels. In multi-channel audio, the left channels are mixed down into one with specific weighing to be displayed in the left panel and similarly with the right channels for the right panel. The center and LFE channels are mixed into left and right with an even share going into each.
- Mid/Side: shows mid and side components of the audio signal. Mid is shown in the left panel and is calculated as
(left + right) / 2
; Side is show in the right panel and is calculated as(left - right) / 2
.
Levels:
- RMS: calculates root mean square of the samples in the sample window.
- Peak: finds the highest (absolute value) sample in the sample window.
- LKFS: calculates loudness as prescribed in Rec. ITU-R BS.1770-5--except for the 400ms window as that is controlled/fine-tuned by the sample window option.
- Mixed: uses "RMS" for the needle/pin or main display element and, if the panel includes them, uses "Peak" for the LEDs/lamps.
Decay:
- Slow: sets the decay factor to 0.0075.
- Normal: sets the decay factor to 0.01.
- Fast: sets the decay factor to 0.015.
Tuning (mouse wheel-controlled):
- Zero: sets the offset in frames from the default zero frame. Only applies to foobar2000
.bin
panels. Default is 0 and the range is [-128.0, 512.0]. If:Ctrl
key is held down during the mouse wheel scroll, the step size is 100.Shift
key is held down during the mouse wheel scroll, the step size is 10.Alt
key is held down during the mouse wheel scroll, the step size is 0.1- No key is held down during the mouse wheel scroll, the step size is 1.
- Range: compresses the range of the needle drawing space. Only applies to foobar2000
.bin
panels when a level other than LKFS is selected. Default is 0 and the range is [0.0, 2.0] in steps of 0.01. - Decay: sets how fast the needle falls per frame. Can also be set to predetermined values in the "Decay" menu. Default is 0.01 and range is [0.0075, 0.03] in steps of 0.0005. Note: the tooltip display value is multiplied by 100.
- Rise: sets how fast the needle rises per frame. Default is 0.2 and the range is [0.01, 0.80] in steps of 0.01.
- Jitter: sets the minimum loudness change threshold needed for the needle to move. Default is 0 and the range is [0.0, 0.050] in steps of 0.001. Note: the tooltip display value is multiplied by 10.
- Gain: sets the preamplifier gain in dB. Default is 0 and range is [-60.0, 60.0]. If:
Ctrl
key is held down during the mouse wheel scroll, the step size is 10.Shift
key is held down during the mouse wheel scroll, the step size is 0.1.Alt
key is held down during the mouse wheel scroll, the step size is 0.01- No key is held down during the mouse wheel scroll, the step size is 1.
- Window: sets the sampling window size in milliseconds. Default is 42 [10.0, 400.0] in unit steps.
- FPS: sets the maximum number of frames rendered per second. Default is 60 and range is [24.0, 100.0] in unit steps.
- Corner: sets the default corner radius width in pixels of the skin image size. Can also be set to enabled or disabled from the "Options" menu. Default is 16 the range is [0.0, 32.0] in steps of 1.6.
Options:
- Downmix Channels: instructs foobar2000 to combine all channels into one. This occurs in the player before any of this component's processing.
- Rounded Corners: sets the corner tuning option to 0.0 (unchecked) or 16.0 (checked).
- Cubic Interpolation: selects between high quality cubic (enabled) and linear (disabled) Direct2D interpolation modes.
- Disable Tuning: disables the tuning menu and makes the component ignore the mouse wheel.
- Remove Background: removes the edge-sampled background and simply uses a dark or light mode default color.
- Freeze: freezes video frame.
- Show Counter: displays a frame counter on the top right.
- Vertical Synchronization: disabled and not functional. ?
- Rescan: Rescans panels directory.
- Reset: Resets all options to their defaults except layout/visual options.
Fullscreen: toggles the component between fullscreen mode and embedded or windowed mode.
The different panels/skins found during the scan of the <foobar2000 profile folder>\vumeter
directory appear in ASCII order (directories first) below the "Fullscreen" toggle.
There is an additional option under: Preferences > Advanced > Visualisations > VU Meter:
- Debug ouptut:
<unchecked>
(untested; ?). - Panels directory:
<empty>
(untested; implies<foobar2000 profile folder>\vumeter
when empty).
The needle movement is approximated using the following formula: display = old +/- (e ^ (new - old) - 1) * rise/decay
. The rise or decay factor limits how far the needle can move per frame or iteration of the calculation.
The needle position, frame number in foobar2000 .bin
panels or angle in AIMP analog .zip
skins, is calculated using the point-slope equation referenced to the zero dB frame or angle. For the AIMP LED .zip
skins, the "light" fill is calculated by interpolating between the points in the dbs
parameter's array using Catmull–Rom splines.
Panel Specification
===================
Reverse Engineer: Jimmy Cassis
Date: 2024-10-01
This specification defines the format of the BIN file.
Panel File Format
-----------------
The files in this format use ".bin" extension.
The panel file begins with a header.
The panel file format layout:
Offset Size Description
0 2 Bitmap width (16-bit unsigned integer, little-endian), between 2 and 4096
2 2 Bitmap height (16-bit unsigned integer, little-endian), between 2 and 4096
4 2 Frame count (16-bit unsigned integer, little-endian), between 2 and 1024
6 2 Zero dB frame (16-bit unsigned integer, little-endian), between 0 and 1024
8 n Needle delta offset list (array of 32-bit unsigned integer offsets, little-endian), `n` is "frames * 4" and the first entry must be greater than or equal to 32; note that some offsets might be repeated due to the "knots" interpolation.
8+n p Background image bitmap pixel array (BI_RGB format [B8G8R8A8 UNORM], 32 bits per pixel, little-endian), `p` is "width * height * 4", format below
8+n+p l Optional, lamp delta offset list (array of 32-bit unsigned integer offsets, little-endian), `l` is "frames * 4"
8+n+p+l d Needle delta arrays (variable size, offsets are big-endian, deltas are BI_RGB and apply per channel), `d` is variable, format below
8+n+p+l+d a Optional, lamp delta arrays (variable size, offsets are big-endian, deltas are BI_RGB and apply per channel), `a` is variable, format below
The total size of the file is: 8+n+p+l+d+a
The total size of the file must be greater than: 8+n+p
The bitmap pixel array layout is as follows (address _decreases_ from left-to-right):
Sample Length: | 8 | 8 | 8 | 8 |
Channel Membership: | Alpha | Red | Green | Blue |
Pixel Bits: | A A A A a a a a | R R R R r r r r | G G G G g g g g | B B B B b b b b |
Bit Number: | 31 30 29 28 27 26 25 24 | 23 22 21 20 19 18 17 16 | 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 |
The needle and lamp delta arrays use the following format:
- For every frame there is a 2-byte big-endian offset while the most significant bit (MSB) of the even byte is unset.
- If the MSB for the even byte is set, it indicates a count (excluding the MSB) of the number of pixel channels to override starting at the offset in the pixel array indicated by the sum of all the previous 2-byte offsets.
* Note that the offset might not necessarily start or end at a pixel boundary.
- Repeat, calculating a new offset from the end of the final overriden pixel until the even byte MSB is set and the count is zero (0x80).
Worked example for the needle delta array (address _increases_ from left-to-right):
Offset Sum: 174272 | 7 | 1489| 19 | 1481| 23 ...
Offset: 32768+32768+32768+32768+32768+10438| 7| 0| 1| 2| 3| 4| 5| 6| 1488|19| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16|17|18| 1480|23| 0| 1|...| 0|
Bytes: 7F FF 7F FF 7F FF 7F FF 7F FF 28 BF 87 8A 8B 87 00 E0 E2 DE 05 D0 93 B1 B2 AE 00 69 6A 67 00 6B 6D 68 00 B8 B9 B6 00 E0 E2 DF 05 C8 97 E6 EE ... 80
Pixel Bits: Bb Gg Rr Aa Bb Gg Rr Bb Gg Rr Aa Bb Gg Rr Aa Bb Gg Rr Aa Bb Gg Rr Aa Bb Gg Rr Bb Gg ... End
Notes
-----
When drawing, ignore the alpha channel.
- Can be bzip2-compressed, LZMA-compressed, Gzip-compressed, Zstandard-compressed or uncompressed.
- Can use needles or lamps (LEDs), or both.
- Can contain a single panel for left and right channels or separate left and right panels.
- By default, the assumption is that the panel file represents both the left and the right panels.
- If the file format is repeated at the end of the delta arrays, it is assumed that the first format corresponds to the left panel and the second format corresponds to the right panel.
- The file formats can be concatenated uncompressed into one file. Alternatively, individually compressed files can be concatenated (keep the same compression scheme for both).
- Another method to provide separate left and right panels is to provide a pair of files where the left panel file ends in
1.bin
and the right panel file in2.bin
.
foobar2000 .bin
panel variants verified:
- Model 702.bin: 702 panel extracted from original DLL resources. This is the hard-coded default.
- nos.bin: Single panel, uncompressed file.
- bzip2s.bin: Single panel, bzip2-compressed file.
- lzmas.bin: Single panel, LZMA-compressed file.
- leds.bin: Single panel with LEDs, bzip2-compressed file.
- pl.bin: Single panel with needle and LEDs, bzip2-compressed file.
- lzma1/lzma2.bin: Individual L/R panels in separate LZMA-compressed files, no space between file name root and number.
- leds 1/leds 2.bin: Individual L/R panels with LEDs in separate bzip2-compressed files, space between file name root and number.
- lzmai.bin: Individual L/R panels LZMA-compressed and concatenated into one file.
- bzip2i.bin: Individual L/R panels bzip2-compressed and concatenated into one file.
- And more every day!
Warning: Identifying LZMA-compressed heuristic is limited; especially if the skin was compressed outside of VUEditor. Therefore it is possible to confuse an uncompressed
.bin
file of any width less than 225 with a LZMA-uncompressed one. Using a bzip2-compressed file mitigates this issue since this scheme starts with an easily identifiable magic number.
- Must be ZIP-compressed and contain a
skin.ini
alongside corresponding PNG images at the root of the archive. - Can contain a single panel for left and right channels or separate left and right panels.
- For single panel the images must be named
0.png
(background),1.png
(needle),2.png
(glass) with optional3.png
(LED) andbg.png
(wallpaper). - For single panel all parameters must be specified under the
VU
section in theskin.ini
file; the supported parameters areMinAngle
,MinLevel
,ZeroAngle
,ZeroLevel
,MaxAngle
,MaxLevel
,PivotPointX
,PivotPointY
,MobilityNegative
,MobilityPositive
,orientation
, anddbs
. The section and parameter names are case insensitive. - For separate left and right panels the left panel images must be named
l_0.png
(background),l_1.png
(needle),l_2.png
(glass) with optionall_3.png
(LED) and the right panel images must be namedr_0.png
(background),r_1.png
(needle),r_2.png
(glass) with optionalr_3.png
(LED). There can be an optionalbg.png
(wallpaper). The image names are case insensitive. - For separate left and right panels, the left panel parameters must be specified in the
skin.ini
file under theVU_L
section and the right panel parameters must be specified under theVU_R
section. The supported parameters are the same as the single panel ones.
Note 1:
MobilityNegative
,MobilityPositive
, andorientation
parameters are currently unused.
Note 2: The
dbs
parameter array is optional and only used in skins that include an LED component in addition to the needle. As noted previously, the LED image is{l_,r_,}3.png
.
- Must be ZIP-compressed and contain a
settings.ini
alongside corresponding PNG images at the root of the archive. - The left panel parameters must be specified in the
settings.ini
file under theleft
section and the right panel parameters must be specified under theright
section. The background must be specified in thebg
section. The supported parameter in all 3 sections ispng
. The supported parameters in theleft
andright
sections areorientation
,start_point
,finish_point
,pos_x
,pos_y
, anddbs
. - The
dbs
image "dimension" can increase or decrease with the decibel level depending on whether the LED image is covered or uncovered. - An
orientation
value of 0 specifies that thedbs
dimension refers to width (i.e., horizontal). Conversely a value of 1 refers to height as the value that changes with the level (i.e., vertical). - The image name must match the one given in by the
png
parameter for each section.
- Must be RAR-compressed and contain a
<filename>.bin
file alongside a<filename>.ini
file. Where<filename>
must exactly match the name used as the base name of<filename>.rar
. Further, these files must be placed in the root of the archive. - The
.bin
file contained in the archive must follow the.bin
file specification outlined above and compressed, if desired, using a supported format. - All parameters must be specified under the
DEFAULT
section in the<filename>.ini
file; the supported parameters arefall
,rise
,singleMeter
,peakLED
,isVertical
,curveAdj
, andbgColour
. The section and parameter names are case insensitive.
Note 1:
fall
,rise
, andcurveAdj
parameters are currently unused.
Note 2: The
peakLED
parameter being true sets _Levels to Mixed as soon as the panel is loaded. ThesingleMeter
andisVertical
parameters combine to set the Layout mode. ThebgColour
parameter sets the background color, overriding the edge color detection.