BPM2OSC Manual

BPM2OSC is a real-time BPM detector that streams tempo data over OSC. It captures audio from any input device — including system loopback — and sends /bpm, /beat, and /resync messages to lighting consoles, VJ software, and show-control systems.

Quick Start

  1. Download and run the Windows installer from the download page.
  2. Launch BPM2OSC.
  3. Click to open Settings.
  4. Select your audio input device (or a loopback device to capture system output).
  5. Add an OSC target: set the IP and port of your destination software.
  6. Click Save.
  7. Click ▶ START. The BPM display will update as soon as the engine detects a stable tempo.
  8. Select a genre preset from the preset bar if the detected BPM looks wrong.
Tip: enable Auto-start on launch in Settings so BPM2OSC starts listening immediately every time you open it.

Installation

Windows installer (recommended)

Download BPM2OSC Setup and run it. The installer includes all required dependencies (sounddevice, NumPy, python-osc, soundcard, pystray). No Python installation needed.

User Interface

BPM2OSC main window showing 97.7 BPM, VU meter, preset bar, Engine panel, and OSC target indicators

The main window is divided into these areas from top to bottom:

AreaDescription
Top bar? (About), ⚙ (Settings), RESYNC, START/STOP, and a transient status message.
VU meterPer-channel RMS bars with peak hold. Expands automatically for stereo and multi-channel devices.
BPM displayLarge numeric BPM readout, BPM unit label, and beat-wheel animation (click to toggle between pie and dot mode).
Bar indicatorBeat counter (1–4) and four coloured segments showing position within the bar.
BPM controlsLOCK, TAP, ÷2, ×2 buttons.
Preset barOne button per configured preset. The active preset is highlighted.
Engine panelAlgoMonitor diagnostic widgets (ODF, BPM history, ACF curve, confidence, stability).
Targets panelOne indicator dot per OSC target. Flashes on every OSC send.
Status barFBLab.it credit and donation link.

System tray

Minimizing the window sends BPM2OSC to the system tray (Windows, requires pystray). Right-click the tray icon for Start/Stop, Resync, and Quit. The tray tooltip shows the current BPM in real time.

Audio Input

Open Settings → Audio Input to select the audio source. BPM2OSC supports two capture modes:

Microphone / audio interface

Any device recognized by PortAudio (via sounddevice) appears in the device list. This includes USB audio interfaces, line-in inputs, built-in microphones, and virtual audio cables. Use a line-in connection from a mixer or DJ controller for the most stable results.

System loopback (Windows only)

Loopback devices appear in the list prefixed with . Selecting one captures whatever is playing through that output — no cable needed. Internally this uses the SoundCard WASAPI loopback API.

Loopback tip: if you use DJ software such as Serato or Rekordbox, set BPM2OSC to capture the master output loopback device so it picks up the DJ's headphone-cued mix rather than the room microphone.

Buffer size and latency

BufferLatency @44100 HzBest for
128~3 msImmediate VU monitoring; BPM less stable on sparse signals
256~6 msDJ sets with fast tempo changes
512~12 msLive events with a stable BPM ✓ recommended default
1024~23 msMaximum BPM stability; barely perceptible lag
2048~46 msVery irregular or sparse signals

Smoothing

Controls the depth of the BPM median filter (number of frames kept in history). Higher values produce a steadier readout but react more slowly to genuine tempo changes. The default of 5 is a good balance for most live situations.

BPM Controls

÷2 and ×2

Halve or double the BPM reported by the engine. Useful when the genre's rhythmic pattern causes the engine to lock to a subdivision (double tempo) or a macro-beat (half tempo).

When active, the ÷2 / ×2 buttons light up in the accent colour. If a multiplier override timeout is configured (Settings → BPM Override), the buttons blink during the last 3 seconds before expiry. Setting the timeout to 0 makes the multiplier permanent until manually reset.

The multiplier stacks: pressing ×2 twice gives ×4 (up to ×4 maximum). Pressing ÷2 resets towards ×1.

TAP tempo

Click TAP repeatedly in time with the beat to set the BPM manually. BPM2OSC averages the intervals between the last 8 taps. If more than 2.5 seconds pass between taps, the history is reset and you start a new sequence.

The TAP override expires after the configured TAP override secs (default: 4 s). Setting it to 0 keeps the TAP tempo indefinitely until you tap again or press LOCK.

Combined use: TAP the beat, then press LOCK immediately to hold the tapped BPM permanently, even after the TAP timeout would have expired.

LOCK and AUTO

LOCK freezes the current BPM, preventing the engine from updating the display and OSC output. The button shows a closed padlock icon 🔒 LOCK while active. Click it again to unlock.

