Phrase Analysis Tool (+ energy, cue countdowns ...)

shown in French; the panel follows your Mac's system language automatically, no setting to change.

Hi all,

Like a lot of people here, I’ve wanted phrase analysis in djay Pro for years — it’s been requested since 2016 and djay has never shipped it, on any platform. rekordbox has had it for years (CDJ-only), but djay never got an equivalent.

So I built a companion app for it myself. It’s free, open source, and strictly read-only — it never writes anything to djay’s database, never touches your audio files, and never sends djay any commands. It just reads.

  1. To be upfront: this isn’t a polished commercial product. It’s a solo, spare-time project — it genuinely works, but it hasn’t been tested across many setups, libraries, or genres beyond mine. Expect some rough edges (see “What it doesn’t do” below for the known ones), and treat it as a work in progress rather than a finished release. Bug reports are genuinely welcome, not just a formality.

    A note on genre: I mix techno, and that shaped some of the design choices below — the structure/energy detection leans on kick presence/absence as the main signal, which is a reliable marker in techno but won’t generalize as cleanly to genres with sparser or less kick-driven structure (vocal-heavy house, hip-hop, etc.). The phrase counter and waveform are genre-agnostic and should work for anyone; the automatic structure labels and energy scale are the parts most likely to need retuning outside of techno/house-adjacent styles. Said so upfront so nobody’s surprised.

    A moderator’s note in advance: this tool works by reading djay’s own on-disk data formats (its live UI via macOS’s Accessibility API, its SQLite library database, and its per-track analysis cache), none of which is documented publicly. I’m posting this because I think it’s useful to the community, but I fully understand if Algoriddim/moderation would rather this kind of post not live here — happy for it to be removed if so, no hard feelings. The code and the full technical writeup live on GitHub regardless: https://github.com/yanchau/djay-phrase-tool.

    What it does

    It’s a small floating panel that sits on top of djay Pro (macOS only) and shows, live, per deck:

    • Phrase counter — which beat you’re on, which bar within the phrase, which phrase number, and a countdown to the next phrase boundary (16 or 32 beats, your choice per deck). This is the core feature — everything else builds on it.

    • Automatic calibrationdownbeat correction is a recurring ask here too; for any track djay has already analyzed (which in practice is almost every track in your library, since djay analyzes in the background even before you load a track), the phrase counter starts immediately with no setup. It reads djay’s own beatgrid analysis, and if you’ve corrected the grid yourself in djay (“Edit Grid”), that correction is read and takes priority automatically. A manual calibration shortcut (tap on the first kick) exists as a fallback for anything djay’s automatic analysis gets wrong, and is remembered per track.

    • Live scrolling waveform — a ~16-second window centered on your current position, colored by frequency band (bass/mid/treble, stacked-layer style similar to rekordbox’s 3-band waveform mode, which is also a popular open request here that djay doesn’t have). Works on streamed tracks (Apple Music/Spotify/SoundCloud) too, not just local files — it’s built from djay’s own cached waveform analysis, not the audio file itself, so DRM isn’t a blocker.

    • Full-track structure overview — the same 3-band coloring, zoomed out to the whole track, with a position marker — the kind of at-a-glance overview asked for here.

    • Automatic structure detection — intro / groove / break / drop / outro labels, detected from the kick pattern (presence/absence of bass energy) — the song breakdown requested here. Not perfect (see Limitations below) but genuinely useful as an at-a-glance guide.

    • Energy scale (1–10) — Mixed In Key-style, something people have otherwise had to go outside djay for, both a per-phrase level that moves with playback and a single whole-track score, derived from the same structure analysis.

    • Countdown to your own cue pointsanother long-requested feature, this reads the actual cue points you’ve placed in djay (ground truth, not a guess), with a countdown and bar number to the next one.

    • Suggested mix-out points — a countdown to the next detected break or the start of the outro, answering another open request here about djay’s Automix not finding good mix-out points (this doesn’t touch Automix, but gives you the same information to act on manually).

    • “Launch in sync” helper — when one deck is paused and the other is playing, shows exactly which bar number the playing deck will be at when you should press play on the paused one, so you don’t have to do the countdown math in your head.

    • Follows your Mac’s language — the panel’s own text is in French or English depending on your system language. Separately, it correctly reads djay Pro’s UI regardless of which language djay itself is set to (confirmed with djay running in French, where several of its accessibility labels are translated).

    What it doesn’t do

    • It cannot control djay in any way — no autoplay, no triggering cues, nothing. Purely a read-only display.

    • The automatic break/drop/transition detection is a heuristic over djay’s own cached, low-resolution waveform data (a few samples per second, not the real audio) — it’s good, not perfect. Your own cue points are shown as a separate, always-accurate source of truth alongside it.

    • It was built and tuned on techno, using kick presence/absence as the main structural signal. It’ll likely need different thresholds (or a different signal entirely) to be reliable on genres where the kick isn’t the dominant structural marker — I haven’t tested it outside techno/house-adjacent styles myself, so treat the structure labels and energy scale as unverified if you’re mixing something else. Reports from other genres welcome.

    • Local-files-only features from the original plan (e.g. full-resolution audio analysis with librosa) turned out to be unnecessary — djay’s own cached analysis was enough to make almost everything here work on streamed tracks too.

    Why I’m sharing the technical details too

    The GitHub repo includes a full writeup of djay’s internal data formats — the binary format used in its SQLite database, the structure of its per-track analysis cache, how the beatgrid/downbeat/cue-point/waveform data is laid out and decoded, what’s confirmed vs. still a hypothesis, and a couple of things I tried and couldn’t crack (musical key decoding, per-cue custom colors) in case someone else wants to pick those up. My hope is this is useful beyond just this one tool — for anyone else who wants to build something on top of djay’s own data, read-only, the way this project does.

    Feedback, bug reports, and pull requests all welcome. Thanks for reading!

    GitHub: https://github.com/yanchau/djay-phrase-tool



    How to use it

    Option A — Doing it yourself in Terminal (~2 minutes, free, no account needed)

    Nothing assumed here either — every click and every thing to copy is spelled out:

    1. Download the project. On the GitHub page, click the green Code button near the top, then Download ZIP. Once downloaded (usually lands in your Downloads folder), double-click the ZIP file to unzip it — you’ll get a folder called djay-phrase-tool-main.

    2. Open Terminal.

      • Press Cmd and the Space bar at the same time

      • A search box pops up in the middle of the screen — type Terminal

      • Press Enter

      • A window opens with a plain black or white background and some text — that’s it, that’s Terminal.

    3. Install the Xcode Command Line Tools (skip this step if you’ve already installed them before, for this or any other project):

      • Select this whole line of text (click right before xcode-select, hold, drag to the end) and copy it: Cmd + C

        xcode-select --install
        
        
      • Click once inside the Terminal window

      • Paste: Cmd + V

      • Press Enter

      • A macOS installer window pops up (separate from Terminal) — click Install, accept the license, wait for it to finish (a few minutes). This only downloads Apple’s own developer tools, nothing from this project.

    4. Grant Accessibility permission. Click the Apple menu (top-left corner of the screen) → System Settings → Privacy & Security → Accessibility, and turn on the toggle for Terminal (this is what lets the app read djay’s on-screen info — it may also prompt you for this automatically the first time you run the app in step 6, in which case just click Open System Settings in that prompt instead of navigating there yourself).

    5. Open djay Pro and load a track on at least one deck.

    6. Go into the downloaded folder and run the app. Back in the Terminal window:

      • Type cd (the letters c and d, then one space — don’t press Enter yet)

      • Open Finder, find the djay-phrase-tool-main folder from step 1, then find the PhraseCounterApp folder inside it, and drag that PhraseCounterApp folder icon straight into the Terminal window — its path appears after cd automatically

      • Press Enter

      • Select this line, copy it (Cmd + C):

        swift run PhraseCounterApp
        
        
      • Click inside the Terminal window, paste (Cmd + V), press Enter

      • The first run takes a minute or two (it’s compiling) — you’ll see text scrolling, that’s normal. Later runs are instant.

      (Prefer not to type any of this? After step 5, in Finder, just double-click Launch PhraseCounterApp.command at the top level of the djay-phrase-tool-main folder instead — first double-click needs a right-click → Open → Open to get past a macOS security prompt, then it’s a normal double-click every time after, no Terminal typing at all.)

    7. A floating panel appears above djay Pro (it has a close button in the top-right corner). For most tracks, the phrase counter starts immediately. If it says “searching djay’s database…” for more than a few seconds (a brand-new track djay hasn’t analyzed yet, or a very obscure edge case), tap ⌃⌥1 (deck 1) or ⌃⌥2 (deck 2) right on the first kick to calibrate manually — it’ll remember this per track from then on.

    8. Resize it by dragging any edge or corner — everything scales together, fonts included.

    9. To stop: close the panel, or click back in the Terminal window and press Ctrl + C.

    Option B — Never used Terminal or written code before? Let an AI assistant set it up for you

    This is genuinely how the tool itself was built . Needs a paid Claude plan or API credits (Claude Code isn’t free), but zero coding knowledge. Every step below is spelled out — nothing assumed:

    1. Download the project. On the GitHub page, click the green Code button near the top, then Download ZIP. Once downloaded (usually lands in your Downloads folder), double-click the ZIP file to unzip it — you’ll get a folder called djay-phrase-tool-main. Inside, you’ll see some files ending in .md (like README.md) — don’t double-click those. Double-clicking opens them as plain text with stray # and * symbols everywhere, which looks broken. They’re meant to be read on GitHub instead, where the same files display as normal formatted text with headings and bold — like the GitHub page itself, or the beginner guide linked at the end of this section.

    2. Open Terminal. This is a different app from anything you’ve probably used before, and that’s fine — you’ll only type into it, nothing complicated:

      • Press Cmd and the Space bar at the same time

      • A search box pops up in the middle of the screen — type Terminal

      • Press Enter

      • A window opens with a plain black or white background and some text — that’s it, that’s Terminal, working as intended.

    3. Install Claude Code. This is the one thing you’re installing. In the Terminal window:

      • Select this whole line of text (click right before npm, hold, drag to the end) and copy it: Cmd + C

        npm install -g @anthropic-ai/claude-code
        
        
      • Click once inside the Terminal window (to make sure it’s the active window)

      • Paste: Cmd + V

      • Press Enter

      • Wait a few seconds until you see the cursor again (a blinking % or $). If instead you see command not found: npm, go install Node.js from nodejs.org (the “LTS” button) first, then repeat this step.

    4. Go into the downloaded folder and start Claude Code. Still in the same Terminal window:

      • Type cd (that’s the two letters c and d, then one space — don’t press Enter yet)

      • Open Finder, find the djay-phrase-tool-main folder from step 1, and drag that folder icon straight into the Terminal window — its full path appears after cd automatically

      • Press Enter

      • Type claude and press Enter

      • The first time only, it’ll ask you to pick a color theme (any is fine, press Enter) and to log in with your Anthropic account — follow what’s on screen.

    5. Ask it to do the rest. Once you see a > waiting for input, type this (or just say it in your own words, any language):

      Please set this up and run it for me. I've never used a terminal before,
      so explain each step simply and ask before doing anything that needs my
      permission.
      
      

      Press Enter. It’ll read the project’s README, install anything still missing, walk you through granting the one macOS permission it needs (Accessibility — explained in the README’s Safety section), and start the app — asking your approval first, in plain language, before anything that changes your Mac.

    Full version of this path with troubleshooting: GETTING-STARTED-FOR-BEGINNERS.md — just click, it opens straight in your browser, nicely formatted, nothing to download first.

    Thanks Yan


