# Audio processing, voice isolation & stems
> Isolate clean vocals from noise and music, separate songs into stems, or trim, loop, fade, normalize loudness, and convert audio.

Isolate clean speech or singing vocals from noisy recordings, split songs into
stems, or apply deterministic audio utilities — trimming, seamless looping,
fades, EBU R128 loudness normalization, and format conversion.

## Primary agent path

Use the Universal Skill with the MCP tool `beatra.audio.process`. One tool
covers all three capability families via the `operation` discriminator, and
every call returns an asynchronous billable task:

| `operation` | Capability | Model | Symmetrical REST endpoint |
| --- | --- | --- | --- |
| `isolate_voice` | `audio_voice_isolation` | `elevenlabs-audio-isolation` | `POST /v1/audio/isolation` |
| `separate_stems` | `audio_stem_separation` | `beatra-stems-v1` | `POST /v1/audio/stems` |
| `trim`, `loop`, `fade`, `normalize_loudness`, `convert_format` | `audio_process` | `beatra-audio-v1` | `POST /v1/audio/process` |

1. Upload local audio with `beatra.assets.upload` and pass its `artifact_id` as
   `source` (or `audio`, accepted interchangeably across MCP `beatra.audio.process`
   and REST; an `https_url` is also accepted). Tokens authorized with either
   `speech:generate` or `music:generate` can invoke `beatra.audio.process`.
2. Call `beatra.models.list` with the matching `capability` when limits,
   formats, or live prices matter.
3. Create one opaque `client_request_id`, submit once, and poll
   `beatra.tasks.get` until terminal.

## AI guide

AI integration guide: https://docs.beatra.ai/llms/audio-processing.md

## Voice isolation