AUTO-LOCK is a confidence-based automatic freeze. When enabled (Settings → BPM Override → Auto-lock below confidence %), the engine monitors its own confidence score and freezes the BPM whenever it falls below the threshold. The button shows 🔒 AUTO (with a coloured label) while the auto-lock is active. The status bar shows the current confidence percentage.

When to use auto-lock: during DJ transitions, breakdowns, or long a-cappella passages where the engine has no rhythmic signal. Values between 40% and 65% work well. Above 70% may freeze too eagerly on sparse percussion.
Manual LOCK takes priority. When you press LOCK, auto-lock is suspended — the BPM stays frozen regardless of confidence until you unlock manually.

RESYNC

Forces the internal metronome to realign its phase to the next engine-detected beat. Use this when the bar indicator has drifted out of sync with the music. RESYNC also sends a /resync 1 OSC message to all enabled targets.

Under normal conditions you should rarely need to press RESYNC — the engine continuously corrects the metronome phase using complex DFT beat-phase estimation.

Engine Presets

A preset is a named set of five engine parameters: BPM search range (min and max), Gaussian prior centre (prior), and the octave-correction gates (×2 gate and ÷2 gate).

Click any preset button in the preset bar to apply it live — no restart needed. The active preset is highlighted. You can also edit the five numeric values individually in Settings without changing the preset name.

Presetmin BPMmax BPMprior×2 gate÷2 gateTypical use
Auto6020012015590Default — most genres
Rock / Live6515510012895Rock, pop, live events
Ballad / Slow501057210560Slow songs, folk, cinematic
Dance / House11514512615580House, nu-disco, French touch
Hip-Hop / R&B701159011580Hip-hop, trap, R&B
Techno / D&B13018515818590Techno, drum & bass, hardstyle
Latin8512510012890Salsa, reggaeton, cumbia

What each parameter does

  • min / max BPM — defines the search range for the ACF peak. Values outside this range are ignored even if the ACF scores them highly.
  • prior — centre of a gentle Gaussian bias added to ACF scores. Slightly favours the expected tempo without overriding the data. Effect is small (±15% weight).
  • ×2 gate — BPM threshold above which the ×2 octave correction is allowed. If the detected BPM exceeds this gate, the engine checks whether the half-tempo lag scores ≥ 75% as high and, if so, halves the result.
  • ÷2 gate — BPM threshold below which the ÷2 correction is allowed. If the detected BPM falls below this gate, the engine checks the double-tempo lag similarly.

Creating and editing presets

In Settings → Engine Presets you can add new presets, rename existing ones, edit their five parameters, or delete them. Factory presets (built-in) can be reset to their defaults with the ⟳ button. Custom presets are stored in the config file.

AlgoMonitor

The Engine panel contains four real-time diagnostic widgets that expose the internal state of the detection algorithm. Updated at ~50 fps.

AlgoMonitor Engine panel with ODF waveform, BPM history, ACF score curve and 100% confidence bar

ODF waveform (top row)

ElementColourMeaning
Filled polygonDark greenArea under the Superflux ODF signal
sig lineBright greenPer-frame ODF value (spectral flux)
thr lineAmberAdaptive threshold: avg + 1.5 × σ over the last 43 frames
Vertical tickRedDetected onset (beat fired)

Right panel

WidgetMeaning
CONF barACF confidence from 0% (red) to 100% (green). Below ~40%: engine uncertain. Above ~70%: strong signal.
OCT badgeOctave correction last applied: ×2, ÷2, 4:3, or (none). Badge background turns red when active.
STAB ±valueStandard deviation of the last 20 BPM estimates. Green < 1 BPM, amber 1–3 BPM, red > 3 BPM.

BPM history graph (middle row)

Green filled chart of BPM estimates over the last ~40 seconds. The Y-axis auto-scales to the observed range ± 2 BPM. A green dot at the right edge marks the current BPM. Use this to spot drifts, jumps, or oscillations between two tempos.

ACF score curve (bottom row)

Purple curve showing the full ACF harmonic-sum scores across the BPM search range. The X-axis spans from min BPM to max BPM; vertical grid lines mark every 20 BPM. A green dashed vertical line marks the detected peak BPM with a numeric label.

A sharp, isolated peak means the engine is confident. A broad or multi-modal curve means the signal is ambiguous — consider enabling auto-lock.

Diagnostics in practice: if the ODF sig line rarely crosses thr, the audio level is too low — check gain. If CONF is chronically low but beats are clearly audible, switch preset. If OCT shows ÷2 constantly, you're in the wrong preset range — try one with a higher prior.

