Skip to content

V1.9.15

Latest

Choose a tag to compare

@fiverecords fiverecords released this 13 Oct 15:40
· 11 commits to main since this release
V1.9.15
5eb6b98

This release comes from one issue, #24: Loop timecode, a generator
preset that goes back to Start TC where it would stop, so that a show or a
promo -- lights, video and music -- can loop with no operator. At the end
of the preset's audio file the loop has no gap: the file goes round to the
sample, and the timecode with it.

Around it, the generator's loops and what its outputs get were reworked.
The A/B loop now goes round exactly and fires its cues on every pass. "Loop
audio file when it ends", now "Loop audio only (timecode keeps counting)",
keeps the timecode on the audio interface's clock in every pass, and the
waveform goes round with the audio. The receivers are told where the
generator is when it jumps, and while it is stopped. The loop options
switch when a preset is saved, and the waveform window and the panel say
which loop runs. With these came fixes to the generator found on the way,
and tooltips, which STC had never shown.

What has run on hardware: @Joren2087 ran a test build of this release for
over 50 minutes -- a 7-8 s WAV looping with Loop timecode, at 24 and 30 fps,
LTC into TimeCode Monitor and Reaper, MTC into Reaper. TimeCode Monitor read
LTC frame-perfect across the loop, he saw no drift and no problem in the
audio, and Reaper's relock of 0.5-1 s at each jump back went away with a
setting of Reaper's own (see Known limits). Art-Net, LA-Net and TCNet were
not tried. Run in simulation, a plain loop behaves in this release as it did
in that build. Everything else came after it, or was in it without being
exercised there (a loop at a Stop TC, cue points, OSC looptc, the A/B
loop, a click on the waveform), and has not run on the hardware it is for:
it was checked by reading the code and in simulation -- STC's own engine,
outputs, audio player and windows driven in virtual time, with WAV files
that carry their own sample index, so that every sample heard at a loop's
seam can be accounted for. "Known limits" near the end lists what the new
options cost or leave open.

Upgrading. Existing configurations load as they are, but for an A/B loop
(below), and nothing new goes into settings.json. A preset saves the new
option only when it is ticked, so the presets file of anyone who does not
use it is written exactly as 1.9.14 writes it. What behaves differently
without touching anything:

  • A preset with an audio file plays to the file's end. A Stop TC left
    in such a preset (the editor already greyed it out and showed
    (audio length)) used to stop the file there; now it is not used, and
    the panel shows 00:00:00:00. A Stop TC typed in the panel or sent by OSC
    after GO still applies. See Fixed.
  • "Loop audio file when it ends" now reads "Loop audio only (timecode
    keeps counting)", and keeps the timecode on the audio interface's clock
    in every pass, as it already did in the first; from the second pass on
    it ran on the computer's clock and drifted from the audio. Every output's
    timecode under that option therefore runs at the interface's rate in
    every pass, and a Start TC change, a jog before Start TC or an
    audio-device stall is pulled back into step the shortest way round the
    file, when that way is under a second. The waveform's needle goes round
    with the audio. See Changed and Fixed.
  • The A/B loop of the waveform window: each pass is exactly as long as
    the loop, a cue on Out and one in the last moment before it now fire on
    every pass, and In's cue fires as the loop jumps back, not a moment
    later. Its toggle reads A/B LOOP; [, ] and L also work in the
    waveform window, and L on Linux; a refused [ or ] there flashes red
    instead of opening a dialog. See Changed and Fixed.
  • An A/B loop through a restart. An A/B loop that 1.9.14 left in the
    settings comes back, as before, on the preset the settings name, and the
    first GO on that preset now keeps it, where 1.9.14's cleared it; the
    preset list marks that preset while A/B LOOP is on. One whose In lies
    before that preset's Start TC comes back off. One that 1.9.14 kept for
    another file than that preset's -- after a choice in the list, while the
    audio played, of a preset with another file, or after the preset was
    given another file -- comes back as it was saved when its In lies at or
    after the preset's Start TC, and GO on the preset keeps it: turn A/B LOOP
    off (or press L) if you do not want it. See Changed.
  • An A/B loop past where the generator stops -- past the end of the
    audio file, or past a Stop TC -- is ignored: GO and PLAY play from Start
    TC as if there were no A/B, where they started at its In and stopped at
    once, or at the end of the file without going round. See Fixed.
  • What the receivers get when the generator jumps. Each jump back of a
    generator loop, and each seek of the generator by half a second or more
    while it plays (a click on the waveform, OSC jog), now goes out as STC
    sends a CDJ hot cue: an MTC Full Frame, an immediate Art-Net and LA-Net
    frame, the LTC encoder restarted at the new position. Shorter steps, such
    as those of a drag on the waveform, go out as before. See Changed.
  • What the receivers get while the generator is stopped. A position
    changed while the generator is paused or stopped -- STOP after PAUSE, a
    new Start TC while stopped, a click or a drag on the waveform, OSC jog --
    now reaches MTC, Art-Net and LA-Net once it has rested for 150 ms: an MTC
    Full Frame and one Art-Net and LA-Net frame, the outputs staying paused.
    Before, they stayed on the value they had when the generator stopped. See
    New.
  • TCNet at a stop. A TCNet layer that pauses with a jump -- the
    generator's STOP back to Start TC, a CDJ's CUE return -- now shows the
    new position at once, with the other outputs; before, it kept the
    position it had while playing. See Changed.
  • A held LTC frame (HOLD ON PAUSE) follows those moves too, and an MTC
    input's locate while stopped. Without HOLD ON PAUSE, LTC stays silent as
    before. See Changed.
  • Save in Generator Presets acts at once on "Loop audio only": ticked or
    unticked and saved, it switches at once on an engine that has that preset
    loaded, also while it plays; before, it waited until the preset was
    applied again (GO, OSC /stc/N/gen/preset, or a choice in the preset list
    while no audio played). Everything else in a preset still waits for GO.
    Closing Generator Presets with changes that are not saved now asks first.
    See New.
  • After a restart the panel's audio status reads NOT LOADED (press GO)
    for the preset's audio file, whether or not it is on disk, until GO or a
    choice in the preset list; 1.9.14 read FILE NOT FOUND. See Fixed.
  • Sliders. BPM SMOOTHING's right-click or double-click reset now sets
    50 %, its default; it set 100 %. A right-click or a double-click on the
    value box beside a gain, BPM SMOOTHING or offset slider now resets the
    slider as the same gesture on the slider does; a single click still opens
    the box for typing. See Changed.
  • Tooltips now appear. Many of STC's controls carry a tooltip, but none
    was ever shown; now they are, after the mouse rests on a control for
    0.7 s. See Fixed.
  • On screen. The waveform window is at least 640 x 180 and has a GO,
    with the name of the preset it starts; the window's header, the panel's
    Stop TC label and its audio status name the loop that runs; the preset
    table shows (loop audio) where it showed (loop), and a preset whose
    audio file is missing shows its Stop TC. See New, Changed and Fixed.
  • OSC /stc/N/gen/preset now does everything GO does, including naming
    the preset (the TCNet track title) and selecting it in the preset list.
    See Fixed.

