File size: 3,760 Bytes
132616b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
---
license: mit
library_name: onnx
pipeline_tag: audio-classification
tags:
  - audio
  - speech
  - speech-quality-assessment
  - acoustic-echo-cancellation
  - aec
  - aecmos
  - mos
  - onnx
---

# AECMOS (ONNX) — non-intrusive MOS estimator for acoustic echo cancellation

AECMOS is a neural, **non-intrusive** (no clean reference needed) speech-quality
estimator for acoustic echo cancellation. Given the three signals of an AEC
scenario — the far-end **loopback** (`lpb`), the **mic** capture, and the AEC's
**enhanced** output (`enh`) — it predicts two mean-opinion-score values:

- **Echo MOS** — how well the echo was removed, and
- **Other / degradation MOS** — how much the near-end speech was degraded.

This repository re-hosts the pretrained **ONNX** weights, unmodified, so they can
be pulled programmatically (e.g. from a pure-Dart runtime) instead of cloning the
full challenge repo.

## Provenance & license

These models are from Microsoft's **AEC-Challenge** repository
(`AECMOS/AECMOS_local`): <https://github.com/microsoft/AEC-Challenge>. They are
released there under the **MIT license** (Copyright © Microsoft Corporation), and
are re-hosted here **unmodified** under the same MIT license for convenience.
Attribution and the AECMOS method belong to the original authors; see the
AEC-Challenge repo and the AECMOS paper (*AECMOS: A speech quality assessment
metric for acoustic echo cancellation*, ICASSP 2022) for details and citation.

If you use these models, please cite the original AECMOS work and Microsoft's
AEC-Challenge, not this mirror.

## Files

Each file's Microsoft "run id" is in its name; the scorer selects its
configuration from that id.

| file | run id | sampling rate | STFT `n_fft` | GRU hidden | scenario marker |
|------|--------|---------------|--------------|------------|-----------------|
| `aecmos_1663915512.onnx` | 1663915512 | 16 kHz | 513 | `[4, 1, 64]` | yes |
| `aecmos_1668423760.onnx` | 1668423760 | 48 kHz | 1537 | `[4, 1, 96]` | yes |

> **Not included:** run id `1663829550` (16 kHz, no scenario marker). It is
> available from the upstream AEC-Challenge repo; this mirror only carries the two
> files above.

Inputs are the three signals as mono PCM scaled to `[-1, 1)`; the front-end is a
librosa-parity log-mel spectrogram (160 mel bands, odd `n_fft`, periodic Hann,
Slaney mel filterbank, `power_to_db` with `ref=max`/`top_db=80`, then `(x+40)/40`
normalization), stacked to a `[1, 3, frames, 160]` tensor with the GRU state
zeroed.

## Usage

### Pure Dart — no ONNX Runtime / FFI

These run on the pure-Dart inference engine
[`onnx_runtime_dart`](https://github.com/CrispStrobe/onnx_runtime_dart) (conv +
max-pool + bidirectional GRU, matched to the Python reference to ~1e-6), so
scoring works on every target including web/WASM.

```dart
// See onnx_runtime_dart/example/aecmos/ for AecmosScorer + the mel front-end.
final scorer = AecmosScorer('aecmos_1663915512.onnx');
final (:echoMos, :otherMos) = scorer.score('dt', lpb, mic, enh); // st | nst | dt
```

The [CometBeat](https://github.com/CrispStrobe/cometbeat) music app ships a
headless CLI wrapper for AEC-quality evaluation:

```bash
# Drop a model into the model cache, then score a scenario (headerless PCM16 mono):
mkdir -p ~/.cache/onnx_runtime_dart_models
huggingface-cli download cstr/aecmos-onnx aecmos_1663915512.onnx \
  --local-dir ~/.cache/onnx_runtime_dart_models
dart run bin/aecmos.dart ~/.cache/onnx_runtime_dart_models/aecmos_1663915512.onnx \
  lpb.raw mic.raw enh.raw dt
```

`st` = far-end single-talk, `nst` = near-end single-talk, `dt` = double-talk.

### Download

```python
from huggingface_hub import hf_hub_download
path = hf_hub_download("cstr/aecmos-onnx", "aecmos_1663915512.onnx")
```