# Qwen Audio Checker

A reusable command-line tool for collecting audio-quality evidence from a public Qwen demo. Use it for narrated videos, training clips, voiceovers, spoken presentations, podcast excerpts and other speech recordings up to **180 seconds**.

The custom code prepares and hashes the input, checks the demo revision, tests clean/silent/reversed controls, sends a full recording for assessment and then checks every sample through overlapping audio windows. Qwen provides the audio perception. This is an independent tool folder: it does not need any other project, account configuration or source repository.

It checks speech intelligibility, pronunciation, pacing/delivery, recording/mix quality and a complete ending. It does not verify facts, ownership, copyright, visual quality or subtitle synchronization. It is designed for speech; music-only material will usually be held because speech evidence is absent. Language/name uncertainty is reported rather than treated as a pass.

## Files

| File | Purpose |
| --- | --- |
| `tool.py` | Complete CLI, preparation, validation and demo client |
| `requirements.txt` | Direct Python dependencies with exact versions |
| `tests/test_tool.py` | Offline tests with synthetic WAV and mocked network |
| `SCHEMAS.md` | Input/output fields, statuses and report interpretation |
| `examples/reference.txt` | Optional neutral intended-wording example |
| `VALIDATION.md` | What has and has not been tested |

## Requirements and cost

- Python **3.11 or newer**. Python 3.11+ supplies the file-hashing API used here.
- `httpx==0.28.1` and `gradio_client==2.7.2` for online operations. Pip also installs their dependencies. There is no Qwen model download.
- FFmpeg for MP3, M4A, MP4 and other non-PCM16 inputs. Already compatible WAV files need only Python for preparation.
- Internet access for `calibrate` and `review`; `prepare` and the test suite work offline.

**The public demo is currently free to access without a user API key or paid account** (checked **2026-10-14**). This tool supplies no payment credential and does not call the separately billed Alibaba API directly. That does not promise unlimited capacity, continued free access or future availability. The official demo source uses a server-side API key for its hosted backend; those are the demo operator's credentials. Direct Alibaba Model Studio API use has separate pricing and terms.