8 Likes

Very cool! Thanks for sharing @Yan

3 Likes

Very cool!

You didn’t want to just compile and release a an unsigned DMG or app? While getting users to use Xcode and compile and sign themselves, for the average user - bypassing Gatekeeper is much easier with the x -attr command, no?

1 Like

Good point — added exactly that since your comment. There’s now a prebuilt, unsigned .app on the Releases page — that’s now the method I’d point the average/casual user to if they just want to try it, no Xcode, no Terminal, no compiling. Every click, nothing assumed:

:warning: djay Pro needs to already be open, with a track loaded on at least one deck, before you launch this app (step 6 below). It only checks once, at launch — skip this and you’ll get a clear “djay Pro doesn’t appear to be running” error, easy to avoid by just doing djay Pro first. Probably the single most common snag, so flagging it upfront.

  1. Go to the Releases page. Releases page — GitHub’s page for finished, downloadable versions of the project, as opposed to the source code.

  2. Download the app. Scroll down slightly to a section called Assets, and click PhraseCounterApp-macOS.zip to download it. Lands in your Downloads folder like any other download.

  3. Unzip it. Double-click PhraseCounterApp-macOS.zip in Finder (or in your browser’s download bar). This creates PhraseCounterApp.app next to it — that’s the actual app.

  4. Move it somewhere permanent (optional): drag PhraseCounterApp.app into your Applications folder. Skippable — it’ll also run fine straight from Downloads.

  5. Open djay Pro and load a track on at least one deck — do this now, before the next step (see the warning above).

  6. Open the app for the first time — one extra click since the app is unsigned (no Apple Developer ID behind this project):

    • Don’t double-click it — macOS will refuse and say it’s “from an unidentified developer.” Normal, expected, not an error.

    • Right-click (or Ctrl-click) PhraseCounterApp.app

    • Choose Open

    • A dialog warns it’s from an unidentified developer — click Open again

    • Only asks once. Normal double-click works every time after.

  7. Grant Accessibility permission. First real launch, macOS asks for this — it’s what lets the app read djay Pro’s on-screen info. Click Open System Settings in that prompt and enable PhraseCounterApp, or go there yourself: Apple menu → System Settings → Privacy & Security → Accessibility.

  8. Floating panel appears above djay Pro — phrase counter, waveform, structure, energy, cue countdowns, same as everything described in my post above.

