Skip to content

v1.2.1

Latest

Choose a tag to compare

@github-actions github-actions released this 16 Aug 18:35
· 12 commits to main since this release

Phonalyser 1.2.1

Released 2026-08-16.

This release makes the QA40x a good citizen on a shared bench, adds a bench that
needs no hardware at all, and brings the browser port level with the desktop.

Highlights

A digital loopback backend. What the playback lane quantises is what the capture lane delivers, with no operating-system device in between. The samples are dithered at the last bit of the selected depth, so the measured noise floor is the arithmetic one - 0.500 LSB RMS, one bit deeper moving it down by 6 dB - and any deviation is the code under test rather than a sound card. It needs no hardware, no permission and no driver, and it is available on every platform and in the browser alike, at 16, 20, 24 or 32 bits on both directions.

The QA40x is free the moment nothing measures with it. The analyzer is claimed while a measurement runs and handed back when the last of the generator, the scope and the FFT stops, so the vendor software, a second Phonalyser or another browser tab can have it without anything being restarted. Reading its telemetry or its calibration page is atomic in the same sense: the device is opened, read and released again. An analyzer another program is holding is not offered as a local device at all, and reappears by itself once it is free.

The analyzer's factory data is read once. The calibration page - 128 register round trips - and the telemetry reading are kept per analyzer serial number, so a panel that only displays values touches no hardware and a reopen after a release costs nothing. A unit swapped for another of the same model cannot inherit the first one's factors, and the open no longer resets the USB device.

A range nobody has chosen is the protected one. A card created for an analyzer that has never had a range selected comes up at +42 dBV in and -12 dBV out - maximum input attenuation and the low output range, the state every teardown parks to - instead of the vendor's 0 dBV / +18 dBV pair.

The net protocol is v2: every capture streams on its own connection. Audio no longer shares the control WebSocket, so control commands stay responsive while PCM streams at full rate.

One server jar for every platform. The headless server ships as phonalyser-server-<version>.jar, with no architecture in its name: it carries the device libraries for all of them, so the same file runs on Windows, Linux and macOS, on x86-64 and on arm64, and a bare java -jar opens devices with nothing staged beside it. The six downloads stay per-platform for what surrounds it - the natives their launcher points at, the launch script and the service integration.

The distortion table's level cells have a unit selector. The THD/IMD table's per-line levels can be read in the unit of choice instead of dBV alone. The FFT view therefore carries two unit selectors: one for the vertical axis, one in the toolbar for the tables. Desktop and web alike.

Other additions. A standalone device scanner that prints every backend's devices with the exact rates and depths they take; an FAQ chapter in the help with its own live search, in every help language; Linux devices named by their card's product name and socket rather than the chip-and-address spelling.

Fixed

  • The largest FFT lengths produced no spectrum at all. The analysis span was clamped to the capture buffer and demanded in one contiguous read, so a frame longer than that buffer - four million points at 48 kS/s is 87 seconds of audio against a 22-second buffer - could never be assembled, and the measurement stayed in a permanent buffer-overrun re-sync. The analyser now gathers its frame into its own buffer across successive reads.
  • Exclusive-mode devices taking 24 or 32 bits only as plain WAVEFORMATEX were refused, and devices taking 24 valid bits in a 32-bit container were not offered at 24. Both are fixed, and a device's default format no longer varies from run to run.
  • Linux capability scans now read the exact formats and rates from the direct hardware device when /proc/asound has no answer, so PCI and HDA cards report what their converter actually takes; ALSA unity-gain pinning no longer skips cards whose volume controls match no port name.
  • "Snap frequency to nearest FFT bin" used the output clock, so with unequal input and output rates the snapped tone landed off the analysis bin grid and the averaged spectrum smeared.
  • The scope's calibrate button stayed off on wide input ranges, refusing levels whose absolute accuracy is beyond question.
  • Closing the frequency-response progress window did not stop the sweep.
  • The oscilloscope's Utility tab stayed English in every language.
  • Plus the browser's own list: the generator could not start from a deployed build, generator start/stop did not restart the statistics, the interface font preferences did not reach the canvas-drawn blocks, infinite averaging fell back to the default on reload, and Firefox offered no output devices.

Browser support

The QA40x is driven over WebUSB, which Chrome, Chromium and Brave support - there the browser measures with the analyzer directly. Edge and Opera run the Web Audio backend only. Every browser can use the loopback backend and a Phonalyser server on the network.

Upgrading

The net protocol is v2 and is not backward compatible: a 1.2.1 client pairs with a 1.2.1 server. Update both ends together.

Server downloads are now the per-platform ZIPs alone - each already carries the server's fat jar beside the natives, the launcher and the service scripts.

The jar inside them lost its platform suffix (phonalyser-server-<version>.jar). The launch and service scripts find it by pattern, so an existing installation keeps working; a service installed from an earlier bundle still points at the old file name, and re-running install-service after unpacking the new ZIP is what moves it over.