SAMPLER.LIKE.AUDIO Bringing Hardware Sampler Soul to the Web Browser

SAMPLER.LIKE.AUDIO

Bringing Hardware Sampler Soul to the Web Browser

The Web Sampler & Sequencer is a fully-featured, open-source drum machine designed to run entirely within a modern web browser. By bridging the tactile workflow of classic beat-making hardware with the accessibility of modern web APIs, it offers a robust music production experience directly from a web browser.

Here is a breakdown of what makes this project technically unique and how it faithfully honors its hardware roots.

What Makes It Unique

The application stands out due to its radical approach to software architecture and browser integration, prioritizing transparency and local execution over cloud dependencies.

  • Zero-Dependency Architecture: The app requires no backend server, no Node.js environment, and no build tools like Webpack.

  • Direct Local File Access: It utilizes the File System Access API on Chromium-based browsers to let users browse and load samples directly from a local computer folder.

  • Absolute Privacy: Because it runs entirely client-side, the app never uploads a user’s audio files or patterns to a remote server.

  • Custom Legacy Audio Decoding: Alongside standard native Web Audio API formats (WAV, MP3, OGG, FLAC), it features a custom pure-JavaScript decoder for AIFF/AIFC files, which are common in vintage sample libraries.

  • Offline Independence: A built-in service worker caches the application shell and libraries, allowing the sampler to function completely offline after the initial load.

  • Transparent Codebase: The source code adheres to a strict philosophy where no individual file exceeds 200 lines.

  • No Compilation Needed: The app runs React natively in the browser via standalone Babel, meaning anyone can “View Source,” edit the code in a text editor, and refresh the page to see changes immediately.

Faithfulness to Hardware Samplers

Despite running in a web browser, the application meticulously recreates the physical feel and workflow limitations that made classic hardware samplers so intuitive.

  • Classic MPC Layout: The interface is built around a traditional 4×4 grid of 16 drum pads.

  • Mouse-Based Velocity: It simulates physical velocity sensitivity by calculating how close the user clicks to the exact center of a pad.

  • Plug-and-Play MIDI: The Web MIDI API allows users to plug in class-compliant USB controllers (like an Akai MPD) to finger-drum immediately with real velocity capture.

  • Tone Mode: By holding CTRL and clicking a pad, users can map a single sample chromatically across all 16 pads to sequence melodies and basslines.

  • Advanced Step Sequencing: The sequencer mimics classic hardware parameters, offering granular, per-step control over velocity, panning, pitch, and swing (shuffle).

  • Analog-Modeled Synthesis: When no sample is loaded on a pad, the app falls back on custom synthesis engines designed to strip acoustic percussion down to its physics—such as modeling the thump of a kick drum or the high-pass filtered noise of a snare wire.

Feature Translation: Hardware vs. Web

Hardware Concept Web Sampler Implementation
Internal Memory

Saves kits, favored samples, and patterns locally using browser localStorage and IndexedDB.

Sample Browsing

Recursively scans local directories to build a searchable, visual waveform grid.

Pattern Chaining

Provides 4, 8, 16, 32, and 64-step pattern options that can be managed in a dedicated Song tab.

Mixer Console

Features a dedicated mixer view with per-track volume, panning, and a shared reverb bus.

SCANALYZER.Like.Audio

https://Scanalyzer.Like.Audio 

At its core, scanalyzer is a smart, automated librarian for your audio files. If you have a massive, unorganized folder full of thousands of random audio samples,
finding the exact sound you need can be a nightmare. This software “listens” to every single file, figures out what it actually sounds like, and visually organizes
your entire collection so you can browse it instantly.

What It Actually Does (The Magic)

Instead of relying on whatever messy name the file was given (like BD_01_final_v2.wav ), the tool relies on acoustic science. When you point it at a folder, it does
the following:

1. Listens & Measures: It quickly scans through your audio files and measures things like how loud it is, how long it rings out, whether it’s a pitched note (like a
piano) or a burst of noise (like a cymbal), and how distorted it is.

2. Classifies & Groups: Based on those measurements, it categorizes the sound. It can tell the difference between a thumping bass, a short drum hit, a lingering
background texture, or a vocal line. It organizes them into a top-level hierarchy (like Percussive, Tonal, or Complex).

3. Builds a Map: It groups sounds that share similar characteristics together—regardless of what they are named.

The Key Benefits for Your Library

• The 3D Sound Cloud: It takes all your sounds and plots them as points in a 3D interactive “cloud.” You can literally see your entire sample library at a glance. If
you click an area where the “kick drums” are grouped, you can visually explore and play similar sounds right next to each other.

• Intelligent Renaming & Reorganizing: Once the software knows what everything is, it features a tool that allows you to easily rename your files and sort them into
neat, structured folders based on their true acoustic traits.

• 100% Private (No Cloud Needed): Even though there is a web browser version of this app, none of your audio files ever leave your computer. All the heavy lifting is
done right on your machine, so your private library stays private.

• Never Scans the Same Thing Twice: Once a file is scanned, it creates a tiny digital “nametag” (a .PEAK file) next to it. If you run the scan again in the future,
it reads the nametag instead of re-listening to the whole sound, saving you a ton of time.

How You Experience It

You can use the tool in two ways—they both do the exact same thing:

• As a Desktop App: A standalone application window running on your computer.
• As a Web Page: A sleek web interface that runs right in your browser (but again, totally offline and client-side).

It turns a chaotic, messy folder of audio files into a clean, searchable, visually explorable library using the actual sound of the files, not just their
filenames.

Twist.Like.Audio

TwistRouting — Anthony’s Media Workflow Matrix

A browser-based broadcast signal routing visualizer, dressed in full LCARS regalia.

TRY IT HERE


It maps the living signal flow of a multi-floor production facility — every stage box,
every camera, every audio channel — onto destinations like control rooms, edit suites,encoders, and floor rooms. You drag a source onto a destination’s input, and the patchcomes alive as a twisting strand of DNA.