(Compile-from-source and the Claude Code path from my original post are both still there too, for the “read the code first” route or a fully hand-held setup — this is just the fastest one. Full step-by-step, including a couple of rarer troubleshooting notes, is in the README.)

1 Like

This is awesome ! managed to get it working. Although. Point 8. Floating panel appears above djay Pro — phrase counter, waveform, structure, energy, cue countdowns, same as everything described in my post above.

Does not seem to work for me. Or is this the floating panel ur referring too. If thats the case it Kinda blocks a lot of DJay Pro screen. And therefore kinda of a downer :frowning: Either way good job. Just wished I could with the floating panel better along with DJay Pro. :slight_smile:

3 Likes

I would just submit an issue on your GitHub page but you have Issues disabled.
I installed, bypassed gatekeeper, enabled Accessibility, allowed access to other apps (pops up on every launch, btw)… but the window is still blank. (screenshot shows pop up, but PhraseCounterApp remains blank after).

I’m guessing there’s an issue with cache folder access, but the app does not ask for access to any specific folders.

Agreed. It shows a lot of information, but so much that it requires a separate screen to be used during performance.

If the UI could be minimized to only cover the top toolbar (horizontal space), or a few lines of the library on the bottom, maybe that way it would work for performance.

2 Likes

Yes. Personally i would prefer a rectangular banner shape. That would lie on top. We already have waveforms and tbh the most important value is the countdown to next cue and phrase analysis. Rest is useless for my workflow. Either the idea and concept is very good since Djay won’t do these 2 important features. Just my opinion. Well done !

