In Ableton
- Put each song's LTC wav on its own audio track, named something obvious like
LTC OUT.
- Warp OFF. This is the one that ruins shows — warping stretches the signal and the
desk drifts or drops lock. Clear transpose and fades too.
- Clip gain 0 dB, nothing on the track: no EQ, compression, reverb or limiter.
Route it straight to a hardware output, not through Master.
- Match Ableton's sample rate to the file so it isn't resampled.
- Line the LTC clip up with the start of the song audio.
Splitting to both machines
One output, two destinations. A passive Y works over short runs, but a distro amp or a
spare console aux is safer — paralleling two inputs drops the level, and LTC is the one
signal you don't want marginal. Balanced cable on long runs, dedicated output, never summed
into a mix bus. If either machine reads intermittently, push the level up a few dB
rather than down.
grandMA3
- LTC goes into the 3-pin female XLR marked LTC on the station. onPC on a laptop
has no LTC input of its own — you need a console, processing unit or node with that XLR.
- Gear icon (or
Menu) → Connector Configuration →
SMPTE Mode = In, then assign your slot in the SMPTE TC column.
- It takes up to 8 external timecode signals at once, so songs can live in separate slots.
- Set Pre Roll (how long the signal must be present before the desk trusts it) and
After Roll (keeps the clock running for a moment if the feed drops).
- Slot settings live on the console, not in the show file — re-check them at every rig.
ProPresenter
View → Timecode, then the gear icon: pick the audio device,
the channel, the format (match your frame rate) and an offset if it
needs nudging against the lighting.
- The speaker icon monitors the incoming signal — confirm the feed is arriving before
hunting for other problems.
- Status reads Playing, Stopped or Not Engaged. "Not Engaged" means
triggering is off, the usual reason a correctly wired feed does nothing.
- Its audio input must not be doing anything else.
Set both to the same frame rate as the files. Mismatched rate is the second most
common failure after warping, and it fails in the ugly way — it looks locked, then drifts.
Why 10-minute files in 15-minute blocks
- Song 1 at 00:00:00:00, song 2 at 00:15:00:00, song 3 at 00:30:00:00 — every song has a
fixed address you can build cues against before you've heard a note.
- Each file runs a full 10 minutes, so an arrangement that grows in rehearsal doesn't
cost you a regenerate.
- The extra 5 minutes is spacing in the address map, not signal — the file is
still exactly 10:00 long. Nothing is rendered into the gap; it's simply room between
one song's last frame and the next song's first, so nothing overlaps and every
address in the show is unique.
- Song 1 at all zeros can read as "no signal" on some desks. If that bites you, push it
to 00:15:00:00 and leave block 0 empty.
Reading a screenshot
A plan is a table, so it's read as one rather than as a page of text. That matters:
reading the whole screenshot in one go means the drag handle, the length column, the title
and the key badge all compete, and the mistakes land in the song name where you can't see
them.
- The key badge anchors every row. It's found by colour — any solid colour, not
just blue — so it survives a restyle, and it can't be garbled the way text can. A row
with a badge is a song; the header, Ministry Moments, chart notes and Dismiss are
dropped rather than left for you to untick.
- Each title is cut out and read on its own, enlarged, as a single line, with the
handle and the length column outside the frame and the badge marking where the title
ends. The length is read from its own column, and the badge from its own pixels —
repainted to black on white first, which is the difference between reading
Bb
and reading nothing.
- Your library is the dictionary. A title that matches a song you already have is
corrected to that spelling, which is how a small screenshot still lands exactly right
from the second week a song is used.
- Nothing is presented as read unless the library can vouch for it. A song that's
new to you is tagged new — check: look at the spelling once, because it becomes
the filename. A near-match shows what was actually read. A row that plainly broke is
tagged read?. This is the part that makes it safe on a Sunday — a wrong title
is never presented as a correct one.
- Measured against 16 generated plans — different fonts, type sizes, row heights, light
and dark, 1× and 2× screens, awkward titles — 14 came back exactly right. The two that
didn't were 13px type on a 1× screen, about nine pixels of letter, and in both the
affected row was flagged rather than passed off as read. With those songs in the
library, both read exactly right too.
- For the cleanest read, screenshot on a Retina display, or zoom the plan to 150% in the
browser first. Pasting the text still beats any of this.
Arrangements
- A song can have more than one arrangement, and each one is its own row in the
library with its own name, length, notes and address. Rows that share a song title are
arrangements of that song; the first one listed is the default.
- Whenever a title is recognised — off a screenshot, a pasted plan, a dropped audio
file, or just typed into the set list — the page asks which arrangement you mean and
opens on the default. Nothing is guessed silently.
- Name it for what changed: "Sunday cut", "Acoustic", "No bridge". The name goes
in the filename, so at the desk you can tell two cuts apart without opening either.
Notes are for the detail — "tag out, extra chorus" — and travel in the CSV.
- A new arrangement takes the next free block rather than sharing the original's
address. Different length, different cues, different address.
- Drop the audio in and the page compares its real length against the arrangement you
picked — a file running 4:40 against a 10:00 arrangement gets flagged as probably a
different cut.
- The one you didn't use stays in the library holding its address, switched off. Use
the arrangements chip on a row to swap this service over to another.
Keeping it in Dropbox
- Put this HTML file and
songs.csv in the shared folder. Everyone opens the
same page, and the library travels with it.
- Connect… in the Library panel points the page straight at that CSV. After that,
Save writes back into the Dropbox folder — no downloads, no dragging files
around, and Dropbox syncs it to the rest of the team. Chrome and Edge only; other
browsers fall back to Open/Save downloads.
- Folder… does the same for the audio: pick a folder in Dropbox and
Render writes the WAVs straight into it instead of downloading a ZIP, so every
song's timecode file is archived where the team can get back to it. The library CSV is
saved alongside them automatically, so the
file column always names files
that are really there.
- Re-rendering skips any file that is already byte-for-byte correct, so a rebuild
after adding one song re-uploads one song, not the whole set.
- Budget for the size: a 10-minute file at 48 kHz is about 57 MB, so a five-song service
is roughly 290 MB. If the quota gets tight, keep the CSV synced everywhere and put the
audio folder on selective sync — the CSV regenerates byte-identical audio on any
machine, from this page or
ltcgen.py.
- You have to reconnect the file and the folder once per session — the page holds no
browser storage by design.
- Safari can't write files in place, and can't be given a destination. Apple
ships no part of the File System Access API — no version, no flag — and no browser
anywhere lets a web page choose where a download goes. So the destination is a Safari
setting, not something this page can control:
Safari ▸ Settings ▸ General ▸ File download location ▸ Other…, and pick your
Dropbox folder. Save and Render then land there on their own.
- There is an "Ask for Each Download" option that looks like the right answer.
Don't rely on it — it's a long-running Safari bug that frequently ignores you and
saves to Downloads anyway. A fixed folder is the one that behaves.
- Render packs the library into the ZIP alongside the audio, so unzipping into
Dropbox gives you the WAVs and the
songs.csv that names them, in one
move. Files are stamped with the date and time they were made.
- Safari writes "songs 2.csv" rather than replacing the original, so bin the
numbered copies and keep one
songs.csv. Open one by accident and you'll
build next week's set from last week's addresses — the page now says so when you
open a numbered file.
- On an iPad, Share… hands the library to the share sheet: choose Save to Files
and pick the Dropbox folder. Text… shows the library to copy and paste, and
works in every browser ever made.
- The person building the set is better off in Chrome or Edge, where
Connect… and Folder… write straight into Dropbox, in place, with no
duplicates and no settings. Safari is fine for everyone else. Addresses and filenames
are identical whichever browser built them.
- If two people edit at once Dropbox makes a "conflicted copy". Whoever is building the
set that week should own the file.
Reading the CSV when something's wrong
The library file is written to be read at 9am with the band waiting. Lines starting with
# are notes and are ignored on load; the columns line up so you can scan them in
any text editor.
song and arrangement — which cut this row is.
start_tc — the address the desk locks to. Written in means pinned
forever; blank means it gets the next free block on the next import.
end_tc and file — worked out from the row and rewritten on
every save. file is the exact WAV this row renders to, so you can go from
a cue that didn't fire, to the address, to the file on disk, in one line. Blank means
the row isn't in this week's service.
notes — yours. What's different about this arrangement.
Choosing the folder, in any browser
No browser lets a web page choose where a file is saved, and Safari has no file-writing
API at all. The way round it is to run the page from your own machine, so there is something
here that can write on its behalf.
- Put
LTC-Timecode-Generator.html, ltcgen.py and
Start LTC Helper.command in the Dropbox timecode folder.
- Double-click Start LTC Helper.command. A Terminal window opens and your browser
opens at the page, already pointed at that folder. (The first time, macOS may ask —
right-click the file and choose Open.)
- Save and Render now write straight into the folder. No downloads, no
"songs 2.csv", and Folder… in the Library panel switches to any other folder
you like.
- Close the Terminal window when you're finished.
- Running two at once is fine — one for Sunday, one for Saturday. The second
takes the next free port and says so, each writes only into its own folder, and the
browser tab is titled with the folder name so you can tell them apart. Point two at
the same folder and it warns you, because then it's last-save-wins.
It listens on this machine only, refuses anything outside your home folder and mounted
drives, and ignores requests coming from other websites. Everything still works with it
switched off — you're back to downloads, and Chrome or Edge can still write in place on
their own.
Lost the CSV?
The library can be rebuilt from the timecode files themselves. Every file states its own
address in its audio, and its name says which song and arrangement it is — so a folder of
renders is a library that just needs reading back.
- Rebuild… in the Library panel, or drop the folder of WAVs onto the audio box.
Each file's start address, frame rate and exact length are read back off the signal
and pinned, so every cue you've already built still lines up.
- Only the head of each file is read, not the whole 57 MB, so a full set takes seconds.
03_Way Maker (Sunday cut).wav comes back as the song Way Maker with
the arrangement Sunday cut — but only when a plain Way Maker is sitting
beside it. On its own, a title like Oh What A Grace (How Marvelous) keeps its
brackets, because that's the title.
- Then Save. That's the CSV back, and the operation with it.
- Dropping timecode files on the audio box no longer adds them as if they were songs —
it offers to rebuild instead.
Keeping addresses stable
Once a song has been generated and cued, its address must never move. Hit
Pin addresses and save — every song then carries an explicit start timecode, and
future imports can only ever hand out blocks nobody has claimed. Songs dropped from this
week stay in the library holding their blocks, just switched off.