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
57 changes: 31 additions & 26 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,37 @@
black mask), QR code to the project site. Board files CERN-OHL-P-2.0, firmware MIT.
A first batch of 10 is ordered; not tested yet.

## Mobile (not released yet)
## 2.2.0 (2026-11-09) and Mobile 2.2.0 (2026-11-09)

Release notes: [docs/release-notes-2.2.0.md](docs/release-notes-2.2.0.md). AVS4 is not
compatible with 2.1.x: update containers, iPhones and Android phones together.

### Container

- Analyzer (live and file): subtracts the sender calibration from the AVS4 QR
from `av_offset_ms` (and `deviation_ms`, grade, metrics). Events keep
`raw_av_offset_ms` and `sender_calibration_ms`; `/api/v1/measurement` has
`raw_offset_ms` and `sender_calibration_ms`; the web UI Input card shows
"AV sync raw"; the file result `summary` has `sender_calibration_ms` and
`median_raw_av_offset_ms`. Not calibrated: no change.
- Generator: the default `AVSYNC_TEST_ID` is now `<NMOS seed>-` plus a short
hash of the seed, the app version and the timing settings (event rate, audio
timecode, video format, AV offset, audio/video lead, source emit offsets),
the same rule as the iPhone generator. It
stays the same over restarts. A set `AVSYNC_TEST_ID` is used as before.
`GET /api/v1/generator` shows the `test_id` in use; the settings page shows
it greyed in the empty `AVSYNC_TEST_ID` field.
- Picture QR **AVS4** (replaces AVS2/AVS3, no backwards compatibility): carries
the real test ID, the Signal form Title (`AVSYNC_SOURCE`) as the generator name and the sender
calibration (not calibrated for now). Same QR size, error correction M. The
analyzer's `/api/v1/status` has a new `signal` object (`test_id`, `name`,
`sender_calibration`, …) and the web UI shows it in the Input card. File
generator and analyzer use AVS4 too (SPECIFICATION "QR + optical code").
- Container generator: `AVSYNC_PATTERN=calibration` (live; Signal API
`pattern`, web form "Picture") sends the calibration pattern instead of the
test signal, for a phone with the calibrator on a TV or monitor.

### Mobile

- Test signal (iPhone and Android) no longer stops by itself about 5 minutes
after the last clock check ("Clock reference expired"). The app keeps
Expand Down Expand Up @@ -61,9 +91,6 @@
too (not saved). New camera view method `beginCalibrator(mode)`, generator
option `mode: 'calibration'` and `senderCalibration*` options. Not tested
with a real board yet (`docs/calibration.md`, `docs/calibrator.md`).
- Container generator: `AVSYNC_PATTERN=calibration` (live; Signal API
`pattern`, web form "Picture") sends the calibration pattern instead of the
test signal, for a phone with the calibrator on a TV or monitor.
- iPhone generator: the source ID stays the same when the generator is stopped
and started again. It changes only after a reinstall, a new app version or
build, or another event rate; name, subtitle and image do not change it
Expand Down Expand Up @@ -119,28 +146,6 @@
- Android: the instrumented test (`connectedDebugAndroidTest`) builds; React
Native's `libc++_shared.so` and the module's no longer collide.

## Container (not released yet)

- Analyzer (live and file): subtracts the sender calibration from the AVS4 QR
from `av_offset_ms` (and `deviation_ms`, grade, metrics). Events keep
`raw_av_offset_ms` and `sender_calibration_ms`; `/api/v1/measurement` has
`raw_offset_ms` and `sender_calibration_ms`; the web UI Input card shows
"AV sync raw"; the file result `summary` has `sender_calibration_ms` and
`median_raw_av_offset_ms`. Not calibrated: no change.
- Generator: the default `AVSYNC_TEST_ID` is now `<NMOS seed>-` plus a short
hash of the seed, the app version and the timing settings (event rate, audio
timecode, video format, AV offset, audio/video lead, source emit offsets),
the same rule as the iPhone generator. It
stays the same over restarts. A set `AVSYNC_TEST_ID` is used as before.
`GET /api/v1/generator` shows the `test_id` in use; the settings page shows
it greyed in the empty `AVSYNC_TEST_ID` field.
- Picture QR **AVS4** (replaces AVS2/AVS3, no backwards compatibility): carries
the real test ID, the Signal form Title (`AVSYNC_SOURCE`) as the generator name and the sender
calibration (not calibrated for now). Same QR size, error correction M. The
analyzer's `/api/v1/status` has a new `signal` object (`test_id`, `name`,
`sender_calibration`, …) and the web UI shows it in the Input card. File
generator and analyzer use AVS4 too (SPECIFICATION "QR + optical code").

## 2.1.1 (2026-11-04) and Mobile 2.0.8 build 12 (2026-11-04)