New

Loop timecode (#24)

Requested by @Joren2087 for a five-minute promo that has to loop with no
operator. A new option in the Generator Presets editor, in a row below
"Loop audio only": Loop timecode (back to Start TC at the end). The two
boxes untick each other.

Where the generator would stop -- at the end of the preset's audio file, or
at Stop TC for a preset without one -- the timecode, the audio and the cue
points go back to Start TC instead, and the preset plays again, for as long
as the generator runs.

  • The end. The end of the audio file; for a preset without audio, its
    Stop TC. A Stop TC typed in the panel or sent by OSC after GO, before the
    end of the file, ends the loop there instead (one less than a frame
    before the end of the file counts as the end of the file). With neither a
    file nor a Stop TC there is no end and the option does nothing; a loop
    shorter than one second does nothing either; the generator then stops as
    it would without the option.
  • The timecode does not reach the end. With the loop, the timecode
    never reaches the Stop TC frame, and every pass lasts exactly Stop TC -
    Start TC: Start 01:00:00:00 and Stop 01:05:00:00 at 25 fps run up to
    01:04:59:24, then 01:00:00:00. LTC, and often Art-Net, still send the
    Stop TC frame just before the jump back (see Known limits). Without the
    loop, the generator still stops on the Stop TC frame, as before.
  • No gap at the end of the file. When the loop ends at the end of the
    audio file, the player loops the file itself, to the sample, and the
    timecode goes back by exactly the file's length: no gap, no repeat, and
    timecode and audio stay together pass after pass (simulated over 1200
    passes with the audio interface's clock up to 2000 ppm off). An OSC jog
    to before Start TC on such a loop puts the audio as far before the end of
    the file, so that it goes round into the top as the timecode reaches
    Start TC and the two run on together (simulated with 480-sample buffers:
    within 9 ms of each other, the timecode never stepping back). The same
    holds for such a jog made while the preset's file is still loading, and
    for a change of the generator's audio device or channel after it. When
    the loop ends at a Stop TC before the end of the file, or without audio,
    the audio is cut there and started again from the top, as the A/B loop
    does.
  • Cue points on every pass: a cue on Start TC as the loop jumps back,
    one exactly on the end just before it, and every one in between once per
    pass.
  • What the receivers get at the jump back: what STC sends at a CDJ hot
    cue (see Changed) -- an MTC Full Frame at Start TC, an immediate Art-Net
    and LA-Net frame, the LTC encoder restarted. TCNet's position jumps back
    with the timecode, and with Audio BPM on that engine its beat count
    starts again at beat 1. MIDI clock, Ableton Link and OSC BPM carry no
    position and do not change.
  • On screen. While the loop is in charge the panel's STOP TC (0=FREE):
    label reads STOP TC (LOOP):, the waveform window's header shows
    LOOP TC, and a cyan line on the waveform marks where the loop goes back
    (see Which loop runs, below). The window's A/B LOOP button is the other
    loop's, not this one. The preset table shows (loop TC) after the Stop
    TC, muted where the loop has nothing to act on: a preset without an audio
    file on disk and without a Stop TC at least a second after Start TC. Which
    files are on disk is checked in the background when the table is filled,
    so a network share that does not answer does not hold the editor up.
  • OSC /stc/N/gen/looptc turns it on or off at once for the preset that
    is playing: 1 on, 0 off. The value is read as a whole number, as
    /clock reads its value: 2 or more is on too; a float or numeric text is
    cut to a whole number first, so 1.0 is on but 0.5 (or -0.5) reads as 0,
    off; text that is not a number reads as 0, off; a negative whole number, a
    true/false argument or no argument changes nothing. It does not change the
    preset: the next GO or preset load, or a Save of the preset in Generator
    Presets, brings the preset's setting back. Turned off while it plays, the
    pass in progress runs to its end and the generator stops there. On, it
    also turns off "Loop audio only", which 0 does not turn back on (the
    next GO, preset load or Save does): on a "Loop audio only" preset, 1 and
    then 0 stop the generator at the end of the pass instead of looping the
    audio. Like the other generator commands, it is not blocked by Show Lock.
  • Save in Generator Presets switches it at once on an engine that has
    the preset loaded, playing or not (below).
  • An A/B loop armed inside it takes over while it is armed, and PLAY from
    STOP starts at its In. One that is not inside it is ignored (see Known
    limits), and the waveform draws it dashed.
  • "Loop audio only" (1.9.14's "Loop audio file when it ends") does what it
    always did: only the audio loops, the timecode counts on (see Changed). A
    preset file with both options ticked (only a hand edit makes one) runs
    Loop timecode.

The generator tells the receivers where it is while stopped

While the generator is paused or stopped its outputs are paused, and in
1.9.14 a position changed then reached only STC's display and TCNet: MTC,
Art-Net and LA-Net stayed on the value they had when the generator stopped.
They now get the new position as a locate, once it has rested for 150 ms:
an MTC Full Frame (MIDI Time Code's own locate) and one Art-Net and one
LA-Net frame, the outputs staying paused -- the messages STC already sends
when an MTC input is located while stopped. It covers:

  • STOP after PAUSE, and STOP after the generator stopped by itself at Stop
    TC or at the end of its file: the receivers go to Start TC, as after a
    STOP from playing;
  • a new Start TC while stopped -- typed in the panel, sent with
    /stc/N/gen/start, or from a preset chosen in the list;
  • a click or a drag on the waveform, and OSC /stc/N/gen/jog, while paused
    or stopped.

A click goes out 0.15-0.17 s after it. A drag, or a stream of jogs, goes
out once, where it ends -- or again wherever it rests for about 0.17 s or
more on the way -- so a receiver never sees a run of changing positions
while the generator is stopped (simulated: a 2 s drag, one locate; held
still mid-drag for 0.18 s or more, one more there). Nothing goes out when
the new position is the frame the receivers already hold, nor for GO or a
PLAY, which start the outputs themselves. LTC stays silent unless HOLD ON
PAUSE is on (Changed).

Which loop runs, on screen

With Loop timecode the generator has three loops -- Loop timecode, "Loop
audio only" and the A/B loop -- and the screen now says which one is in
charge:

  • The waveform window's header names one at a time: LOOP A/B while an
    A/B loop is followed (it goes back from Out to In before either other
    loop can act), else LOOP TC while Loop timecode acts, else LOOP AUDIO
    while "Loop audio only" runs.
  • The panel's Stop TC label reads STOP TC (LOOP): while Loop timecode
    is in charge, STOP TC (A/B): while the A/B loop is, and
    STOP TC (0=FREE): otherwise, Loop audio included.
  • The panel's audio status, with AUDIO PLAYBACK on, reads
    PLAYING (LOOP AUDIO) or READY (LOOP AUDIO) before the file's name
    while "Loop audio only" runs.
  • A cyan line, in the colour of LOOP TC, marks on the waveform -- in
    the window and in the panel -- where Loop timecode goes back while it
    acts: the right edge for a loop at the end of the file, Stop TC for one
    at a Stop TC. It is drawn under the A/B loop, the cue markers and the
    cursor.
  • An A/B loop the generator ignores -- outside Loop timecode's loop, or
    past where the generator stops -- is drawn dim, with dashed In and Out
    lines, at the waveform's right edge for a point past the end of the file.
    The A/B LOOP toggle stays as you set it.

Hold the mouse over the header's label or the panel's for what each text
means.

Save in Generator Presets switches the loop at once

The two loop boxes of a preset -- Loop timecode and "Loop audio only" --
now take effect when you press Save in Generator Presets, on every engine
that has that preset loaded (applied there with the audio file the preset
still names), while it plays, is paused or is stopped: no GO needed. What
each switch does:

  • On to Loop timecode: the loop acts from the next moment, as with
    /stc/N/gen/looptc 1; a timecode already past the loop's end goes back
    into it, which the receivers get as a jump back.
  • Loop timecode off: the pass in progress runs to its end and the
    generator stops there.
  • Loop timecode to Loop audio only: the pass in progress plays on; at
    the end of the file the audio starts again from the top while the
    timecode counts on.
  • On to Loop audio only, from neither: the file loops from the pass in
    progress on, and the generator no longer stops at its end.
  • Loop audio only off: the generator stops at the end of the pass in
    progress, as it stops at the end of the file without the option.
  • Stopped: only the options change, and PLAY starts with them.

Everything else in the preset -- Start TC, Stop TC, the cue points, the
audio file -- still takes effect when the preset is next applied (GO), and
so do the loop boxes after a Save that renames the preset or gives it
another file. After a restart the engine has no audio file loaded until GO
(the panel's audio status reads NOT LOADED (press GO)): a Save then
changes the options that GO will apply with the file. Add makes a new
preset and changes nothing that plays; its tooltip now says so. Save's and
the boxes' tooltips say when they take effect.

Closing Generator Presets with changes that are not saved now asks:
Save, Discard or Cancel (Escape cancels). The question covers the editor and
leaves the other windows working, so STOP and PLAY act while it waits for an
answer. Before, the window closed and the changes were lost without a word.
Engaging Show Lock, quitting STC or restoring a configuration still closes
it without asking, dropping what was not saved.

GO in the waveform window

The waveform window has a GO, between < and PLAY, that does what the
panel's GO does for the window's engine: it starts the preset selected in
the main window's preset list, from its Start TC, or, with its audio file
already loaded, from the In of an A/B loop it follows. It also works with
the main window's input section collapsed, and under Show Lock, as the
panel's GO does. It is greyed out while the engine's input is not the
generator or the generator is in Clock mode, where the panel hides its GO,
and while no preset is selected. The preset it starts is named on the right
of the large timecode, PRESET: Name. PLAY, PAUSE and STOP are a little
narrower so the row fits the window's minimum width.


Changed

The A/B loop: its pass, its cues and A/B LOOP

The A/B loop (waveform window, [ ] and the loop toggle) now goes round
as Loop timecode does:

  • Each pass lasts exactly Out - In. 1.9.14 dropped what the timer had
    run past Out at each jump back, so a 2-second loop averaged 2008.5 ms a
    pass and drifted 10 s behind its own count in 1195 passes.
  • A cue on Out fires on every pass, just before In's (it never fired),
    and a cue in the last sixtieth of a second before Out fires on every
    pass (it fired only when the timer happened to land between it and Out).
  • In's cue fires as the loop jumps back, not a timer tick (about 17 ms)
    later.
  • Arming the loop with the playhead past Out, or seeking past Out while it
    plays, still lands on In, with In's cue.

And what it looks like:

  • The toggle reads A/B LOOP (it read LOOP), so that it is not taken for
    Loop timecode, and is wider so the text fits. Its tooltip, and those of
    [ and ], say they belong to the A/B loop and that their keys work in
    the waveform window and in the main window; LOOP TC in the header has
    one that says it is the preset's Loop timecode.
  • The waveform window is at least 640 x 180 pixels, so its buttons fit;
    a smaller size saved earlier opens at 640 px wide.

The A/B loop's keys in the waveform window

[, ] and L now work while the floating waveform window has the
keyboard focus -- after a click on one of its buttons, its volume slider,
the waveform or its title bar -- as they do in the main window, with the
same checks: Show Lock refuses [ and ] and leaves L free, and a text
box being edited takes them as text. Only these three keys: the backup and
restore shortcuts stay in the main window. Held down, L toggles the loop
at the keyboard's repeat rate, as it always has on Windows and macOS.

The A/B loop through GO and a restart, and on the preset list

The A/B loop belongs to the engine and to the audio file it was set on. As
in 1.9.14, GO on a preset with the same audio file keeps it armed -- so an
A/B left on one preset can be called from another preset with that file --
and GO on a preset with another audio file clears it, as does GO on one
without a file where the engine had one; you take it off (A/B LOOP, or
L) when you no longer want it. What is new:

  • The preset list marks it. While the engine on screen has an A/B loop
    armed (A/B LOOP on, with an Out after the In), the panel's preset list
    marks the preset that engine has loaded: an amber edge on the closed
    list, and Name [A/B] in the open one. Changing the mark does not apply
    the preset again or move the selection. Choosing a preset in the list
    while the audio plays keeps the playing file and its A/B, as in 1.9.14: a
    preset with the same file is then marked, and GO on it keeps the A/B; one
    with another file is not.
  • Through a restart. The A/B comes back with the engine's settings, as
    in 1.9.14, and the first GO on that preset now keeps it. 1.9.14's first
    GO after a restart cleared it -- but on a preset without a file, which
    kept it whatever file it had been set on. That first GO -- and a GO while
    the preset's file is still loading -- starts at Start TC and plays into
    the A/B; with the file loaded, GO starts at the A/B's In, as before. The
    A/B is kept for the next start only when the engine had been given the
    file of the preset in use, and comes back off when its In lies before
    that preset's Start TC: it is not kept after a choice in the list, while
    the audio played, of a preset with another file, nor after a Save that
    renamed the loaded preset or gave it another file without GO. Settings
    left by 1.9.14: see Upgrading.

A jump of the generator goes out as a seek

Each time either generator loop jumps back, and each time the generator is
moved half a second or more while it plays (a click on the waveform, OSC
/stc/N/gen/jog), the outputs now get what a CDJ hot cue gives them: an MTC
Full Frame at the new position with a new quarter-frame cycle, an immediate
Art-Net and LA-Net frame, and the LTC encoder restarted at the new position.
Before, each output had to notice the jump in the values it was sending, and
the LTC output logged a correction in ltc_gaps.log at every jump
(simulated: no Full Frame, and one ltc_gaps.log line per jump; now one
Full Frame and no line). Half a second is the jump a CDJ's position has to
make for STC to treat it as a seek. Shorter steps -- each step of a drag on
the waveform, a stream of short jogs -- are not announced and go out as in
1.9.14: a drag moves the generator every 17-33 ms, and a seek announced at
each step would leave MTC no complete quarter-frame cycle and LTC no frame
for as long as the drag lasts (simulated). With another input selected
nothing changes; paused or stopped, a move goes out as a locate once it
rests (New). The messages are the ones STC already sends at a hot cue; check
your receivers anyway.

TCNet: a layer that pauses with a jump shows where it is

When a source pauses and its position jumps at the same moment by a video
frame (33 ms) or more, the TCNet layer now shows the new position at once;
before, it kept the last position it had while playing until something moved
it again. At a generator STOP, or when its Clock mode is switched off, the
layer goes back to Start TC with the other outputs (before, it stayed on the
stop position); a CDJ's CUE return shows the cue point as the deck pauses
there (before, the position before CUE). A deck that pauses a little ahead
of its last reported position (a late update, a high pitch) can show the
paused position too. The layer still reads paused, never stopped. A plain
pause, with no jump, is unchanged, except for a source that arrives in whole
frames -- the generator, or an MTC, LTC, Art-Net or LA-Net input -- whose
pause falls one frame past the last frame played: the layer then moves to
that frame, the one the other outputs stop on.

HOLD ON PAUSE follows a locate while stopped

With HOLD ON PAUSE, LTC OUT keeps repeating a frame while the source is
paused or stopped. That frame now follows a locate made while stopped --
the generator's (New) or an MTC input's -- from the next frame boundary, so
an LTC reader shows what MTC and Art-Net show; before, it stayed on the
frame of the moment the source stopped. Without HOLD ON PAUSE, LTC stays
silent while stopped, as before.

"Loop audio only (timecode keeps counting)"

The box that read "Loop audio file when it ends" now reads "Loop audio only
(timecode keeps counting)" and has a tooltip: only the audio loops, the
timecode keeps counting (up to a Stop TC set after GO, or for ever) and the
cue points fire on the first pass only. That is what it always did,
whatever the code's comments and the 1.9.11 notes said (that the cue points
fire again on every pass); Loop timecode is the option that goes back. The
preset table shows (loop audio) for it, where it showed (loop); a long
file name is cut before it, so it stays whole.

A jump is pulled back the shortest way. With "Loop audio only", a Start
TC change while the file plays, a jog to before Start TC, or a stall of the
audio device leaves the timecode off the audio; it is now pulled back into
step by the shortest way round the file, in every pass, when that way is
under a second. Before, nothing was pulled from the second pass on, and in
the first pass such a difference was pulled only when it was itself under a
second, sometimes the long way round, and otherwise left alone: the
timecode could stay off the audio for good (simulated: 0.95 s off with a
3 s file and Start TC moved back 2.05 s, now within 1 ms of it after 6 s).
The pull is gradual, at most 20 ms per 60th of a second. That the timecode
now stays on the audio interface's clock after the first pass is under
Fixed.

Sliders: BPM SMOOTHING's reset, and a reset on the value box

BPM SMOOTHING's right-click or double-click now resets it to 50 %, the
value it starts with, instead of the gain sliders' 100 %. And each of these
sliders -- the gains, BPM SMOOTHING, the TCNet offsets and the output
offsets -- now also resets from the value box beside it: a right-click on
it, or a double-click (the first click opens the box for typing; the second
closes it, dropping what it held, and resets). A single click still opens
the box to type a value, and Enter sets it. The tooltips say "Right-click
or double-click to reset" (BPM SMOOTHING: "... to reset to 50%"). The
generator's volume sliders (VOLUME in the panel, VOL in the waveform
window) have no reset, on the slider or on its box, as before.

The Generator Presets window

It opens 600 px wide (was 560), with a wider Stop TC column, so that
(loop TC) fits after (audio length). A window size you have already
saved is kept.


Fixed

  • A preset with an audio file ignored the editor. The editor greys out
    Stop TC for a preset with an audio file, says the file's length is used
    and shows (audio length); but GO, the preset list and OSC
    /stc/N/gen/preset applied the Stop TC typed before the file was added,
    and stopped the file there. Now that preset plays to the file's end. A
    Stop TC typed in the panel or sent with /stc/N/gen/stoptime after GO
    still applies, and the preset keeps its text, so removing the file in the
    editor brings it back. At GO, /gen/preset or a choice in the list
    while no audio plays, a preset whose audio file is missing from the disk
    runs as one without audio, to its Stop TC, as in 1.9.14; the preset table
    now shows that Stop TC for it, where it showed (audio length) (the
    editor's Stop TC field stays greyed out while the preset names a file). A
    file that is on disk but cannot be read (the panel's audio status shows
    the error) now runs with no end, where 1.9.14 stopped it at that Stop TC.
  • "Loop audio file when it ends": the timecode drifted from the audio
    after the first pass.
    While a file plays, the generator's timecode
    follows the audio interface's clock; with "Loop audio file when it ends",
    as the option was called, it did so in the first pass only, and from the
    second it ran on the computer's clock, drifting from what is heard -- and
    the waveform's needle with it -- by the interface's clock error: 0.2-0.4 s
    an hour for an interface 50-100 ppm off (simulated: 53 ms in ten minutes
    at 100 ppm, 1.2 s at 2000 ppm). A very short file did worse: with a loop
    of about a second or less, the timecode held back or stepped back at the
    second pass and fell behind the audio (0.8 s behind with a 0.6 s file
    after two minutes), and with one of about 0.3 s or less it stopped about a
    second past Start TC for good, so a Stop TC or an A/B loop after that was
    never reached. Now the timecode follows the audio interface's clock in
    every pass, as Loop timecode does, and stays with the audio (simulated:
    within 3-7 ms after ten minutes at 100 and 2000 ppm).
  • The waveform under "Loop audio file when it ends" (reported on #24).
    The audio loops while the timecode counts on past the file's end, and
    everything on the waveform was placed by the timecode: from the second
    pass the needle stuck at the right edge, the window's file time read the
    file's length ("0:03 / 0:03"), an A/B loop set in a later pass was not
    drawn, and a click, the hover readout and the TC ruler all took the first
    pass -- a click took the timecode back to it (8.7 s back in pass 4 of a
    3 s file, simulated), sent the receivers there, and fired the first
    pass's cue points again. Now the needle, the file time and the A/B points
    go round with the audio, and a click, a drag, the hover readout and the
    ruler stand for the pass the timecode is in; a click moves the timecode
    by less than the file's length. With a Stop TC, a point at or past it
    stands for the last pass that comes before it, from which PLAY plays, and
    a stop at a Stop TC on the end of a pass leaves the needle at the right
    edge. The cue markers stay those of the first pass, where the cues fire.
    Without a loop nothing changes.
  • The waveform's hover readout -- the file time and the timecode beside
    the mouse -- had the A/B markers, the cue markers and the cursor drawn
    across its text; it is now drawn over them.
  • Preset changes from a slow disk, from the second one on. 1.9.14 fixed
    the audio starting late, and a click on the waveform being lost, when a
    preset changes while its file is still loading; but after an engine's
    first load that fix no longer ran, so from the second preset change on
    the audio again started late against the timecode (simulated: 240-252 ms
    behind, now 16-21 ms, a device buffer and the timecode's usual lead), and
    a click during a load was dropped. It now runs after every load.
  • OSC /stc/N/gen/preset now does what GO does: it names the preset in
    use (the TCNet track title), selects it in the preset list, and fills the
    panel as GO does.
  • An A/B loop past where the generator stops. An A/B set under "Loop
    audio file when it ends" from its second pass on lies past the end of the
    file, where only that option's timecode goes. Called from a preset with
    the same file and without the option -- or from the same preset once the
    box was unticked -- GO and PLAY started at its In and the end of the file
    stopped the generator at once; one past a Stop TC did the same, and one
    whose Out lay past the end of the file played from its In and stopped at
    the end without going round. Such an A/B is now ignored: GO and PLAY
    play from Start TC to the end of the file, or to the Stop TC, as if there
    were no A/B, and the window's header does not read LOOP A/B. Under
    "Loop audio only" it runs as before, and runs again once that box is
    ticked again.
  • The generator's audio device changed while it is paused. Changing
    AUDIO PLAYBACK DEVICE or AUDIO CHANNEL, or turning AUDIO PLAYBACK on,
    while the generator was paused left the audio at the top of the file,
    and PLAY then started the music there, whatever the timecode. The audio
    now goes where the timecode puts it, paused or playing (simulated, paused
    1.5 s into the file: 8.6 ms from the timecode after PLAY, where the two
    stayed about 1.5 s apart).
  • [ or ] refused in the waveform window -- [ at or past Out, or
    ] at or before In -- opened a dialog that had to be closed before any
    window took a click, STOP and PLAY included. The button now turns red for
    a moment instead, as the keys refuse silently in the main window. Their
    tooltips say so.
  • Tooltips never appeared. STC set tooltips on many controls -- the
    waveform window's loop buttons, the preset and cue editors' buttons, the
    sliders' reset hint, SAMPLE RATE and BUFFER SIZE -- but had nothing to
    show them, so none ever appeared. They now appear after the mouse rests
    on a control for 0.7 s, in every window. Three were wrong or misleading:
    the cue editor's Add puts a new cue at the waveform's edit cursor when one
    is placed (it said Start TC), and is corrected; BPM SMOOTHING's reset
    went to 100 %, not its default; and the sliders' reset hint, which a
    slider's value box shows too, promised a reset there, where neither
    gesture did one. The last two are now made true (Changed).
  • L did nothing on Linux. The A/B loop's L worked on Windows and
    macOS, and on Linux only with Caps Lock on; it now works there too.
  • After a restart, the panel's audio status read FILE NOT FOUND for
    the preset's audio file, which is on disk but not loaded until GO. It now
    reads NOT LOADED (press GO) until GO or a choice in the preset list,
    whether or not the file is on disk; after that, a file that is missing
    reads FILE NOT FOUND.
  • The OSC reference in the preset editor (OSC ?) lists /stc/N/gen/jog,
    which was missing, and the new /stc/N/gen/looptc.

Known limits

At a stop

  • LTC at STOP, without HOLD ON PAUSE (the default): LTC goes silent
    where you pressed STOP and never sends Start TC, so an LTC reader keeps
    the stop position while STC and the other outputs show Start TC. This is
    what @Joren2087 reported on the test build, and it is as in 1.9.14: tick
    HOLD ON PAUSE for LTC receivers that should follow STOP back to Start TC
    (the carrier then never stops while the generator is paused or stopped). A
    short burst of Start TC at STOP is possible, but waits until it is known
    how LTC receivers take a held Start TC.
  • An output switched on while the generator is paused or stopped gets
    the position at the next move or PLAY, not at once; so does one that was
    off when the position last moved.
  • A locate goes out 0.15-0.17 s after a click, and a drag only where it
    rests, so a receiver can lag a fast series of clicks while the generator
    is stopped.

The A/B loop's keys

  • In the main window they act once you have clicked inside the window:
    just after STC starts, and after a click on the main window's title bar,
    the window's frame has the keyboard focus and takes no key, as in 1.9.14.
    In the waveform window they act whatever has the focus.
  • On keyboards that type [ and ] with AltGr or Option (Spanish,
    Belgian), Windows and macOS report that key with the modifier, so STC
    does not take it as the A/B loop's key there, as in 1.9.14 (read from
    JUCE's code, not seen on such a keyboard).
  • Held down, L toggles the loop at the keyboard's repeat rate, so
    where it ends depends on how long it was held.
  • Alt+click (Option+click) on a slider's track resets it; on its value
    box it opens the box for typing.

At the seam

  • A file that is not a whole number of frames long ends every pass on a
    short frame, and the frame count starts again at Start TC: a 3.010 s file
    at 25 fps ends each pass with a 10 ms frame, which the outputs send in
    only about half the passes. Export loops a whole number of frames long
    (5:00.000 is 7500 frames at 25 fps); at 29.97 that is rarely a round
    duration.
  • MP3: the file carries the encoder's delay and padding, silence that
    STC does not remove, so it can be heard at every pass. Use WAV, AIFF or
    FLAC for loops.
  • LTC at the jump back still sends the frame it had already prepared for
    the output before the restart: the end frame (which the timecode itself
    never reaches), and with large audio buffers (4096 samples) the frame
    after it too -- or, in some passes, that frame cut short by the restart,
    which LTC readers skip, so one frame period carries no readable frame.
    Then it goes on from Start TC + 1 (+ 2 or + 3 with 4096), without Start TC
    itself. The frame cut short comes mostly on a loop at the end of the file
    (simulated: 6 of 20 passes with an even timer; with an uneven one, 4 of 20
    with the audio interface's clock 50 ppm off and every pass with it 500 ppm
    off; at 29.97, 11 of 20, one of them losing two frame periods), now and
    then at a Stop TC (2 of 20 passes at 25 fps with an uneven timer, none at
    29.97 with an even one). Art-Net can likewise send the end frame just
    before the jump, depending on its timing. MTC sends neither. A fix belongs
    with LTC that knows the loop when it prepares its frames.
  • A DAW chasing timecode relocks at each jump back as at any jump of its
    timecode: on the test build Reaper took 0.5-1 s each time, until its
    "synchronize by seeking ahead" was set to 100 ms instead of its 1000 ms
    default.
  • Switching the loop while it plays -- turning it on or off, or a
    change of Stop TC or Start TC that moves its end between the end of the
    file and a Stop TC before it -- can leave a click, or a gap of one to
    three audio buffers (10-30 ms in the simulation), at that moment. Turned
    off just after the audio has gone round but before the timecode has, up
    to 16 ms of the file's top sounds before the stop (45 ms with 4096-sample
    buffers); with a file of about a second (up to 1.05 s) the stop comes
    about half a second after the switch (simulated: 367-567 ms), the next
    pass sounding from the top meanwhile.
  • An A/B loop that is not inside the loop is ignored: one whose In is
    before Start TC or whose Out is past the loop's end, and, on a loop that
    ends at the end of the file with no gap, one whose Out is at the end of
    the file or less than a sixtieth of a second before it, which cannot be
    honoured. The loop goes on from Start TC, and PLAY from STOP starts at
    Start TC, not at the A/B's In. The waveform draws such an A/B loop
    dashed.
  • A click past a Stop TC, on a loop that ends at a Stop TC set after GO
    before the end of the file, is taken into the loop: PLAY plays from the
    matching place in the loop, not from where you clicked, and while paused
    the receivers are sent the clicked position, which the loop never plays.

Switching the loop with Save, or with OSC looptc

  • Near the end of the file: switched on in the last tenth of a second
    or so before the end of the file, the first jump back can be silent for a
    few hundredths of a second (simulated: up to 30 ms).
  • The audio can jump at a switch: a switch that has the audio loop the
    file and finds the audio more than a tenth of a second from where the
    timecode puts it moves the audio there. That is usually a repeat or a
    skip of up to about a second, in the second after a jog or a Start TC
    change; it is more after a jog past the end of the file, or more than a
    second before Start TC, where the audio had stayed apart. The timecode
    does not move.
  • "Loop audio only" turned off after a jog before Start TC plays as
    without the option, the file to its end and then silence to the stop,
    unless it comes a second or more after a jog that was within about a
    second of a whole number of file lengths (in practice, only with very
    short files): then the audio is back in step and the pass plays to the
    stop in step.
  • Loop timecode switched on and off again before PLAY while paused in
    Loop audio only's second pass (two Saves) stops the generator at once
    when PLAY is pressed, the timecode taken back to the end of the first
    pass, without Loop audio's last pass.

"Loop audio only"

  • A very short file -- shorter than about two audio buffers, 0.17 s at
    4096 samples and 48 kHz -- can leave the timecode settling up to the
    file's length away from the audio, and with one of a buffer or less the
    timecode is in effect not corrected and runs on the computer's clock.
  • A Start TC change while the file plays brings the timecode to the
    audio gradually, over seconds, rather than the audio to the timecode.
    With a file of two seconds or more, a change, a jog or a stall of the
    audio device that leaves the timecode a second or more from the audio,
    counted the shorter way round the file, is not pulled back at all, as in
    1.9.14.

Presets and engines

  • Browsing the preset list while a Loop timecode preset's audio plays
    does to the loop what it does to any running preset in 1.9.14: the
    browsed Start TC, Stop TC and cues are applied, and the playing file and
    its two loop options are kept.
    • A different Start TC makes the audio jump by the difference; timecode
      and audio stay together.
    • A browsed Start TC later than the timecode does not move the timecode
      into the new loop: it first runs up to the new Start TC, outside the
      loop, for as long as the difference. On a loop that ends at a Stop TC
      before the end of the file, the audio plays from the top of the file
      meanwhile, ahead of the timecode until the two are pulled together
      (when under a second apart) or the next jump back.
    • A Loop timecode preset without audio (a loop at its Stop TC) takes the
      browsed preset's file and options, as any preset without audio does in
      1.9.14: if the browsed preset has no Loop timecode, the loop stops, and
      a browsed file loads and plays from where the timecode is to its end.
  • Engines loop on their own. Two engines are not realigned when they
    jump back, and an engine following its audio drifts from one on the
    computer's clock a little more every pass (simulated: 1.0 ms a pass for a
    2 s loop with the audio clock 500 ppm off, 1.8 s an hour).
  • After a restart, PLAY before any GO or preset selection runs without
    the preset's audio and cue points -- as in 1.9.14 -- and so, for a preset
    that loops at the end of its file, with no end. Press GO first; the
    panel's audio status reads NOT LOADED (press GO) until then.
  • Choosing the preset that is already selected in the list does
    nothing; press GO to apply it again. With a single preset, < and >
    restart it while it plays and do nothing while it is stopped.
  • Choosing a preset in the list while the generator plays keeps the
    playing file and its loop options -- unless the generator has no audio
    output open, in which case the same choice applies them.
  • The first GO after a restart, or a GO while the preset's file is still
    loading, starts at Start TC even with an A/B loop it will follow; the next
    GO starts at the A/B's In. PLAY (or OSC /stc/N/gen/play) while that load
    is still running can start at the A/B's In, past Start TC and the cues
    before it, even for an A/B that Loop timecode ignores once the file is
    loaded.
  • An A/B loop set before a Start TC that a later Save moved past its In
    is kept by GO in the same session, but comes back off after a restart.
  • The preset list's mark shows an A/B loop that is armed, also when the
    loop is ignored (outside Loop timecode's loop, or out of reach without
    it); the window's header and the waveform show whether it runs.
  • Going back to 1.9.14: 1.9.14 loads the presets and runs Loop timecode
    presets without the loop (they stop where they would). Its first save of
    the settings (a GO is enough) writes the presets file again without the
    option; the 1.9.15 version stays in generator_presets.json.bak until a
    save that changes the file.

Credits

@Joren2087 opened
#24,
"Feature Request: Timecode loop", with the design this release follows: a
per-preset Loop timecode beside "Loop audio file when it ends", the two
excluding each other, going back to Start TC at a Stop TC or at the end of
the audio. Looking into his request also showed that "Loop audio file when
it ends" did not do what the code's comments said. He then ran a test build
of this release for over 50 minutes at 24 and 30 fps, with LTC into TimeCode
Monitor and Reaper and MTC into Reaper; found the Reaper setting that
shortens its relock at each jump back; and reported what STOP leaves on LTC
readers, the waveform window's unclear LOOP button and the needle stuck at
the end under "Loop audio file when it ends" -- which brought the
generator's locates while stopped, TCNet at STOP, the A/B LOOP name and the
waveform's fixes under "Loop audio only".