The “twist” is the metaphor and the mechanic: each routing point is a twist, and thesignals you braid into it are rendered as an animated double helix — two strands (cyan and magenta) spiraling around each other, the way two feeds wind together into one production.
Route a healthy source and the helix flows clean; route a faulted one and the strand corrupts, flickering red.


What it does

  • Sources (left ingress panel) — draggable signal nodes, discovered dynamically from the
    Sources/ tree:

    • Video stage boxes, organized by floor
    • Audio stage boxes (channel banks), organized by floor
    • Productions — finished program outputs exposed as re-routable sources
    • Shape encodes category at a glance: video reads as a trapezoidaudio as a rounded
      pill
      , multiplex/group containers stay square.

  • Destinations (footer tabs) — consumers of signal, discovered from the Destinations/
    tree. Each category (Control Rooms, Edit Suites, Encoders, Floors…) becomes a tab group;
    each room is a tab full of twists:

    • Video Mixers, Audio Mixers, Multi Viewers, Intercoms
    • Monitors (single-feed)
    • ISO recorders with working RECORD / STOP arming and a pulsing REC indicator

  • Patching — drag a source onto a twist. The twist’s helix grows to show what’s braided
    in; click the LCARS lip or the left bar to fold/unfold the strand. Open a twist to get a
    matrix modal where you drag rows to reorder priority and switcher-input assignments.

  • Fault propagation — any source whose status isn’t OK (e.g. LOST CLOCK) pulses red.
    Route it anywhere and the destination inherits the alarm: the room’s LCARS L-bar pulses red
    and the twist’s DNA strand corrupts. Faults are visible end-to-end, the way they should be
    in a real plant.

  • Zero-backend discovery — the whole source/destination tree is just folders of JSON.
    Drop in a new stage box or a new control room and it appears in the UI; no code change.
    Discovery prefers an index.json manifest in each folder (so it works on any static
    host), and falls back to parsing autoindex HTML when none is present.

GIT HUB REPOSITORY

Data model

Everything is plain JSON under two roots:

Sources/        # draggable signals
  Audio/<Floor>/<box>.json
  Video/<Floor>/<box>.json
  Productions/<program>.json
Destinations/   # twists that consume signal
  Control Rooms/<tier>/<room>.json
  Edit Suites/<suite>.json
  Encoders/<encoder>.json
  Floors/<floor>/<room>.json

source declares its channels, a colour class, a floor, and a status:

{ "id": "stagebox-101", "name": "STAGEBOX 101", "prefix": "S101-", "count": 12,
  "extraClass": "audio-studio", "floor": "1st Floor", "items": ["CH 1", "…"],
  "status": "LOST CLOCK" }

destination declares its twists, each with what it accepts (video / audio /
both), its switcher inputs, and limits like maxVideo / maxAudio:

{ "id": "prod3", "name": "PROD 3", "color": "#646DCC",
  "twists": [ { "name": "Video Mixer", "accepts": "video", "inputs": ["SW IN 1", "…"] } ] }

Running it

Local, no dependencies (uses Python’s stdlib server, which provides the autoindex fallback):

python3 start.py        # serves the UI and opens your browser on a free port

Deploy to a static host over FTPS:

python3 uploadftp.py    # regenerates every index.json manifest, then uploads only the git diff

uploadftp.py is the smart deployer: it walks Sources/ and Destinations/ writing fresh
index.json manifests, then uses git status to upload only what changed (handling
renames and deletions), falling back to a full upload when there’s no diff. FTP credentials
come from a local .env (FTP_HOSTFTP_USERFTP_PASS). (deploy.py is the older,
simpler full-tree uploader.)

Front-end layout

The app is plain HTML/CSS/JS — no framework, no build step:

index.htm            # shell + all the LCARS styling
js/globals.js        # discovery (listDirectory/fetchJSON), folding, tabs
js/poolVideo.js      # render video source pools
js/poolAudio.js      # render audio source pools
js/visuals.js        # the DNA-helix SVG rendering
js/matrix.js         # twists, routing, the matrix modal, fault logic
js/dragDrop.js       # drag-and-drop patching
js/productions.js    # productions-as-sources
js/topbar.js         # destination tabs / groups
js/app.js            # boot: build the tree, wire everything up

Homage to the LCARS designers

This project is a love letter to LCARS — the Library Computer Access/Retrieval System — the operating-system aesthetic of the 24th century. None of this look would exist without the artists who invented it:

  • Michael Okuda, scenic art supervisor for Star Trek: The Next GenerationDeep Space
    Nine
    Voyager, and the films — the man who designed LCARS itself. The sweeping rounded
    “elbows,” the flat candy-coloured panels, the confident typography, the idea that a starship
    interface could be calm — that’s all Okuda. The fan community named the style the
    “Okudagram” in his honour, and this app’s palette is taken straight from an Okudagram
    colour reference.
  • Denise Okuda, scenic artist and video supervisor, Mike’s collaborator and co-author of
    the Star Trek Encyclopedia — half of the partnership that made the future legible.
  • Rick Sternbach, senior illustrator and technical consultant, who with Mike Okuda gave the
    hardware its grammar (the Technical Manual) so every readout felt like it meant something.
  • Gene Roddenberry, for the conviction that the future’s tools should look like they were
    built for people, not against them.

The colours here are credited to the Okudagrams Color Complete Set Ver. 4.1
(lcarsmania.com, Toshitin) and live in lcars-styleguide.json —
LCARS Orange, Lilac, Blue Bell, Tomato, Sunflower, Red Alert, and the rest — used exactly as intended: as flat, functional, beautiful blocks of information.

To Mike, Denise, Rick, and everyone who ever lined up a perfect LCARS elbow at 2 a.m. so a panel would read right on camera — thank you. We’re still trying to live up to the future you drew.

“Tea. Earl Grey. Hot.” — and a clean signal path.


Created by Anthony Peter Kuzub · www.like.audio

LCARS is a trademark/design associated with Star Trek and its rights holders. This is a non-commercial fan tribute and a working engineering tool; no affiliation or endorsement is implied.

The Live Sound “Gotcha”: When 48k AVB Fits the Amps, but Breaks the System Core

The Live Sound “Gotcha”: When 48k AVB Fits the Amps, but Breaks the System Core