TestFlight build 12 was built from the PR head before this release commit (same
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.24)
project(mxl-avsync VERSION 2.1.1 LANGUAGES C CXX)
project(mxl-avsync VERSION 2.2.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
4 changes: 2 additions & 2 deletions core/include/avsync/avsync.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ inline constexpr int kYWhite = 940;
inline constexpr int kYBackground = 502;
inline constexpr int kYNeutralChroma = 512;

inline constexpr char kCoreVersion[] = "2.1.1";
inline constexpr char kAppVersion[] = "2.1.1";
inline constexpr char kCoreVersion[] = "2.2.0";
inline constexpr char kAppVersion[] = "2.2.0";
inline constexpr char kMxlRevision[] = "218ddaa0a08c12ffe75fc475ae65aa3d9eef16d7";
inline constexpr char kQrSchema[] = "mxl-avsync/1";
inline constexpr char kManifestSchema[] = "mxl-avsync-manifest/1";
Expand Down
62 changes: 62 additions & 0 deletions docs/release-notes-2.2.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# mxl-avsync 2.2.0

Calibration with the calibrator board, an Android test signal, sender
calibration in a new picture QR (AVS4), and a test signal on the phone that no
longer stops after 5 minutes. Full list in [CHANGELOG](../CHANGELOG.md).

## Picture QR AVS4 (update everything together)

- AVS4 replaces AVS2/AVS3. Old phones and containers cannot read it, and 2.2.0
cannot read the old QRs: update all containers, iPhones (TestFlight) and
Android phones (APK) at the same time.
- It carries the real test ID, the generator name (Title, at most 24 bytes) and
the sender calibration. Same QR size; error correction M instead of Q.
- Analysers (phone, container, file) subtract the sender calibration from the
AV offset and keep the raw value next to it. Containers send "not
calibrated", so container to container nothing changes.

## Calibrator board

- Settings → With calibrator (iPhone and Android): step 1 plug in, step 2
camera vs microphone (flash + click on the rear camera), step 3 screen vs
speaker (the generator's calibration pattern; saved as the phone's sender
calibration and sent in the QR).
- A TV or monitor can be measured with the container's calibration pattern
(`AVSYNC_PATTERN=calibration`).
- Board files, firmware and signal contract: `hardware/calibrator/`,
[calibrator.md](calibrator.md). The first boards are ordered; nothing is
tested with a real board yet.

## Phone app

- Android test signal, same as the iPhone (picture, options, QR, stable sender
ID, "Stopped" screen, calibration mode). Not tested on a phone yet.
- The test signal no longer stops about 5 minutes after the last clock check:
the app keeps checking the clock and the signal slews to each check (at most
0.1 ms per second, never jumping). A signal started before the first check
switches from device UTC to NTP UTC.
- Stable sender ID; Results grouped by sender with nicknames (default: the
Title from the QR), a reference per sender and Δ values; tap to focus.
- Stop shows a large "Stopped"; Clear calibration asks first and clears both
calibrations.
- Android: 120/240 fps via the high-speed camera mode, icons and status bar
fixed, test APK from GitHub Actions.
- Shipped as TestFlight Mobile 2.2.0 and the Android APK from the v2.2.0 tag.

## What changes for the platform

- Not compatible with 2.1.x (AVS4). Generator and analyzer share one pin, so
they move together.
- Default test ID: with `AVSYNC_TEST_ID` unset, the generator uses
`<NMOS seed>-` plus a short hash of the seed, the app version and the timing
settings. It stays the same over restarts but changes with each version. A
set `AVSYNC_TEST_ID` is used as before.
- New setting `AVSYNC_PATTERN` (default `test`, live; `calibration` sends the
calibrator pattern). Nothing else in the environment changes.
- Analyzer `/api/v1/status` has a new `signal` object; `/api/v1/measurement`
and events gain `raw_offset_ms` / `raw_av_offset_ms` and
`sender_calibration_ms` when the QR carries a calibration.
- No metric is new, renamed or removed. Ports, NMOS resources and labels are
unchanged. The analyzer's source emit offsets (`AVSYNC_SOURCE_EMIT_*`) keep
their meaning; they are separate from the sender calibration.
- In-place upgrade.
2 changes: 1 addition & 1 deletion mobile-app/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"expo": {
"name": "AVsync",
"slug": "mxl-avsync",
"version": "2.0.8",
"version": "2.2.0",
"icon": "./assets/icon.png",
"orientation": "portrait",
"androidStatusBar": {
Expand Down
2 changes: 1 addition & 1 deletion mobile-app/modules/avsync/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apply plugin: 'com.android.library'

group = 'io.leeo86.mxl.avsync'
version = '2.0.8'
version = '2.2.0'

def expoModulesCorePlugin = new File(project(':expo-modules-core').projectDir, 'ExpoModulesCorePlugin.gradle')
apply from: expoModulesCorePlugin
Expand Down
4 changes: 2 additions & 2 deletions mobile-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mobile-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mxl-avsync-phone",
"version": "2.0.8",
"version": "2.2.0",
"private": true,
"main": "node_modules/expo/AppEntry.js",
"scripts": {
Expand Down
Loading