Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

# The apps folder is a package: appkit imports each app in it as apps.<app>.
2 changes: 1 addition & 1 deletion apps/midiengine/midiin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""What the apps that play say about the MIDI devices in the hub.

Instruments and the midiEngine hear every USB MIDI device at once, through
``midiports.usb_host.all_ports()``. :class:`Watch` names the ones open now,
``midiports.usb_host.all_ports()``. `Watch` names the ones open now,
for the status line, and notices when one comes or goes.
"""

Expand Down
8 changes: 6 additions & 2 deletions apps/ostinato/app/engine/engine.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Ostinato's sound engine. Each engine worker runs one Engine.

Several engine workers render in parallel, each owning some of the tracks
Expand Down Expand Up @@ -392,7 +396,7 @@ def apply_many(self, ops):

def resequence(self):
"""Forget what was sequenced and not yet played: the song or the
transport changed. :meth:`sequence_ahead` sequences it again."""
transport changed. `sequence_ahead` sequences it again."""
self.queue = []
self.sequenced_to = None

Expand Down Expand Up @@ -469,7 +473,7 @@ def retempo(self, at_frame):
# -- what plays ---------------------------------------------------------

def segments(self, t0, t1):
"""What plays between ticks t0 and t1: :func:`songmodel.model.segments`."""
"""What plays between ticks t0 and t1: `songmodel.model.segments`."""
return model.segments(self.project, t0, t1)

def _sequence(self, until):
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/engine/enginehost.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""One engine, whatever hosts it: a browser worker, a process, or a thread.

A host gives an ``EngineHost`` three things and asks one:
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/engine/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Entry point of an engine worker.

Ports from the page (workers/host.js): ``audio`` to the AudioWorklet,
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/engine/master.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Entry point of the master worker: the master rack, on the sum of every track.

The track engines don't talk to the AudioWorklet. Each one talks to this
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/engine/mastercore.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The master track's sound, whatever hosts it: the tracks' blocks summed,
through the master rack and volume.

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/catalog.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""What instruments and effects exist, from assets/catalog.json.

scripts/make_catalog.mjs writes it from the same wheels the engines load,
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/editor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The pattern editor: a step grid for drums, a piano roll for everything else.

Both edit the selected track's current pattern through the app's history, so
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/engines.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The UI's side of the engine workers.

The UI owns the project. Every edit is an op, applied here and sent to every
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/files.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Files: save and open projects, autosave, and export WAV and MIDI.