OSC Targets

BPM2OSC can send to any number of OSC destinations simultaneously. Each target is configured independently. Open Settings → OSC Targets and click + Add target to create a new one.

FieldDefaultNotes
NameDisplay label shown in the target dot and Settings list.
IP127.0.0.1Destination IP address or hostname.
Port8000UDP or TCP port on the destination.
ProtocolUDPUDP (fire-and-forget) or TCP (reliable, auto-reconnect every 15 s).
BPM path/bpmOSC address for the BPM float message.
Beat path/beatOSC address for the beat trigger (int 1).
Resync path/resyncOSC address for the resync trigger (int 1).
Send BPMonEnable/disable BPM messages for this target independently.
Send BeatonEnable/disable beat messages for this target.
Send ResynconEnable/disable resync messages for this target.
Normalize BPMoffMap BPM to a 0.0–1.0 float before sending.
Norm min / max20 / 500BPM range for the normalization mapping.
OSC target edit dialog for Resolume showing IP, port, OSC paths and BPM normalization

OSC target edit dialog — Resolume example with BPM normalization enabled

Target dot indicators

Each target has a coloured dot in the main window Targets panel:

  • Dark blue — idle (no recent send)
  • Yellow flash — UDP send in progress
  • Green flash — TCP send in progress
  • Grey with red X — TCP connection error (reconnecting automatically)

OSC Messages

/bpm float Current BPM value (e.g. 126.0). Sent on every change ≥ 0.05 BPM and every 10 s as a keepalive.
/beat int 1 Fires on every beat tick of the internal metronome. Phase-locked to the detected beat.
/resync int 1 Fires when the operator presses the RESYNC button.

Normalized BPM

When Normalize BPM is enabled on a target, the BPM float is mapped linearly to the range [0.0, 1.0] using:

value = (bpm - norm_min) / (norm_max - norm_min)
value = clamp(value, 0.0, 1.0)

With defaults (min=20, max=500): 120 BPM → 0.2, 200 BPM → 0.36. Adjust min and max to match your software's expected range.

Settings Reference

BPM2OSC Settings window showing Audio Input, Engine Presets, BPM Override and OSC Targets sections

Audio Input

ParameterDefaultNotes
DeviceSystem defaultAll input devices + loopback (Windows). Loopback devices are prefixed with ⟲.
Buffer size512Audio processing block size in samples. Larger = more stable BPM, higher latency.
Smoothing5Depth of the BPM median filter (number of estimates kept in history).
Auto-startoffIf enabled, detection starts automatically when BPM2OSC launches.

BPM Override

ParameterDefaultNotes
Multiplier override secs0How long ÷2/×2 stays active (seconds). 0 = permanent until manually reset.
TAP override secs4How long a TAP override stays active. 0 = permanent.
LOCK override secs0How long a manual LOCK stays active. 0 = permanent until unlocked.
Auto-lock confidence %0Confidence threshold for auto-lock (0–100). 0 = disabled. Values 40–65 are typical.

Config File

Settings are saved automatically to:

  • %APPDATA%\BPM2OSC\bpm2osc.json

The file is updated every time you click Save in Settings and on every clean shutdown. You can edit it manually with any text editor. Invalid values are silently ignored and replaced with defaults on the next launch.

{
  "audio_device_name": "Focusrite USB Audio",
  "audio_loopback": false,
  "buffer_size": 512,
  "smoothing": 5,
  "autostart": false,
  "auto_lock_confidence": 0.53,
  "multiplier_override_secs": 0.0,
  "tap_override_secs": 4.0,
  "lock_override_secs": 0.0,
  "preset": "Rock / Live",
  "min_bpm": 65,
  "max_bpm": 155,
  "prior_bpm": 100,
  "mul2_gate": 128,
  "div2_gate": 95,
  "targets": [
    {
      "name": "MagicQ",
      "ip": "192.168.1.100",
      "port": 8000,
      "protocol": "udp",
      "bpm_path": "/bpm",
      "beat_path": "/beat",
      "resync_path": "/resync",
      "send_bpm": true,
      "send_beat": true,
      "send_resync": true,
      "enabled": true,
      "bpm_normalize": false,
      "bpm_norm_min": 20.0,
      "bpm_norm_max": 500.0
    }
  ]
}

Integrations

ChamSys MagicQ

MagicQ does not accept BPM values via OSC. The correct approach is to map the /beat OSC message to a Speed Master Tap function via the Automation window. This makes MagicQ tap-tempo its Speed Master on every beat, keeping chase speeds locked to the music.