2 Likes

I agree with @skymakai and @Jay_Dizzle. Simplifying the interface by removing unnecessary information and making it a long “landscape” orientation across the width of the screen would make it a better overlay for djay. Fantastic work on this!

2 Likes

Ok i will work on it . Thanks for your feed back. Normaly the window is resizable but in didn’t work a lot on tbe responsive design

1 Like

You’re welcome!

@Jay_Dizzle @skymakai @Slak_Jaw — you were all right, and it’s done. v1.1.0 replaces the tall two-column panel with a compact horizontal banner, and fixes the permission loop.

GitHub: https://github.com/yanchau/djay-phrase-tool — download the ready-to-run app from the Releases page, or compile from source; both walked through in the README.

The banner — one thin row per deck, landscape across the screen, as suggested. What survived the cut: phrase number, bar/beat position, countdown to the next phrase boundary (now in bars, not just seconds), the section badge, and the cue / mix-out / next-change countdowns. What’s gone: the scrolling waveform and the energy scale — djay already draws a better waveform than I ever could, right underneath, so that was screen space spent duplicating what’s already there.

Everything is colour-coded consistently (violet = phrase, cyan = your own cue point, orange = suggested mix-out, red = boundary imminent), and every number has a hover tooltip explaining what it is — no need to memorise the layout.

