diff --git a/CHANGELOG.md b/CHANGELOG.md index 41bf3da..6bfe443 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 `-` 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 @@ -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 @@ -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 `-` 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fcd3c7..10fdcac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/core/include/avsync/avsync.hpp b/core/include/avsync/avsync.hpp index 0266589..7c5cbdc 100644 --- a/core/include/avsync/avsync.hpp +++ b/core/include/avsync/avsync.hpp @@ -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"; diff --git a/docs/release-notes-2.2.0.md b/docs/release-notes-2.2.0.md new file mode 100644 index 0000000..8259f4c --- /dev/null +++ b/docs/release-notes-2.2.0.md @@ -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 + `-` 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. diff --git a/mobile-app/app.json b/mobile-app/app.json index 3757244..ee42c47 100644 --- a/mobile-app/app.json +++ b/mobile-app/app.json @@ -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": { diff --git a/mobile-app/modules/avsync/android/build.gradle b/mobile-app/modules/avsync/android/build.gradle index 3dc77a7..fd6a1b2 100644 --- a/mobile-app/modules/avsync/android/build.gradle +++ b/mobile-app/modules/avsync/android/build.gradle @@ -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 diff --git a/mobile-app/package-lock.json b/mobile-app/package-lock.json index 54b5a12..0bd6379 100644 --- a/mobile-app/package-lock.json +++ b/mobile-app/package-lock.json @@ -1,12 +1,12 @@ { "name": "mxl-avsync-phone", - "version": "2.0.8", + "version": "2.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mxl-avsync-phone", - "version": "2.0.8", + "version": "2.2.0", "dependencies": { "@expo/vector-icons": "~14.0.4", "expo": "~52.0.0", diff --git a/mobile-app/package.json b/mobile-app/package.json index d9b484e..3450cc1 100644 --- a/mobile-app/package.json +++ b/mobile-app/package.json @@ -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": {