The file pickers belong to the page (index.html in a browser,
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/fonts.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Fonts: Montserrat from lvgl-bindings, Material icons from the app.

Text fonts come from lvgl-bindings' ``fonts/`` folder, at the tag pinned for
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/help.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The guide: how to play Ostinato, inside the app (it never links out).

Shown once on the first run, and any time from the ? button.
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/history.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Undo and redo: every edit is an op with its inverse, grouped into steps.

A step is what one undo takes back: one click on the grid, one drag in the
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/inspector.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The inspector: the selected track's instrument, its knobs, and its effects;
or, with the master selected, the master effects.

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/keyboard.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The on-screen keyboard: shows what's playing, plays the selected track."""

import lvgl as lv
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/knob.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""A knob: drag up or down to turn it; its name under it, its value inside.

Dragging is vertical, as in most music software: up turns it up, one step
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/layout.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Where each region of the window goes.

Every size here comes from the window size through one scale factor, and
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Ostinato's UI: LVGL, the project, and the engines.

In a browser this is the UI worker: the page (index.html) runs nothing but
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/meter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""A stereo segment meter: left and right columns of lit segments.

Levels arrive about 30 times a second as peak dB since the last reading.
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/page.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The UI's line to whatever hosts it: here, the browser page (index.html).

The page holds what a worker can't: the file pickers, local storage, the
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/song.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The song: scenes in order, each a pattern per track and a repeat count.

Click a track's letter in a scene to cycle through its patterns (and "-",
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/status.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The status bar: the project's name and whether it's saved, a word when the
audio drops out, and on the right either a message or the last MIDI."""

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/theme.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Colours, spacing and the type scale, defined once, as shared LVGL styles.

Every widget takes its look from a handful of shared styles; a pressed,
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/tooltip.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Tooltips: what an icon-only button does, shown when the mouse rests on it.

LVGL hovers a released pointer (HOVER_OVER, HOVER_LEAVE) when its input
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/tracks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The track list: one row per track, select to play it, mute, solo, volume.

Under the tracks, the master: its volume, and select it to see the master
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/app/ui/transport.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The top bar: transport, position, tempo, swing, metronome, patterns."""

import lvgl as lv
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Ostinato on CPython, Phase 0 spike: the demo song through the desktop
runner and mixer, live MIDI from a Windows port, and the shared UI drawing.

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/control.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The control socket: what the checks drive the desktop app through.

The browser checks reach the app through Chrome's DevTools: they send the UI
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/device.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The engine process as an hmilink device: it holds the song and makes the sound.

python -m ostinato --role device [--port 9100] [--song FILE]
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/dialogs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Windows' own Open and Save dialogs, through comdlg32 and ctypes.

No dependency: ``GetOpenFileNameW`` and ``GetSaveFileNameW`` with the
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/engine_loop.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""An engine's life on the desktop, the same in a process and in a thread.

The runner hands it ``io`` (how messages arrive and leave) and a ``Ring``
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/linkrunner.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The UI's runner when the engines are another process's: an hmilink panel.

desktop/runners.py's runners host the engines and the mixer in this process
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/midi.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""MIDI in on the desktop: Windows MIDI ports, read once, relayed to every engine.

The browser's page relays Web MIDI to the engine workers; here one thread in
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/midi_send.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""A stand-in keyboard for the checks: plays MIDI into a port, on time.

python desktop/midi_send.py "Ostinato Loopback" (the control socket starts it)
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/mixer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The desktop mixer: the AudioWorklet's job, in Python, on WASAPI.

It asks each engine for blocks, sums them through the shared master
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/patch_synthio.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Write patched/synthio.py: audiodsp's synthio.py with its block clock per
thread instead of per process (the stress test's --synthio-tls experiment).

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/ring.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""One engine's audio on its way to the mixer: a single-producer,
single-consumer ring of int16 stereo frames, plus a few shared counters.

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/runners.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The two ways to run the engines and the mixer: processes or threads.

Both give the UI the same object:
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/send.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Play keys into a Windows MIDI port, stamping each with perf_counter_ns
(QueryPerformanceCounter: the same clock in every process on the machine).

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/stress.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Free-threading stress test for _audiodsp and LVGL (Phase 0).

python3.15t.exe -I -X gil=0 desktop/stress.py [--threads 16] [--rounds 3] [--blocks 400]
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/ui/engines.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The UI's side of the engines on the desktop: app/ui/engines.py's job, over
a runner (desktop/runners.py) instead of the page's MessagePorts.

Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/ui/page.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The desktop's page: what index.html does for the browser version.

The shared UI (app/ui) talks to its page through the same names (``send``,
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/desktop/window.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""The desktop app's window: pydevices' WinDisplay, maximised, as the installed PWA is.

``PYDEVICES_MAXIMIZED=1`` makes the desktop board config open WinDisplay
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/engine/engine.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Ostinato's sound engine: runs in a worker, owns everything you hear.

The page relays MIDI bytes here (``feed``); the AudioWorklet asks for audio
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/ostinato/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Ostinato on the desktop: ``python -m ostinato`` from a checkout.

The browser version and the desktop app share everything in ``app/`` and studio's ``songmodel``. What
Expand Down
4 changes: 4 additions & 0 deletions apps/ostinato/ostinato/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 Brad Barnett
#
# SPDX-License-Identifier: MIT

"""Start Ostinato on the desktop.

python -m ostinato [--engines processes|threads] [--midi NAME]... [--fresh]
Expand Down
Loading
Loading