The permission popup on every launch — thanks for reporting that @skymakai, it was a real bug, and the cause was dumber than expected. macOS ties permissions to an app’s exact code signature, and swift run recompiles a bare binary with a new signature every single time — so every launch looked like a brand-new app and asked again, forever. The launcher now builds a proper .app bundle with a fixed identity, so you grant it once and it stays granted across rebuilds.

The blank window was almost certainly the same problem wearing a different hat: Accessibility not actually granted, with the app failing silently instead of saying so. It now shows a real error dialog telling you what’s missing, rather than opening an empty panel.

If you already installed the earlier version

First, grab v1.1.0 from the Releases page and replace the old app.

Then, if anything still looks stuck — the counter never leaves “not calibrated”, a permission popup keeps coming back, or nothing happens at all when you open it — it’s the old Accessibility entry, which can get wedged in a state where toggling it off/on in place does nothing. This exact sequence has cleared it every time, one click at a time, no Terminal needed:

  1. Open System Settings. Apple menu (top-left corner) → System Settings. Or Cmd + Space, type System Settings, Enter.

  2. Go to Accessibility. In the left sidebar click Privacy & Security, then scroll down the right-hand list and click Accessibility.

Remove the old entry. Find PhraseCounterApp in the list, click it once to select it, then click the (minus) button just below the list. Do this even if its toggle already looks “on” — a stale entry can look enabled without actually being granted.

  1. Launch the app — double-click PhraseCounterApp.app, or Launch PhraseCounterApp.command if you compiled from source.

  2. Click OK on the alert. An error dialog appears (“Can’t start” / “Impossible de démarrer”). This is expected at this point, not a bug — click OK to dismiss it.

  3. Go back to Accessibility — same path as step 2. PhraseCounterApp is listed again: macOS re-adds it automatically the moment the app tries to use Accessibility and gets refused.

  4. Grant it. Turn the toggle next to PhraseCounterApp on.

  5. Open the app again. It should now show real data from djay Pro.

Why it happens: macOS ties Accessibility permission to the app’s exact signature, and a stale or half-granted entry can get stuck where toggling it in place doesn’t take effect. Removing it and letting the app re-request from scratch clears it reliably.

(Same steps, always up to date, live in the README’s Troubleshooting section.)

And if you actually preferred the older, more visual version — full scrolling waveform, energy scale — it isn’t gone: source, README and screenshot are preserved as-is at the v1.0.0 tag.

Thanks again for the feedback — the compact version is genuinely better than what I’d have built alone.

2 Likes

Very nice @Yan!

1 Like

Hello,

One feature I wanted but couldn’t crack: having the cue-point countdown display in the colour of the next cue. I couldn’t work out how cue colours are encoded/assigned in djay’s data — it’s one of the two things (along with musical key) I mention in the writeup as still unsolved. If anyone has decoded the per-cue colour logic, a pointer would be very welcome.

1 Like

Excelent work. I’ll test it out tomorrow.

1 Like

Hi @Yan . Can Confirm it works. And very well.

Although for me I’m only interested in The Beats/bars to next cue point and the Phrase. Theres some irrelevant info (At least for me) that I don’t understand nor interested in seeing.

Screenshot 2026-07-26 at 14.50.18

After Intro, like the pic shows. That info is none important to me. Simplifying this and making it more obvious and easy to read the Phrase and Beats to cue is the most important factor I believe and I think most will agree :slight_smile:

Theres also one thing that would have made this 100 workable for me. And that is. Not having them stacked. I would love having Deck one above deck one (Djay Pro) and deck to above Deck two (Djay). That would be amazing !

Again super well done from your part. and this is all constructive criticism and my opinions only :slight_smile:

1 Like

@Jay_Dizzle hi you I will have a look on your suggestion:
i will cancel exit (not useful) and the grey for next change (all infos already on the waveform).
i will check design improvement : two individuals bars that you can move on the top of each deck

