> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/curator/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/curator/_mcp/server.

> AudioDataFilterStage composite — end-to-end audio curation pipeline that decomposes into VAD, band, UTMOS, SIGMOS, and speaker separation sub-stages from a single YAML config

# `AudioDataFilterStage` Composite Pipeline

`AudioDataFilterStage` is a `CompositeStage` that decomposes into a configurable sequence of audio sub-stages for extracting clean single-speaker segments from raw audio files. Use it when you want the full quality-filtering pipeline driven by a single YAML config instead of wiring stages individually.

## Understanding the Composite

### What It Does

A `CompositeStage` is a stage that, at pipeline build time, expands into a sequence of underlying stages. `AudioDataFilterStage` expands into the audio quality-filtering chain — preprocessing, VAD, band, UTMOS, SIGMOS, concatenation, speaker separation, per-speaker filters, and timestamp mapping — using parameters loaded from a YAML config.

This serves two purposes:

1. **Single-config pipelines**: tune the entire pipeline in one place instead of editing many `pipeline.add_stage(...)` calls.
2. **Resource declarations live with the stage**: each sub-stage's CPU/GPU allocation is set in the same YAML, alongside its functional parameters.

### Default Pipeline Order

When all sub-stages are enabled, the composite expands into:

1. **`MonoConversionStage`** — normalize channels and sample rate.
2. **`VADSegmentationStage`** — split into speech segments.
3. **`BandFilterStage`** — drop segments not matching the target bandwidth.
4. **`UTMOSFilterStage`** — drop segments below the MOS threshold.
5. **`SIGMOSFilterStage`** — drop segments failing any active SIGMOS dimension.
6. **`SegmentConcatenationStage`** — concatenate surviving segments with silence gaps.
7. **`SpeakerSeparationStage`** — diarize and fan out one task per speaker.
8. **Per-speaker filters** — rerun VAD + Band + UTMOS + SIGMOS on each speaker's audio.
9. **`TimestampMapperStage`** — project final boundaries back to original-file timestamps.

### When to Use the Composite vs Individual Stages

| Approach                           | Use When                                                                                                                                    |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `AudioDataFilterStage` (composite) | Standard end-to-end curation; you want YAML-driven configuration; you want all sub-stages enabled.                                          |
| Individual stages                  | You only need part of the pipeline (e.g., VAD + UTMOS without speaker separation), or you need to interleave audio stages with custom code. |

## Basic Usage

### Step 1: Pick a Config Source

Construct the stage from a YAML config file:

```python
from nemo_curator.stages.audio.advanced_pipelines.audio_data_filter import AudioDataFilterStage

audio_filter = AudioDataFilterStage(config_path="./audio_filter.yaml")
pipeline.add_stage(audio_filter)
```

Or pass a config dict inline:

```python
audio_filter = AudioDataFilterStage(
    config={
        "vad": {"enable": True, "min_duration_sec": 1.0},
        "utmos": {"enable": True, "mos_threshold": 3.0},
        "sigmos": {"enable": False},
        "speaker_separation": {"enable": True},
    },
)
```

If neither `config_path` nor `config` is provided, the bundled default config is used.

### Step 2: Customize the YAML

Each top-level key maps to one sub-stage; set `enable: false` to skip it. The default configuration shipped with the stage:

```yaml
mono_conversion:
  output_sample_rate: 48000
  strict_sample_rate: true
  cpus: 1.0

vad:
  enable: true
  min_duration_sec: 2.0
  max_duration_sec: 60.0
  threshold: 0.5
  min_interval_ms: 500
  speech_pad_ms: 300
  cpus: 1.0
  gpus: 0.1

band_filter:
  enable: true
  band_value: full_band
  cpus: 1.0
  gpus: 0.0

utmos:
  enable: true
  mos_threshold: 3.4
  cpus: 1.0
  gpus: 0.1

sigmos:
  enable: true
  noise_threshold: 4.0
  ovrl_threshold: 3.5
  sig_threshold: null
  col_threshold: null
  disc_threshold: null
  loud_threshold: null
  reverb_threshold: null
  cpus: 1.0
  gpus: 0.1

concatenation:
  silence_duration_sec: 0.5
  cpus: 1.0

speaker_separation:
  enable: true
  exclude_overlaps: true
  min_duration: 0.8
  gap_threshold: 0.1
  buffer_time: 0.5
  cpus: 1.0
  gpus: 0.3

timestamp_mapper:
  passthrough_keys: null
  cpus: 1.0
```

The parameters mirror the sub-stage's constructor arguments. See the per-stage pages linked at the bottom for parameter details.

The default UTMOS threshold in the YAML config is `3.4`, while the standalone `UTMOSFilterStage` class default is `3.5`. The composite uses the YAML value when constructed from the bundled config; tune as needed for your data.

### Step 3: Disable Unneeded Stages