Sources: [official demo](https://huggingface.co/spaces/Qwen/Qwen3.5-Omni-Offline-Demo), [pinned source used by this tool](https://huggingface.co/spaces/Qwen/Qwen3.5-Omni-Offline-Demo/blob/2888772e0aa651efa67c2ece0a3c5a23bcf91a50/app.py), [official Alibaba model pricing](https://www.alibabacloud.com/help/en/model-studio/model-pricing).

The pinned source routes requests to `qwen3.5-omni-plus`. The tool cannot independently verify the actual runtime model identity or input audio token usage. The word “Offline” in the demo's name does **not** mean that this client runs a model offline.

## Install on Windows

Open PowerShell in this folder. A typical location is `C:\Users\YOUR_NAME\Documents\MyTools\05-qwen-audio-checker`.

```powershell
py -3.11 -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe tool.py --help
```

If another supported Python is installed, substitute that version for `-3.11`. No virtual-environment activation or PowerShell execution-policy change is needed.

To convert non-PCM16 media, install FFmpeg. One Windows package-manager option is:

```powershell
winget install --id Gyan.FFmpeg --exact
```

Open a new terminal after installation and check `ffmpeg -version`. Alternatively, install from [FFmpeg's download page](https://ffmpeg.org/download.html) and provide its executable path with `--ffmpeg "C:\Tools\ffmpeg\bin\ffmpeg.exe"` on the `prepare` command.

## Install on macOS or Linux

From this folder:

```bash
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python tool.py --help
```

Check `python3 --version` first; it must be 3.11 or newer. Install Python using your platform's supported distribution if needed. On Debian/Ubuntu you may also need the matching Python `venv` package.

Optional FFmpeg installation:

```bash
# macOS with Homebrew
brew install ffmpeg

# Debian/Ubuntu
sudo apt update
sudo apt install ffmpeg
```

On other distributions, use the supported FFmpeg package or [official download guidance](https://ffmpeg.org/download.html). The code itself does not need elevated privileges.

## Workflow

Commands below use Windows PowerShell. On macOS/Linux replace `.\.venv\Scripts\python.exe` with `.venv/bin/python`; use normal platform paths. Always use a **new output directory**. Existing output directories are refused even if empty, so earlier evidence cannot be silently overwritten.

### 1. Prepare the recording locally

```powershell
.\.venv\Scripts\python.exe tool.py prepare "C:\Media\narration.mp4" --output "runs\narration-01"
```

Optional intended wording:

```powershell
.\.venv\Scripts\python.exe tool.py prepare "C:\Media\narration.wav" --reference "C:\Media\script.txt" --output "runs\narration-02"
```

The reference must be a UTF-8 text file containing 1–20,000 characters. It is optional. If present, the tool performs a separate full-clip reference pass in addition to the blind pass; all windows are still assessed blind.

Preparation creates `bundle.json`, `audio.wav` and optionally `reference.txt`. It contacts no service. PCM16 mono/stereo WAV at 8–96 kHz is copied with its samples unchanged. Other formats use FFmpeg to decode the **first audio track** to PCM16, mono, 48 kHz. This downmix/resampling can change channel-specific details; use an already compatible stereo WAV if preserving stereo is important. No normalization, silence removal or speed change is applied. Converted inputs exceeding 180 seconds are rejected; conversion is bounded at 181 seconds to avoid processing an indefinitely long input. Rejected output contains a failure record, not a usable bundle.

For material longer than three minutes, deliberately prepare shorter excerpts with clear boundaries using your editor. Keep the original input file and the bundle files unchanged: the tool checks both on every review. A moved original will require preparing a new bundle.

### 2. Establish a known-good calibration

Choose a clear spoken recording you have actually listened to. It should have at least 12 seconds of uninterrupted, understandable speech near the beginning and comfortably more than eight words. Five seconds is the minimum accepted length; a shorter sample is less useful. Avoid music, long pauses and ambiguous speech in this control.

If necessary, prepare this recording as in step 1. Then:

```powershell
.\.venv\Scripts\python.exe tool.py calibrate "runs\known-good\audio.wav" --output "runs\calibration-01" --known-good --send-audio
```

`--known-good` is your confirmation that a human has listened to this reference. `--send-audio` explicitly permits this operation to send it to the public demo. Both flags are required. The tool sends three controls derived from the first 12 seconds: the unchanged audio, silence and reversed audio. It records the raw model text and structured findings. A successful schema/control check produces `calibration_candidate`; inspect the returned words and descriptions before relying on it.

Reuse an inspected calibration report only while its input files and the pinned demo revision stay unchanged. Recalibrate if the service's behavior changes. Passing these simple controls does not prove reliable assessment of every accent, language or defect.

### 3. Review the actual recording

```powershell
.\.venv\Scripts\python.exe tool.py review "runs\narration-01\bundle.json" --calibration "runs\calibration-01\report.json" --output "runs\review-01" --send-audio
```

The tool:

1. Verifies bundle, source, calibration and control hashes.
2. Checks the exact official demo revision, host and advertised API signature. It stops if these have changed.
3. Sends the full clip blind and, if supplied, with the intended-wording reference.
4. Splits the PCM samples into 12-second windows with 0.5-second overlaps and sends each window blind, marking only the last as final.
5. Records precise submitted sample ranges, raw responses, findings and validation errors.

Each review makes one full-clip request, optionally one reference request, and one request per window. A 60-second clip has six windows: seven requests without a reference, eight with one. Calibration makes three additional requests. Requests run sequentially; this is a public demo, not a batch-production service.

Window coverage uses local sample counts. Model-estimated timestamps are deliberately not requested or accepted as coverage evidence. Complete submitted coverage does not establish perfect perception by the model. A full-clip acoustic failure stays held even if the windows pass.

### 4. Inspect the evidence

Open `runs/review-01/report.json` in a text editor. Check `status`, `errors`, each full-clip response, every window's heard words and acoustic findings, and the `coverage` section. Listen to any uncertain or suspicious passage yourself.

- `candidate_evidence_requires_inspection`: all mechanical/schema checks and model-reported checks passed; the result still requires judgment.
- `held`: missing evidence, an acoustic failure or uncertainty exists. Inspect and address the cause.
- `failed`: service, parsing, file integrity or other execution problem interrupted the run.

Every report has `publication_approved: false`. The tool never approves, uploads, publishes or changes your original media. It does not turn a model opinion into a quality guarantee.

## Privacy and security

`prepare` is local. `calibrate` sends control audio. `review` sends the full audio, window audio and optional reference text to the official Hugging Face Space and its Alibaba backend. Use recordings you are permitted to share with these services. Their retention and data-use terms apply; this client cannot enforce server-side deletion or a no-retention guarantee.

No user API key, Hugging Face token or browser cookie is supplied. The client sets `HF_HUB_DISABLE_IMPLICIT_TOKEN=1`, uses `token=False`, disables its analytics and uses a fixed host. Network configuration does not inherit environment proxy settings. Generated reports remain local and can contain file paths, transcripts and sensitive spoken material. Keep `runs/`, private media and references out of public source repositories.

This code does not automatically retry failed jobs or rerun failed assessments. Gradio handles its normal queue protocol, but the application submits each job once. Existing run directories are never reused. If a transient outage warrants retrying, inspect the failure and deliberately use a new output directory; retain the earlier record.

## Tests and troubleshooting

Offline tests need only Python:

```powershell
python -m unittest discover -s tests -p "test_*.py" -v
```

They mock online requests and use synthetic PCM. No calibration or review command against the live demo is run by the test suite. See [VALIDATION.md](VALIDATION.md) for the tested scope.

| Message/problem | Action |
| --- | --- |
| `FFmpeg is required` | Install FFmpeg, pass `--ffmpeg`, or provide compatible PCM16 WAV. |
| Existing output directory | Choose a fresh directory; preserve the earlier evidence. |
| Missing/changed evidence | Restore the exact original or prepare and review the new file version. |
| Demo revision/host/signature changed | Stop and inspect the new official source; changing the pin without review defeats the check. |
| Calibration held | Inspect the actual controls and raw responses; use a genuinely clear human-reviewed sample or wait for service recovery. |
| Demo unavailable, quota/rate limit, timeout | Keep the failed report. The public demo has no availability guarantee. Retry deliberately later if warranted. |
| Unexpected JSON / missing acoustic evidence | The report is held or failed; do not convert it to a pass by editing evidence. |
| Corporate proxy required | This version disables inherited proxies. Arrange approved direct access or have a developer add an explicit, reviewed proxy option. |

Exit status is `0` for successfully prepared bundles or complete candidate evidence, and `2` for held/failed operations and input errors. Exit `0` never means publication approval.