On the MagicQ side — one-time setup:

  1. Setup → Network → OSC → enable OSC RX, port 8000
  2. Open Macro → View Autom
  3. Add a new row (press the Insert soft-button or Add)
  4. Set Type = OSC
  5. Set P1 = /beat (the OSC address BPM2OSC sends)
  6. Set Function = Speed Master Tap
  7. Set P2 = 1 (Speed Master ID — SP1; change if you use a different Speed Master)
  8. In each Cue Stack that should follow the beat, set Speed Master = SP1

From this point on, every /beat message from BPM2OSC will tap the Speed Master, and all cue stacks assigned to SP1 will chase in sync with the music.

In BPM2OSC:

  • IP: MagicQ machine's IP address (or 127.0.0.1 if on the same machine)
  • Port: 8000
  • Protocol: UDP
  • Send BPM: off — Send Beat: on
  • Beat path: /beat
MagicQ supports up to 100 Speed Masters (SP1–SP100). If you need different cue stacks to run at different speeds, assign them to different Speed Masters and add one Autom row per Speed Master, each listening on a different OSC address.

Resolume Arena / Avenue

OSC target edit dialog for Resolume showing IP, port, OSC paths and BPM normalization

In BPM2OSC — OSC target settings:

  • IP: Resolume machine's IP address
  • Port: 7000 (Resolume default OSC input port)
  • Protocol: UDP
  • BPM path: /composition/tempocontroller/tempo — Send ✓
  • Beat path: /beat — Send off (Resolume handles its own beat grid)
  • Resync path: /composition/tempocontroller/resync — Send ✓
  • Enable Normalize BPM (0–1), min: 20.0, max: 500.0

On the Resolume side:

  1. Preferences → OSC → enable OSC input on port 7000
  2. The tempo controller path /composition/tempocontroller/tempo is built-in — no mapping needed
  3. Resolume expects a normalized 0–1 value for tempo, hence the BPM normalization above
Resync in Resolume: sending /composition/tempocontroller/resync triggers Resolume's internal beat-grid reset, keeping its visuals phase-locked to the music when the operator presses RESYNC in BPM2OSC.

Generic OSC (Bitfocus Companion, QLab, etc.)

Any software that can receive OSC over UDP or TCP will work. Point BPM2OSC at the destination IP and port, configure the OSC paths to match what the target software expects, and enable or disable individual message types (BPM, beat, resync) as needed.

Common use cases:

  • Bitfocus Companion: trigger buttons or macros on beat using /beat
  • QLab: use /bpm to feed tempo to a click track or time-based cue
  • TouchDesigner / vvvv: use /bpm and /beat to drive generative visuals
  • MIDI-to-OSC bridges: convert /beat to a MIDI clock pulse
Localhost testing: set IP to 127.0.0.1 and open any OSC monitor (e.g. Protokol) on the same port to verify messages before connecting real hardware.

Troubleshooting

BPM display shows wrong value

  • Try a different genre preset. Most detection errors are octave mistakes fixed by the right preset.
  • Check the AlgoMonitor ACF curve: if the peak is at a different position than expected, the prior may be pulling it. Adjust the preset's prior BPM.
  • Lower the buffer size if the display lags noticeably behind the music.
  • Increase the buffer size if the display oscillates between two values.
  • Use TAP to override temporarily while adjusting settings.

CONF bar stays low (red / yellow)

  • The audio level may be too low. Check the VU meter — the bars should reach the green zone on the beat.
  • Sparse percussion (breakbeats, half-time) is harder to detect. Try the Hip-Hop preset and enable auto-lock at ~50%.
  • During breakdowns or DJ transitions low confidence is expected — enable auto-lock to prevent the display from drifting.

No audio devices visible

  • Make sure your audio interface or microphone is plugged in before starting BPM2OSC.
  • On Windows, check that the device is not set to exclusive mode by another application.
  • Loopback devices require the output device to be active (playing audio).

OSC not received by the destination

  • Check IP address and port. On a single machine use 127.0.0.1; for network targets use the machine's LAN IP.
  • Check that no firewall is blocking UDP/TCP on the destination port.
  • Use an OSC monitor (e.g. Protokol) on the same machine as the destination to confirm packets arrive.
  • TCP targets show a connection error (grey dot with X) if they can't connect — verify the destination is listening before starting BPM2OSC.

Application doesn't start

  • Reinstalling BPM2OSC usually fixes startup issues — download the installer again from the website.
  • Check that %APPDATA%\BPM2OSC\bpm2osc.json is not corrupted. Delete it to reset to defaults.
Still stuck? Write to info@fblab.it with a description of the problem and, if possible, a screenshot of the AlgoMonitor panel.