Each sub-stage with `enable:` accepts `false` to skip it. Common partial pipelines:

| Pipeline                   | Disable                                                                                                        |
| -------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **VAD-only**               | `band_filter.enable: false`, `utmos.enable: false`, `sigmos.enable: false`, `speaker_separation.enable: false` |
| **Quality-only**           | `speaker_separation.enable: false` (keeps audio whole instead of fanning out per speaker)                      |
| **Single-speaker known**   | `speaker_separation.enable: false` (substantial GPU savings when input has one speaker)                        |
| **No bandwidth filtering** | `band_filter.enable: false`                                                                                    |

## Common Configurations

### High-Quality TTS Training Data

Strict thresholds across all dimensions, no narrowband, no high-reverb:

```yaml
mono_conversion:
  output_sample_rate: 48000
vad:
  enable: true
  min_duration_sec: 3.0
band_filter:
  enable: true
  band_value: full_band       # full-band only
utmos:
  enable: true
  mos_threshold: 4.0          # strict
sigmos:
  enable: true
  noise_threshold: 4.5
  ovrl_threshold: 4.0
  reverb_threshold: 3.5
  disc_threshold: 4.0
speaker_separation:
  enable: true
```

### Permissive Web-Crawl Curation

Looser thresholds; preserve more data; rely on downstream training to filter further:

```yaml
mono_conversion:
  output_sample_rate: 16000   # narrow-band acceptable
  strict_sample_rate: false   # auto-resample
vad:
  enable: true
  threshold: 0.4              # lenient
band_filter:
  enable: false               # accept any bandwidth
utmos:
  enable: true
  mos_threshold: 3.0
sigmos:
  enable: true
  noise_threshold: 3.5
  ovrl_threshold: 3.0
speaker_separation:
  enable: true
```

### ASR Training (Single-Speaker Read Speech)

Skip speaker separation since each file is known to have one speaker:

```yaml
mono_conversion:
  output_sample_rate: 16000
vad:
  enable: true
  min_duration_sec: 2.0
band_filter:
  enable: true
  band_value: narrow_band     # match deployment
utmos:
  enable: true
  mos_threshold: 3.5
sigmos:
  enable: true
speaker_separation:
  enable: false               # skip — single speaker
```

## Complete Pipeline Example

A pipeline that uses `AudioDataFilterStage` as the entire processing chain:

```python
from nemo_curator.pipeline import Pipeline
from nemo_curator.backends.xenna import XennaExecutor
from nemo_curator.stages.audio.advanced_pipelines.audio_data_filter import AudioDataFilterStage
from nemo_curator.stages.audio.io.convert import AudioToDocumentStage
from nemo_curator.stages.text.io.writer import JsonlWriter

pipeline = Pipeline(name="audio_data_filter")

# Reads from a manifest and produces filtered AudioTask per speaker
pipeline.add_stage(AudioDataFilterStage(config_path="./audio_filter.yaml"))

# Export
pipeline.add_stage(AudioToDocumentStage())
pipeline.add_stage(JsonlWriter(path="./curated_audio"))

executor = XennaExecutor()
pipeline.run(executor)
```

For a complete end-to-end walkthrough including dataset download, see the [ReadSpeech Tutorial](/curate-audio/tutorials/readspeech).

## Best Practices

* **Start from the default config and tune one knob at a time**: don't tighten thresholds on five dimensions at once. You'll lose visibility into which one rejected each dropped segment.
* **Disable speaker separation when you can**: it's the most expensive sub-stage. If your input has known single-speaker audio, set `speaker_separation.enable: false` for a substantial speedup.
* **Match resources to hardware**: the `cpus` / `gpus` keys per sub-stage control parallelism. On a 16-CPU / 4-GPU node, the defaults work well; tune up for larger nodes.
* **Use `strict_sample_rate: false` only when needed**: auto-resampling can mask data-quality bugs (unexpected 8 kHz audio in a 48 kHz dataset). Default to strict and disable only when heterogeneity is expected.
* **Inspect distributions before tightening thresholds**: route a small sample through with most filters disabled to score the data, then pick thresholds from the percentile distributions.

## Related Topics

* **[Preprocessing Stages](/curate-audio/process-data/quality-filtering/preprocessing)** — `MonoConversionStage`, `SegmentConcatenationStage`, `TimestampMapperStage`.
* **[VAD](/curate-audio/process-data/quality-filtering/vad)**, **[Band Filter](/curate-audio/process-data/quality-filtering/band-filter)**, **[UTMOS](/curate-audio/process-data/quality-filtering/utmos)**, **[SIGMOS](/curate-audio/process-data/quality-filtering/sigmos)**, **[Speaker Separation](/curate-audio/process-data/quality-filtering/speaker-separation)** — per-stage details.
* **[ReadSpeech Tutorial](/curate-audio/tutorials/readspeech)** — end-to-end walkthrough.