`operation: "isolate_voice"` (`elevenlabs-audio-isolation`, REST
`POST /v1/audio/isolation`) extracts clean speech or singing vocals while
removing background music, room reverb, wind, traffic, and crowd noise. Use it
to clean noisy field recordings before
[voice clone](https://docs.beatra.ai/en/docs/capabilities/speech/voice-clone),
[speech to text](https://docs.beatra.ai/en/docs/capabilities/speech/speech-to-text), or
[speech to speech](https://docs.beatra.ai/en/docs/capabilities/speech/speech-to-speech).

```json
{
  "operation": "isolate_voice",
  "source": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "format": "wav",
  "client_request_id": "isolate-opaque-1"
}
```

- **Input limits**: duration must be **`4.6` seconds to `300.0` seconds (`5 minutes`)**,
  and file size at most `100 MB`. Clips shorter than `4.6` seconds or longer than
  `300.0` seconds are rejected before billing with `422 invalid_request`
  (`details.reason: "audio_too_short"` or `"audio_too_long"`, zero credit charge).
  Both MCP `beatra.audio.process` and REST `POST /v1/audio/isolation` accept either
  `source` or `audio` for the input media reference (and normalize the legacy model
  alias `"beatra-voice-isolate-v1"` to `"elevenlabs-audio-isolation"`).
- **Optional output formatting**: `isolate_voice` accepts only `format` (`"wav"`
  default, `"mp3"`, `"ogg"`, `"flac"`, `"m4a"`, or `"ulaw_8k_wav"`), `sample_rate`
  (`8000`, `16000`, `22050`, `24000`, `32000`, `44100`, `48000` Hz),
  `bitrate_kbps` (`64`, `128`, `192`, `256`, `320` for lossy `"mp3"`, `"ogg"`,
  `"m4a"`, with `"m4a"` up to `256`), and `channels` (`1` or `2`). Do not pass
  `fade_in_ms`, `fade_out_ms`, `loudness_lufs`, or `true_peak_db` on
  `isolate_voice` — apply those afterward with the deterministic audio utilities
  below.
- **Cost & output**: prepaid by **started input minute** at `721 credits` per
  started minute (`<= 60s` = `721 credits`, `5 min` = `3,605 credits`). Returns
  `outputs: [{"role": "voice", ...}]` containing pure isolated vocals without
  accompaniment stems.

## Stem separation

`operation: "separate_stems"` (`beatra-stems-v1`, REST `POST /v1/audio/stems`)
splits a mixed music track (up to `600` seconds / `10 minutes`, `<= 100 MB`)
into individual instrument and vocal stems.

```json
{
  "operation": "separate_stems",
  "source": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "mode": "two_stem",
  "client_request_id": "stems-opaque-1"
}
```

- `mode: "two_stem"` (default, `180 credits` per task): returns `vocals` and
  `instrumental` (`outputs[].role`: `"vocals"`, `"instrumental"`).
- `mode: "multi_stem"` (`360 credits` per task): splits into 6 stems (`vocals`,
  `drums`, `bass`, `guitar`, `piano`, `other`, returned as `outputs[].role`:
  `"stem:vocals"`, `"stem:drums"`, `"stem:bass"`, `"stem:guitar"`, `"stem:piano"`,
  `"stem:other"`).
- Output format is determined by the stem separation model; `separate_stems` does
  not accept `format` or local finishing parameters.

## Deterministic audio utilities

`beatra-audio-v1` (REST `POST /v1/audio/process`) performs deterministic audio
post-processing on inputs up to `3,600` seconds (`60 minutes`, `<= 300 MB`) at
a flat **`60 credits` per task**:

- `trim`: cut a segment using `start_ms` (`>= 0`, default `0`) plus **exactly
  one** of `end_ms` (`> start_ms`) or `target_duration_ms`.
- `loop`: repeat the clip or a sub-range (`loop_start_ms` default `0`,
  `loop_end_ms`; loop window at least `4,000` ms) using **exactly one** of
  `target_duration_ms` (`1,000`–`3,600,000` ms) or `loop_count` (`2`–`100`),
  with `crossfade_ms` (`50`–`3,000` ms, default `500` ms) and `end_with_fade`
  (boolean, default `true`).
- `fade`: apply `fade_in_ms` and/or `fade_out_ms` (`0`–`30,000` ms, at least one
  provided) using `fade_curve` (`"tri"` default, `"exp"`, `"log"`, or `"qsin"`).
- `normalize_loudness`: two-pass EBU R128 loudness normalization to
  `loudness_lufs` (`-30.0` to `-9.0` LUFS, default `-14.0`) and `true_peak_db`
  (`-9.0` to `0.0` dBTP, default `-1.0`).
- `convert_format`: transcode or resample to `format` (required: `"mp3"`,
  `"wav"`, `"ogg"`, `"flac"`, `"m4a"`, or `"ulaw_8k_wav"` for 8 kHz mono
  telephony), with optional `sample_rate`, `bitrate_kbps`, and `channels` (`1`
  or `2`).
- Every deterministic operation above can also include optional finishing fields
  (`fade_in_ms`, `fade_out_ms`, `fade_curve`, `loudness_lufs`, `true_peak_db`,
  `format`, `sample_rate`, `bitrate_kbps`, `channels`) in the same task.

## Result

Every operation returns `"type": "audio_process"`, `"operation"`, and
`"outputs"` (`separate_stems` adds `"mode"`, and deterministic utilities add
`"metrics"` and `"steps"`). Each `outputs[]` item carries `role` (`"voice"` for
`isolate_voice`, `"vocals"` / `"instrumental"` for `two_stem`, `"stem:<kind>"`
for `multi_stem`, and `"main"` for deterministic utilities), `artifact_id`, CDN
`url`, `mime_type`, and `duration_seconds`; `"role": "main"` also includes
measured `loudness_lufs` and `true_peak_db`:

```json
{
  "type": "audio_process",
  "operation": "isolate_voice",
  "outputs": [
    {
      "role": "voice",
      "artifact_id": "artifact_01JZ...",
      "url": "https://cdn.beatra.ai/tenants/.../voice.wav",
      "mime_type": "audio/wav",
      "duration_seconds": 18.4
    }
  ]
}
```

## Task status and recovery

`queued` and `running` are not failures. Keep polling the same `task_id`; never
submit a replacement because work is still running. On a lost create response,
retry the identical arguments with the same `client_request_id`. If any input
changes, use a new ID. Failed tasks automatically refund the reserved credits.
Artifact URLs are CDN addresses — copy them to your own storage promptly.

## REST API

Direct protocol integrations may call `POST /v1/audio/isolation`,
`POST /v1/audio/stems`, or `POST /v1/audio/process` with a stable
`Idempotency-Key` header, plus the shared task endpoints. Follow the generated
[API reference](https://docs.beatra.ai/en/docs/api-reference). Skill + MCP is the recommended
integration; use REST for custom, non-agent applications.