Hey @Jay_Dizzle@Slak_Jaw @skymakai following up on your feedback (and thanks again for testing this in real conditions, it’s exactly the kind of report that’s useful).

Per what I said I’d look at:

i will cancel exit (not useful) and the grey for next change (all infos already on the waveform). i will check design improvement : two individuals bars that you can move on the top of each deck

Both are done:

Dropped the “exit” (orange) and “next change” (grey) countdowns. Kept: phrase number + countdown, the structure badge (GROOVE/INTRO/BREAK/DROP/OUTRO), your own cue point countdown, and the press-play-in-sync hint.

Two independent panels instead of one combined banner. Each deck now gets its own small floating panel, auto-positioned above that deck in djay Pro at launch. Each one is freely movable and resizable on its own — drag it wherever you actually want it, it stays there. Closing either one closes the app (it’s one process, not two).

New release is up: v1.2.1 — same setup instructions as before, either compile from source or grab the prebuilt .app. Heads up: the auto-positioning above each deck is a best-effort read of djay’s own layout, not a guarantee — if it lands a little off on your setup, just drag it where you want; it won’t reposition itself again on its own.

(v1.2.1 rather than v1.2.0 — caught and fixed a rare bug of my own right before posting this: the cue-point countdown could occasionally show a nonsense huge number instead of a real countdown on certain tracks. Same panels, same features, just that one fix.)

For everyone else who preferred the fuller combined-banner view (or the very first tall-column version) — both are still available and not going anywhere; this is a new option alongside them, not a replacement. Links to all versions are at the top of the README.

One open question while I’m here: should the structure badge (INTRO / GROOVE / BREAK / DROP / OUTRO) go the same way? Your argument about the grey countdown applies to it just as well — it’s automatic detection rather than ground truth, and djay’s own waveform already shows you the structure at a glance. It’s also the least reliable thing left in the panel, since it’s a heuristic over djay’s low-resolution cached waveform. I still find it useful myself as a quick read, but I’m not convinced it earns its space for everyone. Happy to drop it, make it optional, or leave it — opinions welcome before I touch anything.


Reminder for anyone hitting a permission error or a panel stuck on “not calibrated”: this sequence has been reliable every time —

  1. Open System Settings (Apple menu → System Settings, or Cmd+Space → type “System Settings” → Enter).

  2. Privacy & Security in the sidebar → Accessibility in the list on the right.

  3. Find PhraseCounterApp, select it, click to remove it — even if its toggle already looks on (a stale entry can look enabled but not actually be granted).

  4. Launch the app (double-click Launch PhraseCounterApp.command, or however you normally open it).

  5. It’ll show an error dialog — expected at this point, not a bug. Click OK.

  6. Go back to System Settings → Privacy & Security → Accessibility — PhraseCounterApp should be listed again.

  7. Turn its toggle on.

  8. Reopen the launcher one more time. It should now show real data.

Full write-up (including why this happens) is in the README’s Troubleshooting section.

1 Like

I appreciate your work.
(Edit: I’m trying to use the pre-built app.)
I’ve followed your instructions, but unfortunately the app still isn’t working for me.
I still get a pop-up when launching, to allow app permission to control other apps. Control+Option+1 On Kick has no effect. I don’t get data.

A couple other observations:

  1. The panels cannot be resized, so screen resolution must be at least 1800x1169… it does not work on the default screen resolution of the 14” MacBook Pro.
  2. The D1 and D2 windows are different shapes (Edit: depends on whether track is loaded)
  3. The tooltip pop ups do not fully show.

Image: Tool Tips

Image: Default Screen Resolution

Hi, sorry to hear this I will work on it but not before friday.

There is a known bug when you open the app with the library expanded. (please expand and close it several time )
Don’t forget to load a track before to open the app.
All tracks should be analyse by Djay (trouble with playlist imported from traktor ???), please try to analyse the same track with Djay pro and let me know and load it before to open the app.
Do the same thing with a local file on your computer and with a new Apple Music track and give me feedback please.
Nothing happen when you try to resize the panel ( arrow on the right ) or to move IT in another place ?
Be sure to follow all the 8 points of the “Reminder for anyone hitting a permission error or a panel stuck on “not calibrated”"
sorry but be sure that we will find a solution

1 Like