Every system engineer knows that dangerous moment on a load-in day: the false sense of security. You’ve run your lines, your network switches are glowing with beautiful, stable activity LEDs, and the initial pink noise test passes with flying colors. You step away from the tech table to grab a cold coffee, entirely confident that the audio rig is rock-solid.

Then, you roll in the primary loudspeaker processor, and the entire house of cards collapses.

This is the story of a classic digital audio “gotcha”—a day where a perfectly innocent, standard-rate network conversion box works flawlessly with your amplifiers, only to hit a brick wall when plugged into the system’s central processing brain. It isn’t a hardware failure, and it isn’t the conversion box’s fault. It’s a clash of two entirely different architectural mindsets within modern professional sound systems.

Phase 1: The 48 kHz Honeymoon
The day starts simple. The venue or tour is built around a standard, reliable 48kHz digital infrastructure. To get those console channels out to the main PA over the network, you deploy a format converter to bridge your console’s protocol over to an AVB network stream. It effortlessly spits out a 48kHz AVB stream, pointing it straight down the network to your modern, network-native power amplifiers.

You open your system management software, route the AVB streams to the amps, and *boom*—clean audio.
Why does this work so beautifully? Because modern professional amplifiers are engineered with an “adaptable endpoint” ideology. Even though the internal DSP core of a high-end network amplifier almost always operates natively at 96 kHz,  manufacturers design these endpoints to be incredibly forgiving listeners. When the amplifier detects an incoming 48kHz AVB stream, its onboard network hardware automatically engages an internal Sample Rate Converter (SRC). It gracefully up-samples the 48 kHz network audio to 96kHz at the input gate without a single error or clock pop.
You walk away from the rack room smiling. The 48 kHz stream is happy, the 96kHz amps are happy, and the system sounds incredible.

Phase 2: Rolling in the System Brain
After lunch, the central system processor or immersive matrix engine arrives. This is the master brain tasked with handling complex distribution, time-alignment, tuning, or object-based spatial mixing for the entire venue. To maximize mathematical precision, filter accuracy, and the microsecond time-delays that modern sound system design demands, the configuration dictates that this core processor must be run at its native, premium 96 kHz mode

mode.

You re-patch the network. Instead of sending the conversion box’s 48kHz AVB stream straight to the amplifiers, you route those console tracks into the inputs of the loudspeaker processor first, intending to let the core brain do the heavy DSP lifting before handing the final mix off to the amps.
You click “Connect.”

Suddenly, the network status screen lights up bright red. Absolute silence fills the room. The system processor throws a massive clocking error and completely refuses to unlock the streams.

The Gotcha: A Tale of Two Ideologies
This is where the trap snaps shut. It is incredibly easy to assume that because manufacturers build seamless, automatic sample rate conversion into their *amplifiers*, they must have put that exact same capability into their flagship *central processors*.

They didn’t.

Unlike endpoint amplifiers—which only have to manage a handful of audio channels destined for a specific set of speakers—a core loudspeaker processor or matrix hub handles dozens or hundreds of simultaneous routing cross-points. Because of this massive processing scale, high-end system processors are designed with a strict “True Match” architectural ideology: the input streams must match the internal engine clock identically.

These heavy-duty central brains generally do not possess asynchronous sample rate converters across their primary network input cards. When you set that master processor to run at 96kHz, it completely blinds itself to 48kHz AVB streams. It cannot upscale them on entry the way the amplifiers did just an hour prior.

Not a Fault, But a Generational Shift
It is tempting to blame the conversion box in this scenario, but the box is doing exactly what it was asked to do: outputting a clean, stable 48kHz network stream. The breakdown occurs entirely because of a shift in engineering mindsets between different classes of DSP hardware.
An amplifier is designed to be a flexible destination; it adapts to whatever flavor of audio you feed it because it sits at the very end of the line. A core matrix processor, however, is designed to be the absolute master clock authority of a massive sound system; it demands total consistency across its inputs to maintain strict, deterministic processing latency and absolute mathematical accuracy

The Fix for the System Engineer
By the time the sun starts to set, the lesson is learned. To get out of this corner, you have two choices:

1. **The Compromise:** Force the central loudspeaker processor to drop its internal engine down to 48kHz to match your conversion box. You lose a tiny bit of high-sample-rate resolution on paper, but the network immediately locks, the audio flows, and the show goes on.

2. The Right Tool for the Job: Recognize that a 48 kHz console infrastructure and a 96kHz system processing core need a dedicated mediator. You introduce a heavy-duty, system-grade hardware network bridge—one specifically engineered with the massive asynchronous processing horsepower required to upscale a 48kHz world into a strict, pristine 96kHz network stream before it ever hits the processor’s input gate

the show must go on:

The Hybrid Infrastructure Compromise: If you are dealing with a permanent installation or a split system where some zones absolutely demand 96kHz networking but others are trapped in 48kHz, you start splitting lanes. You run an old-school, analog 2-wire copper lines straight into a handful of local amplifiers to bypass the network entirely, while simultaneously building an AES3-to-AVB hardware gateway elsewhere in the rack. By taking a 48 kHz AES3 feed and running it through a local gateway that handles the up-sampling to 96kHz AVB, you can feed the master processor exactly what it wants for the main array, leaving the copper to handle the rest.

In live sound, assuming that two pieces of gear from the same generation or ecosystem think the same way is the fastest route to a headache. Always look past the network jack on the chassis, check the clocking architecture under the hood, and remember that just because an amp can adapt, doesn’t mean the brain can.

Altec Lansing Flamenco spekers

the Altec Lansing 848A Flamenco is a highly revered vintage speaker system from the “golden era” of home hi-fi. Produced side-by-side with its sister model, the Valencia, from the mid-1960s to the mid-1970s, the Flamenco was designed to bring Altec’s legendary, massive “Voice of the Theater” (VOTT) cinematic sound into domestic living rooms.
Here is a breakdown of what makes the Flamenco speakers so notable:

Key Components & Specifications
Acoustic Lineage: The Flamenco relies on the same core components found in the famous A7 Voice of the Theater systems, repackaged in a domestically acceptable cabinet.
Woofer: Features the massive 15-inch Altec 416-Z bass driver, known for its effortless and natural low-end reproduction.
High-Frequency Array: Utilizes the 806A compression driver mated to an 811B aluminum multicell horn. This combination is famous for throwing an incredibly wide and dynamic soundstage.

Crossover: The signal is divided by the passive N-800F crossover network at 800 Hz.
Efficiency: They boast an incredibly high sensitivity (around 100 dB SPL), meaning they can be driven to room-filling volumes with as little as 1 to 5 watts of power.
Impedance: Early, highly desirable iterations were 16-ohm systems.

Design and Aesthetics
While Altec’s industrial speakers were purely utilitarian, the Flamenco was meant to be a piece of premium furniture.
Cabinetry: Constructed with an oak veneer (in contrast to the Valencia’s walnut finish).

The Grille: The most distinguishing feature of the Flamenco is its ornate, neo-Moorish or Spanish-style lattice grille. Described by Altec as “simulated wrought iron,” this dark grille gives the speaker a very bold, vintage aesthetic that provides a stark contrast to modern, minimalist audio gear.
Construction: The Flamenco featured heavy interior damping padding on all sides and a fully solid base to reduce cabinet resonance.

Why Audiophiles Love Them Today
Because of their extreme efficiency, Flamencos are highly sought after by fans of low-wattage Single-Ended Triode (SET) tube amplifiers. When paired with high-quality tube amplification, these speakers deliver a massive sense of scale, life-like vocal presence, and a dynamic energy that modern, narrow tower speakers often struggle to replicate.

The anatomy of a fader cap

Overall Geometric Topology & Curvature

  • Base Volume: Begin with a standard rectangular cuboid. The lateral sides (left and right) remain strictly planar and parallel to each other.

  • The Primary Saddle (Concave): The top face features a deep, concave cylindrical boolean subtraction running along the transverse axis. This creates the central “scoop” or saddle where the finger rests. The nadir of this curve sits precisely at the center point of the top plane.

  • The Crests and Downward Trail (Convex): The front and back edges of the concave saddle do not end in sharp corners. Instead, they transition into high-radius convex fillets. These rounded crests roll smoothly downward, transforming the horizontal top surface into the vertical front and back faces. This continuous curve creates a soft, sweeping drop-off on both ends of the longitudinal axis.

  • OLYMPUS DIGITAL CAMERA

     

 

Surface Topography: The Grip Grooves

  • Geometry/Displacement: Embedded entirely within the concave saddle are a series of parallel, shallow horizontal striations.

  • Orientation: These grooves run along the transverse axis (perpendicular to the fader’s sliding direction).

  • Shading Execution: In a PBR workflow, these should be handled via a normal map or displacement map using a subtle sine-wave profile. They are designed to catch grazing light, creating alternating horizontal micro-bands of soft specular highlights and self-shadowing (ambient occlusion) within the deeper scoop.

The Indicator Line Wrap

  • UV Projection: The stark indicator line requires a continuous UV projection mapped along the longitudinal axis.

  • Path of the Wrap: The solid band originates on the flat, lower-front vertical face. It sweeps seamlessly up and over the front convex crest, plunges directly through the center of the ribbed concave saddle (bisecting the horizontal grooves at a perfect 90-degree perpendicular angle), climbs up the rear convex crest, and drops down to terminate on the rear vertical face.

  • Material Contrast: The painted line must have an independent material ID or a mask. It requires a high-albedo, purely diffuse surface (Roughness 0.9+) with zero specularity, ensuring the line remains readable and does not reflect light the way the base plastic does.

Material & PBR Shading Instructions

  • Base Material: Dielectric polymer (injection-molded plastic).

    Index of Refraction (IOR): ~1.45

  • Roughness: Set to medium-low (approx. 0.35). The plastic should exhibit a slight sheen. Specular reflections should be visible but slightly blurred, simulating a micro-texture that prevents a perfect, mirror-like gloss.

  • Specular Highlights: The primary lighting interaction will occur on the front and back convex crests. These tight curves should act as sharp specular catchers, grabbing overhead lights and creating bright, curved horizontal glints that define the upper boundaries of the fader cap.

  • Shadowing: Soft shadowing and heavy ambient occlusion should pool in the central concave depression, contrasting with the highly illuminated convex lips.

Rotary Selector Switch (SelectorSwitch)

Rotary Selector Switch (SelectorSwitch)

The `SelectorSwitch` is a high-fidelity Tkinter Canvas-based widget designed to model discrete multi-position controls. It mimics the behavior of physical rotary switches found on industrial equipment, laboratory instruments, and high-end audio gear.

Continue reading

MDP – Multi Dimensional Panner

MDP – Multi Dimensional Panner

Demo: https://like.audio/MDP/

## Overview

The **Multi-Dimensional Panner (MDP)** is an advanced user interface concept designed for spatial audio mixing, object-based panning (e.g., Dolby Atmos), and complex parameter control. It extends the traditional “Linear Travelling Potentiometer” (LTP) by placing it within a free-floating, rotatable widget on a 2D plane.

Continue reading

CMDP: Circular Motion Displacement Potentiometer

CMDP: Circular Motion Displacement Potentiometer

DEMO: http://like.audio/CMDP

# CMDP: Circular Motion Displacement Potentiometer

Overview
The **Circular Motion Displacement Potentiometer (CMDP)** is a novel user interface concept designed for spatial audio mixing, microphone array management, and multidimensional sound control. It combines the precision of linear faders with the intuitive spatial organization of a polar coordinate system, allowing users to visualize and manipulate sound sources in a 360-degree field.

 

Continue reading

The Great Un-Boxing: Audio’s Transition from Signal to State

The Great Un-Boxing: Audio’s Transition from Signal to State

For decades, the broadcast world was defined by physics. We built facilities based on the “Box Theory”: distinct, dedicated hardware units connected by copper. The workflow was linear and tangible. If you wanted to process a signal, you pushed it out of one box, down a wire, and into another. The cable was the truth; if the patch was made, the audio flowed.

