Beat Analyzer
At a glance
The beat-analyzer is the system’s beat clock and its level meters. It has no box and no screen of its own: it is a program on the A³ Core machine, sitting on the same JACK audio graph as REAPER.
It does two jobs:
The beat. It sends
/beat— the beat in the bar, the bar and the tempo — to the devices. A³ Motion follows it in EXT and PIO, the A³ Mixer’s tap keys blink with it.The meters. Twelve peak/RMS meters, 25 times a second. The coronas around A³ Motion’s channel blobs, the glow of its sphere, the lightning of its speakers and the A³ Mixer’s VU meters all come from here.
Where the beat comes from is your choice, and you make it on A³ Motion’s clock key.
beat-analyzer repository — not under the
a3-audioorganisation, but part of the same system and versioned along with itBuilt on BTrack for the tempo detection
Clock modes
The beat-analyzer has three clock modes. A³ Motion’s clock key picks one: each
tap on the key steps INT → EXT → PIO and tells the beat-analyzer the new mode
with /clockmode.
A³ Motion reads |
|
Mode |
Where the beat comes from |
|---|---|---|---|
INT |
0 |
a3motion |
A³ Motion. You tap the tempo on Motion, Motion sends |
EXT |
1 |
intern |
The music. The beat-analyzer listens to the audio and finds the beat itself |
PIO |
2 |
pioneer |
The Pro DJ Link tempo master — a CDJ, or StemDeck as master |
What each mode needs
INT — a3motion. Nothing but A³ Motion. Motion sends its own /beat to
port 7775; the beat-analyzer relays each one to every target in its
configuration except the one named motion, so Motion never hears its
own beat come back. In this mode the beat-analyzer’s own clock is paused,
and a /tap it receives does nothing here.
EXT — intern. Music on the beat-analyzer’s input. Its JACK input bpm_1
is patched from REAPER by Core’s patchbay, so whatever REAPER hands it is what
it listens to. From that it finds onsets and a tempo, and a clock of its own
counts the beats — it keeps counting between detected beats, and at the last
tempo if the music stops. Tapping works here:
The first tap after a pause of more than two seconds sets the one: the beat restarts at 1, at the tempo it had.
From the second tap on, the tempo is taken from your taps (the middle of the last eight intervals); from the third on, every tap also puts the beat back on 1.
A tapped tempo outside
BPM_MIN–BPM_MAXis ignored.
Warning
A tapped tempo stays. Once you have tapped a tempo in EXT, the beat-analyzer keeps it: it still follows the music’s beats for the phase, but no longer changes its tempo by itself. A new tempo takes new taps; the analysis only goes back to finding the tempo on its own after the beat-analyzer is restarted.
PIO — pioneer. A Pro DJ Link network the Core machine is on. The beat-analyzer joins it as a virtual CDJ, number 7, and listens on UDP ports 50000–50002. It follows the tempo master: the player whose status says master while it plays. Until it has heard who the master is, it takes the beats of any player. The tempo it sends is the master’s track tempo with its pitch applied — what the master’s display shows.
The Pro DJ Link beat says where the beat is in the bar, not which bar it is,
so in PIO the bar number in /beat is always 0.
Note
No CDJs? Use StemDeck as the master. StemDeck can be the tempo master on the link by itself, and PIO then follows StemDeck exactly as it would follow a CDJ. See Playing without CDJs.
Switching modes by hand
A³ Motion’s clock key is the normal way. Anything that can send OSC can do the
same — /clockmode with an integer to port 7775 on the Core machine. With
oscsend from liblo-tools, on the Core machine itself:
oscsend localhost 7775 /clockmode i 2 # 0 a3motion, 1 intern, 2 pioneer
A value outside 0–2 is clamped to the nearest mode. A³ Motion does not hear about a change made this way: its clock key keeps showing what it showed.
Playing without CDJs: StemDeck as the tempo master
With no CDJs in the booth, StemDeck can drive the whole clock. The chain, as the code runs it:
StemDeck, deck with MASTER on
│ Pro DJ Link: a beat packet on every beat, a status packet every 200 ms,
│ as virtual CDJ 6, sent as broadcast on UDP 50001 / 50002
▼
beat-analyzer, clock mode 2 (pioneer), virtual CDJ 7
│ takes StemDeck as the tempo master: it says master, and it plays
│ /beat beat-in-bar, 0, bpm
▼
A³ Motion on PIO, A³ Mixer's tap keys, every other /beat target
Start StemDeck and load a set on a deck. Wait for the BPM readout: a deck sends nothing until its tempo analysis is done.
Press MASTER on that deck — or just press PLAY on it: with no master chosen, the only playing deck becomes master by itself (not under SYNC: PIO, and not once you have turned MASTER off by hand). The top bar reads
PIO master: A(or B).On A³ Motion, tap the clock key until it reads PIO.
The BPM on A³ Motion now follows the master deck, tempo fader included.
Where the one is. StemDeck counts the bar from the first beat of the track’s beat grid, not from anything it knows about the music. If A³ Motion’s downbeat falls on the wrong beat, that is where to look.
A stopped master stays master and sends no beats. A³ Motion then carries on at the last tempo it had, as it does whenever the beats stop.
The same works on one machine: StemDeck and the beat-analyzer both listen on ports 50000–50002, and because StemDeck sends as broadcast, both of them get every packet regardless of which started first.
The meters
The beat-analyzer measures twelve JACK inputs, vu_1 … vu_12, and sends
each as a peak and an RMS value between 0 and 1, all twelve in one packet.
It gives a channel no meaning of its own: which signal is on which meter is
decided by the JACK patching alone. In the A³ setup:
JACK input |
OSC address |
Signal |
A³ Motion shows it as |
|---|---|---|---|
|
|
mixer channels 1–4 |
the corona around each channel blob |
|
|
subwoofer |
the glow of the sphere |
|
|
speakers 1–4 |
the lightning of each speaker |
|
|
– |
unused |
The inputs count from 1, the addresses from 0: vu_N arrives as
/vu/(N-1). Patch with the OSC numbers in mind and every meter lands one
channel across — and still looks plausible.
Where it runs and where its settings live
The beat-analyzer runs on the A³ Core machine as the systemd --user service
beat-analyzer.service, started and stopped together with the rest of Core
(it is part of a3-main.service). The a3-core package installs the unit and
builds the program from the beat-analyzer checkout in the a3-system
workspace.
Its settings are a .env file in its working directory, build/ in the
beat-analyzer checkout. It reads, in this order, the first of:
build/.env.envone directory up, in the checkout itself.env.examplein the working directory
and with none of them, it sends to a single target on 127.0.0.1:9000. The
template is .env.example in the checkout:
cp .env.example build/.env
The settings that matter most:
Setting |
What it does |
|---|---|
|
one target for |
|
a separate port for that target’s meters, so |
|
where |
|
the tempo range the clock counts in. A tempo outside it is doubled or halved into it |
|
its player number on the Pro DJ Link network. 7 |
|
how many meters. 12 |
|
meter updates per second. 25 |
|
how fast the meters rise and fall |
|
print every beat, or every Pro DJ Link beat, to the log |
The settings are read at start. After a change, restart the service:
systemctl --user restart beat-analyzer
The clock mode is not a setting. The beat-analyzer always starts in mode 1 (intern) and changes when it is told to.
Which port on which device gets what is listed, as measured on the rig, in Ports and endpoints. The messages themselves are in the OSC reference.
Troubleshooting
Symptom |
What to do |
|---|---|
A³ Motion reads PIO or EXT, but the tempo follows the wrong source |
The beat-analyzer restarted, or started after A³ Motion, and is back in its start mode (intern). Tap Motion’s clock key once round, back to the mode you want: every step tells the beat-analyzer again |
EXT: no beat, the BPM stands still |
Is the service running ( |
EXT: half or double your tempo |
Set |
EXT: the tempo no longer follows the track |
You tapped: a tapped tempo stays. Tap the new tempo, or restart the service |
PIO: nothing arrives |
The Core machine has to be on the same network as the players, and nothing else on it may hold ports 50000–50002 exclusively. The log says |
PIO: it follows the wrong player |
It follows whoever says master while playing. Set master on the player you mean |
The meters all sit one channel across |
The JACK patching is off by one: |
The meters don’t move at all |
Check the service, then the |
Its log is the service’s journal:
journalctl --user -u beat-analyzer -f
With DEBUG_BEAT_CONSOLE=1 it prints a line per beat with the tempo and how
far the beat was off; with DEBUG_PIONEER_CONSOLE=1, a line per Pro DJ Link
beat, naming the player and whether it is master.