Today, we are witnessing the dissolution of the box.

The industry is currently navigating a violent shift from Signal Flow to Data Orchestration. In this new paradigm, the “box” is often a skeuomorphic illusion—a user interface designed to comfort us while the real work happens in the abstract.

From Pushing to Sharing

The fundamental difference lies in how information moves. In the hardware world, we “pushed” signals. Source A drove a current to Destination B. It was active and directional.

In the software world of IP and virtualization, we do not push; we share. The modern audio engine is effectively a system of memory management. One process writes audio data to a shared block of memory (a ring buffer), and another process reads it. The “wire” has been replaced by a memory pointer. We are no longer limited by the number of physical ports on a chassis, but by the read/write speed of RAM and the efficiency of the CPU.

The Asynchronous Challenge

This transition forces us to confront the chaos of computing. Hardware audio is isochronous—it flows at a perfectly locked heartbeat (48kHz). Software and cloud infrastructure are inherently asynchronous. Packets arrive in bursts; CPUs pause to handle background tasks; networks jitter.

The modern broadcast engineer’s challenge is no longer just “routing audio.” It is artificially forcing non-deterministic systems (clouds, servers, VMs) to behave with the deterministic precision of a copper wire. We are trading voltage drops for buffer underruns.

The “Point Z” Architecture

Perhaps the most radical shift is in topology. The line from Point A (Microphone) to Point B (Speaker) is no longer straight.

We are moving toward a “Point A → Cloud → Point Z → Point B” architecture. The “interface layer” is now a complex orchestration of logic that hops between cloud providers, containers, and edge devices before ever returning to the listener’s ear. The signal might traverse three different data centers to undergo AI processing or localized insertion, creating a web of dependencies that “Box Thinking” can never fully map.

The era of the soldering iron is giving way to the era of the stack. We are no longer building chains of hardware; we are architecting systems of logic. The broadcast facility of the future isn’t a room full of racks—it is a negotiated agreement between asynchronous services, sharing memory in the dark.

Rust Headless 96kHz Audio Console

Architecting a Scalable, Headless Audio Console in Rust

In the world of professional audio—spanning broadcast, cinema, and large-scale live events—the mixing console is the heart of the operation. Traditionally, these have been massive hardware monoliths. Today, however, the industry is shifting toward headless, scalable audio engines that run on standard server hardware, controlled remotely by software endpoints.

This article proposes the architecture for Titan-96k, a scalable, 32-bit floating-point audio mixing engine written in Rust. It is designed to handle everything from a simple podcast setup to complex 7.1.4 immersive audio workflows, controlled entirely via MQTT.

Continue reading

Linear Traveling Potentiometer – Software

February is Toronto AES Audio Engineering Society Member showcase….

The **Linear Travelling Potentiometer (LTP)** is a hybrid user interface widget designed to save screen real estate while maximizing control density. It integrates a rotary knob directly onto the cap of a linear fader, allowing simultaneous control of two related parameters (e.g., Level and Pan, or Send Level and Send Pan) in a single compact footprint.

Back in 2013, I presented a concept at the AES Toronto meeting called the “Linear Traveling Potentiometer” (LTP).

demo: https://like.audio/LTP/

The idea was simple but mechanically complex: Combine a linear fader and a rotary potentiometer into a single, fluid control. Two motions, one component.

I even had a prototype in a “black bag” that I let people feel without seeing. The goal was to control intensity (volume) and position (pan) simultaneously—a single-point coordinate system for surround sound and spatial audio.
For years, this existed mostly as hardware prototypes and sketches. But the vision never went away.

Now, nearly 15 years later, I have finally recreated my vision purely in software. Click, grab it like a fader… Move up for volume and sideways to pan…

I’ve brought the “Two in One” concept to life digitally. No moving parts, just the physics of the original idea translated into code.

It’s been a long road from that first presentation to this software build. Sometimes the technology just needs to catch up to the idea.



 

# builder_audio/dynamic_gui_create_custom_LTP.py
#
# A Linear Traveling Potentiometer (LTP) widget.
# Acts as a vertical fader, but the cap is a rotatable knob.
# Control + Drag rotates the knob (-100 to 100).
# Standard Drag moves the fader vertically.
# “Freestyle” mode allows adjusting both axes simultaneously (vertical=fader, horizontal=rotation).
#
# Author: Anthony Peter Kuzub
# Blog: www.Like.audio (Contributor to this project)
#
# Professional services for customizing and tailoring this software to your specific
# application can be negotiated. There is no charge to use, modify, or fork this software.
#
# Build Log: https://like.audio/category/software/spectrum-scanner/
# Source Code: https://github.com/APKaudio/
# Feature Requests can be emailed to i @ like . audio
#
# Version 20250821.200641.1
import tkinter as tk
from tkinter import ttk
import math
from managers.configini.config_reader import Config
app_constants = Config.get_instance()
# — Default Configuration Constants —
DEFAULT_LTP_WIDTH = 100
DEFAULT_MIN_VAL = 0.0
DEFAULT_MAX_VAL = 100.0
DEFAULT_LOG_EXPONENT = 1.0
DEFAULT_BORDER_WIDTH = 0
DEFAULT_BORDER_COLOR = “black”
DEFAULT_TICK_SIZE_RATIO = 0.2
DEFAULT_TICK_FONT_FAMILY = “Helvetica”
DEFAULT_TICK_FONT_SIZE = 10
DEFAULT_TICK_COLOR = “light grey”
DEFAULT_VALUE_FOLLOW = True
DEFAULT_VALUE_HIGHLIGHT_COLOR = “#f4902c”
DEFAULT_CAP_RADIUS = 18 # Radius of the knob cap (Increased by 20% from 15)
ROTATION_MIN = 100.0
ROTATION_MAX = 100.0
# ———————————————
from workers.logger.logger import debug_logger
from workers.logger.log_utils import _get_log_args
from workers.styling.style import THEMES, DEFAULT_THEME
from workers.handlers.widget_event_binder import bind_variable_trace
class CustomLTPFrame(tk.Frame):
def __init__(
self,
master,
config,
path,
state_mirror_engine,
base_mqtt_topic,
subscriber_router,
):
colors = THEMES.get(DEFAULT_THEME, THEMES[“dark”])
fader_style = colors.get(“fader_style”, {})
self.bg_color = colors.get(“bg”, “#2b2b2b”)
self.accent_color = colors.get(“accent”, “#33A1FD”)
self.neutral_color = colors.get(“neutral”, “#dcdcdc”)
self.track_col = colors.get(“secondary”, “#444444”)
self.handle_col = colors.get(“fg”, “#dcdcdc”)
self.text_col = colors.get(“fg”, “#dcdcdc”)
self.min_val = float(config.get(“value_min”, DEFAULT_MIN_VAL))
self.max_val = float(config.get(“value_max”, DEFAULT_MAX_VAL))
self.log_exponent = float(config.get(“log_exponent”, DEFAULT_LOG_EXPONENT))
self.reff_point = float(
config.get(“reff_point”, (self.min_val + self.max_val) / 2.0)
)
self.border_width = int(config.get(“border_width”, DEFAULT_BORDER_WIDTH))
self.border_color = config.get(“border_color”, DEFAULT_BORDER_COLOR)
# Cap Styling
self.cap_radius = int(config.get(“cap_radius”, DEFAULT_CAP_RADIUS))
self.cap_color = config.get(“cap_color”, self.handle_col)
self.cap_outline_color = config.get(“cap_outline_color”, self.track_col)
# Custom styling
self.tick_size = config.get(“tick_size”, fader_style.get(“tick_size”, DEFAULT_TICK_SIZE_RATIO))
tick_font_family = config.get(“tick_font_family”, fader_style.get(“tick_font_family”, DEFAULT_TICK_FONT_FAMILY))
tick_font_size = config.get(“tick_font_size”, fader_style.get(“tick_font_size”, DEFAULT_TICK_FONT_SIZE))
self.tick_font = (tick_font_family, tick_font_size)
self.tick_color = config.get(“tick_color”, fader_style.get(“tick_color”, DEFAULT_TICK_COLOR))
self.value_follow = config.get(“value_follow”, fader_style.get(“value_follow”, DEFAULT_VALUE_FOLLOW))
self.value_highlight_color = config.get(“value_highlight_color”, fader_style.get(“value_highlight_color”, DEFAULT_VALUE_HIGHLIGHT_COLOR))
self.value_color = config.get(“value_color”, self.text_col)
super().__init__(
master,
bg=self.bg_color,
bd=self.border_width,
relief=“solid”,
highlightbackground=self.border_color,
highlightthickness=self.border_width,
)
self.path = path
self.state_mirror_engine = state_mirror_engine
self.base_mqtt_topic = base_mqtt_topic
self.subscriber_router = subscriber_router
self.config = config
self.freestyle = config.get(“freestyle”, False)
# Initialize Variables
# Linear Value (Standard Fader)
self.linear_var = tk.DoubleVar(value=float(config.get(“value_default”, (self.min_val + self.max_val)/2)))
# Rotation Value (Knob)
self.rotation_var = tk.DoubleVar(value=float(config.get(“rotation_default”, 0.0)))
self.temp_entry = None
# Register Widgets with State Mirror Engine
if self.state_mirror_engine and self.path:
# Register main linear variable
self._register_sub_widget(“linear”, self.linear_var)
# Register rotation variable
self._register_sub_widget(“rotation”, self.rotation_var)
# Bind traces for Redraw
self.linear_var.trace_add(“write”, self._request_redraw)
self.rotation_var.trace_add(“write”, self._request_redraw)
def _register_sub_widget(self, suffix, variable):
if suffix == “linear”:
target_path = self.path
else:
target_path = f{self.path}/{suffix}
sub_config = self.config.copy()
sub_config[“path”] = target_path
if suffix == “rotation”:
sub_config[“value_min”] = ROTATION_MIN
sub_config[“value_max”] = ROTATION_MAX
self.state_mirror_engine.register_widget(target_path, variable, self.base_mqtt_topic, sub_config)
callback = lambda: self.state_mirror_engine.broadcast_gui_change_to_mqtt(target_path)
bind_variable_trace(variable, callback)
topic = self.state_mirror_engine.get_widget_topic(target_path)
if topic:
self.subscriber_router.subscribe_to_topic(topic, self.state_mirror_engine.sync_incoming_mqtt_to_gui)
self.state_mirror_engine.initialize_widget_state(target_path)
def _request_redraw(self, *args):
self.event_generate(“<<RedrawLTP>>”)
def _open_manual_entry(self, event, target_var, min_v, max_v):
if self.temp_entry and self.temp_entry.winfo_exists():
return
self.temp_entry = tk.Entry(self, width=8, justify=“center”)
self.temp_entry.place(x=event.x 20, y=event.y 10)
current_val = target_var.get()
self.temp_entry.insert(0, str(current_val))
self.temp_entry.select_range(0, tk.END)
self.temp_entry.focus_set()
submit_cmd = lambda e: self._submit_manual_entry(e, target_var, min_v, max_v)
self.temp_entry.bind(“<Return>”, submit_cmd)
self.temp_entry.bind(“<FocusOut>”, submit_cmd)
self.temp_entry.bind(“<Escape>”, self._destroy_manual_entry)
def _submit_manual_entry(self, event, target_var, min_v, max_v):
raw_value = self.temp_entry.get()
try:
new_value = float(raw_value)
if min_v <= new_value <= max_v:
target_var.set(new_value)
else:
if app_constants.global_settings[“debug_enabled”]:
debug_logger(
message=f“⚠️ Value {new_value} out of bounds! Ignoring.”,
**_get_log_args(),
)
except ValueError:
pass
self._destroy_manual_entry(event)
def _destroy_manual_entry(self, event):
if self.temp_entry and self.temp_entry.winfo_exists():
self.temp_entry.destroy()
self.temp_entry = None
class CustomLTPCreatorMixin:
def _create_custom_ltp(self, parent_widget, config_data, **kwargs):
label = config_data.get(“label_active”)
config = config_data
path = config_data.get(“path”)
layout_config = config.get(“layout”, {})
font_size = layout_config.get(“font”, 10)
custom_font = (“Helvetica”, font_size)
custom_colour = layout_config.get(“colour”, None)
state_mirror_engine = self.state_mirror_engine
subscriber_router = self.subscriber_router
base_mqtt_topic_from_path = kwargs.get(“base_mqtt_topic_from_path”)
colors = THEMES.get(DEFAULT_THEME, THEMES[“dark”])
bg_color = colors.get(“bg”, “#2b2b2b”)
secondary_color = colors.get(“secondary”, “#444444”)
frame = CustomLTPFrame(
parent_widget,
config=config,
path=path,
state_mirror_engine=state_mirror_engine,
base_mqtt_topic=base_mqtt_topic_from_path,
subscriber_router=subscriber_router,
)
if label:
lbl = tk.Label(frame, text=label, font=custom_font, background=bg_color, foreground=colors.get(“fg”, “#dcdcdc”))
if custom_colour:
lbl.configure(foreground=custom_colour)
lbl.pack(side=tk.TOP, pady=(0, 5))
width = layout_config.get(“width”, DEFAULT_LTP_WIDTH)
height = layout_config.get(“height”, 300)
canvas = tk.Canvas(
frame, width=width, height=height, bg=bg_color, highlightthickness=0
)
canvas.pack(fill=tk.BOTH, expand=True)
canvas.update_idletasks()
# Visual State
visual_props = {“secondary”: secondary_color}
hover_color = “#999999”
# Interaction State
drag_state = {“start_x”: 0, “start_y”: 0, “start_val_lin”: 0, “start_val_rot”: 0, “active”: False}
def on_press(event):
drag_state[“active”] = True
drag_state[“start_x”] = event.x
drag_state[“start_y”] = event.y
drag_state[“start_val_lin”] = frame.linear_var.get()
drag_state[“start_val_rot”] = frame.rotation_var.get()
if not (event.state & 0x0004): # No Ctrl
update_linear_from_y(event.y)
def on_drag(event):
if not drag_state[“active”]:
return
is_ctrl = event.state & 0x0004
if frame.freestyle:
# Vertical adjusts fader, Horizontal adjusts rotation
update_linear_from_y(event.y)
update_rotation_from_x(event.x)
elif is_ctrl:
# Rotation Mode (Vertical drag for rotation)
dy = drag_state[“start_y”] event.y
sensitivity = 2.0
new_rot = drag_state[“start_val_rot”] + (dy * sensitivity)
new_rot = max(ROTATION_MIN, min(ROTATION_MAX, new_rot))
frame.rotation_var.set(new_rot)
else:
# Linear Mode
update_linear_from_y(event.y)
def on_release(event):
drag_state[“active”] = False
def update_linear_from_y(y):
h = canvas.winfo_height()
norm_y = (y 20) / (h 40)
norm_y = 1.0 max(0.0, min(1.0, norm_y))
log_norm_pos = norm_y**frame.log_exponent
current_value = frame.min_val + log_norm_pos * (
frame.max_val frame.min_val
)
frame.linear_var.set(current_value)
def update_rotation_from_x(x):
w = canvas.winfo_width()
# Rotation area same length as fader height (h-40)
# Center it at the current rail? Or just relative to the whole canvas width.
# User said “area to move it left or right should be about the same length as the fader”
h = canvas.winfo_height()
fader_len = h 40
# Start rotation from center of canvas
cx = w / 2
# Offset from center
dx = x cx
# Map dx to rotation value. fader_len total width for full rotation range?
# So range is [-fader_len/2, fader_len/2]
norm_x = dx / (fader_len / 2.0)
norm_x = max(1.0, min(1.0, norm_x))
new_rot = norm_x * 100.0 # ROTATION_MAX
frame.rotation_var.set(new_rot)
def on_alt_click(event):
frame._open_manual_entry(event, frame.linear_var, frame.min_val, frame.max_val)
def redraw(*args):
current_w = canvas.winfo_width()
current_h = canvas.winfo_height()
if current_w <= 1: current_w = width
if current_h <= 1: current_h = height
_draw_ltp_vertical(
frame,
canvas,
current_w,
current_h,
visual_props[“secondary”]
)
frame.bind(“<<RedrawLTP>>”, redraw)
# Initial Draw
redraw()
# Bindings
canvas.bind(“<Button-1>”, on_press)
canvas.bind(“<B1-Motion>”, on_drag)
canvas.bind(“<ButtonRelease-1>”, on_release)
canvas.bind(“<Alt-Button-1>”, on_alt_click)
canvas.bind(“<Configure>”, lambda e: redraw())
def on_enter(event):
visual_props[“secondary”] = hover_color
redraw()
def on_leave(event):
visual_props[“secondary”] = secondary_color
redraw()
canvas.bind(“<Enter>”, on_enter)
canvas.bind(“<Leave>”, on_leave)
return frame
def _draw_ltp_vertical(frame, canvas, width, height, current_secondary):
canvas.delete(“all”)
cx = width / 2
# 1. Track Line
canvas.create_line(
cx, 20, cx, height 20,
fill=current_secondary, width=4, capstyle=tk.ROUND
)
# 2. Calculate Handle Position (Linear)
value_lin = frame.linear_var.get()
norm_value = (
(value_lin frame.min_val)
/ (frame.max_val frame.min_val)
if (frame.max_val frame.min_val) != 0
else 0
)
norm_value = max(0.0, min(1.0, norm_value))
display_norm_pos = norm_value ** (1.0 / frame.log_exponent)
handle_y = (height 40) * (1.0 display_norm_pos) + 20
# 3. Fill Line (from bottom to handle)
canvas.create_line(
cx + 2.5, height 20, cx + 2.5, handle_y,
fill=frame.value_highlight_color, width=5, capstyle=tk.ROUND
)
# 4. Draw Rotatable Cap (Knob)
rot_val = frame.rotation_var.get()
# 0 val = -90 degrees (Up)
angle_deg = 90 + (rot_val / 100.0) * 135.0
angle_rad = math.radians(angle_deg)
radius = frame.cap_radius
# Cap Circle
canvas.create_oval(
cx radius, handle_y radius,
cx + radius, handle_y + radius,
fill=frame.cap_color, outline=frame.cap_outline_color, width=2
)
# Pointer Line
pointer_len = radius * 0.8
px = cx + pointer_len * math.cos(angle_rad)
py = handle_y + pointer_len * math.sin(angle_rad)
canvas.create_line(
cx, handle_y, px, py,
fill=frame.cap_outline_color, width=2, capstyle=tk.ROUND
)
# Values Text
if frame.value_follow:
# Linear Value to the right
canvas.create_text(
cx + radius + 10,
handle_y,
text=f{value_lin:.1f},
fill=frame.value_color,
anchor=“w”,
font=(“Helvetica”, 8)
)
# Rotation Value to the left
canvas.create_text(
cx radius 10,
handle_y,
text=f“R:{rot_val:.0f},
fill=frame.value_color,
anchor=“e”,
font=(“Helvetica”, 8)
)

## Core Concepts

### 1. Hybrid Control
* **Linear Fader (Y-Axis):** The vertical position of the cap controls the primary value (typically Volume, Level, or Depth).
* **Rotary Knob (Rotation):** A knob embedded in the fader cap controls a secondary value (typically Pan, Param, or Intensity).
* **Unified Interaction:** Both controls are accessible from the same visual element, reducing mouse travel and UI clutter.

### 2. Interaction Modes
The LTP supports distinct interaction modes to prevent accidental changes:

* **Standard Mode:**
* **Drag Handle:** Adjusts Linear Value only.
* **Alt/Option + Drag:** Adjusts Rotary Value only (Linear position is locked).
* **Scroll:** Fine-tune Linear Value.
* **Alt/Option + Scroll:** Fine-tune Rotary Value.

* **Freestyle Mode:**
* Dragging the handle adjusts **BOTH** Linear and Rotary values simultaneously based on 2D mouse movement. This allows for gestural control (e.g., “throwing” a sound into a corner).

* **Pan Latch:**
* **Double-Click** the cap to engage “Pan Latch”.
* In this state, horizontal mouse movement adjusts the Rotary value without needing to hold a modifier key.
* Click or drag again to disengage.

### 3. Visual Feedback
* **Linear:** Position of the cap along the vertical track.
* **Rotary:** Orientation of the indicator line on the cap.
* **Active State:** The knob glows (default blue/orange) when Rotary control is active (via modifier, latch, or freestyle mode).
* **Pointer:** When adjusting rotation, the indicator line extends (10x length) to provide precise visual feedback, then retracts on release.

## Use Cases

* **Channel Strips:** Volume (Linear) + Pan (Rotary).
* **Effect Sends:** Send Level (Linear) + Pre/Post Toggle or Send Pan (Rotary).
* **Synthesizers:** Cutoff (Linear) + Resonance (Rotary).
* **Spatial Audio:** Distance (Linear) + Azimuth (Rotary – mapped to circular motion).

## Implementations

### HTML5 Demo (`index.html`)
A standalone web-based demonstration using HTML5 Canvas.
* **Features:** Multi-touch support (1 finger slide, 2 finger twist/pan), keyboard modifiers, responsive layout.
* **Theme:** Dark mode with high-contrast UI.

## The Open Concept License

This project is released under **The Open Concept License**.

* **Freedom:** You are free to use, modify, and distribute this work.
* **Attribution:** Explicit credit to **Anthony Kuzub** must be given in all derivative works.
* **Nomenclature:** Implementations must strictly use the terms **LTP (Linear Travelling Potentiometer)**, **GCA (Ganged Controlled Array)**, and **MDP (Multi-Dimensional Panner)** where applicable.
* **Warranty:** Provided “As Is” without warranty.

*(See the full license text in the application footer or source code.)*

 

Optimizing Data Acquisition: The Architecture of GET, SET, RIG, and NAB

High-Throughput Instrument Control Protocol

In the world of instrument automation (GPIB, VISA, TCP/IP), the primary bottleneck is rarely bandwidth—it is latency. Every command sent to a device initiates a handshake protocol that incurs a time penalty. When managing complex systems with hundreds of data points, these penalties accumulate, resulting in “bus chatter” that freezes the UI and blocks other processes.

Continue reading

The Mixer, My Grandfather, and the Looming Crisis of Unfixable Electronics

💡 The Mixer, My Grandfather, and the Looming Crisis of Unfixable Electronics

My weekend project—a powered mixer for a friend—was a powerful, hands-on lesson in the changing nature of electronics and the fight for the Right to Repair.

For a friend, I made an exception to my usual “no bench work” rule. The diagnosis was classic: a blown channel, likely from speakers incorrectly wired in parallel. Instead of a minimal patch job, I opted for a full refurbishment, the way I was taught: new, high-quality Panasonic FC caps and fresh, matched transistors. A labour of love, not profit. Continue reading

Immersive audio demonstration recordings

From Artist’s Intent to Technician’s Choice

In a world full of immersive buzzwords and increasingly complex production techniques, the recording artist’s original intentions can quickly become filtered through the lens of the technician’s execution.

I’ve been thinking about this a lot recently. I just acquired something that powerfully inspired my career in music—a piece of music heard the way it was truly intended before we fully grasped how to record and mix effectively in stereo. It was raw, immediate, and utterly captivating.

I feel we’re in a similar transition zone right now with immersive content production. We’re in the “stereo demo” phase of this new sonic dimension. We’re still learning the rules, and sometimes, the sheer capability of the technology overshadows the artistic purpose. The power of immersive sound shouldn’t just be about where we can place a sound, but where the story or the emotion demands it.

It brings me back to the core inspiration.

Putting the Mechanics into Quantum Mechanics

As we explore the frontier of quantum computing, we’re not just grappling with abstract concepts like superposition and entanglement—we’re engineering systems that manipulate light, matter, and energy at their most fundamental levels. In many ways, this feels like a return to analog principles, where computation is continuous rather than discrete.

A Return to Analog Thinking

Continue reading