# Creații audio (/ro/docs/gateway/audio-creatives)

Melodii și podcasturi ca creații editabile în codai Studio — o cronologie multipistă cu secțiuni, piste, clipuri, MIDI, efecte, magistrală master și versuri sincronizate, editată prin operații mici.

O **creație audio** (`kind: "audio"`) este o [creație](./creatives.mdx) al cărei document este o cronologie audio multipistă: o melodie sau un episod de podcast. Folosește același API ca orice altă creație — creare, citire, editare prin operații, versiuni, revenire, ramificare, verificare, partajare — și același document, cu cronologia în `doc.audio`. Crearea, citirea și editarea sunt **gratuite**; fișierele pe care le pui pe ea vin din [operațiile media](./media-ops.mdx), din generarea de muzică și voce sau din propriile încărcări.

```bash
curl https://ai.codai.ro/v1/studio/creatives \
  -H "Authorization: Bearer $CODAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "audio", "title": "Episodul 12" }'
```

## Modelul documentului [#modelul-documentului]

Un document audio are un singur format, `stereo` (mixaj la 48 kHz; pânza de 1920×1080 se folosește doar pentru o scenă opțională de copertă / vizualizare), cel mult **o** scenă (doar subtitrări) și un `fps` opțional. Tot ce contează stă în `doc.audio` (schema `CreativeAudio`):

| Câmp | Ce conține |
| --- | --- |
| `meta` | `bpm` (20–300), `key` (`{ tonic, mode }`), `timeSignature` (`[4, 4]`), `language`, `loudnessTarget`, `sampleRate` (44100 \| 48000) |
| `sections` | Părțile melodiei sau ale episodului: `{ id, kind, startMs, durationMs, label?, lyrics?, styleHint?, locked? }`; `kind` este `intro`, `verse`, `pre_chorus`, `chorus`, `bridge`, `outro`, `instrumental` sau `custom` |
| `tracks` | Cel mult 16: `{ id, role, kind?, name?, gainDb?, pan?, mute?, solo?, locked?, sends?, fx?, automation?, clips[], midiClips? }` |
| `master` | Magistrala master: `fx`, `targetLufs`, `truePeakDb`, `limiter` |
| `lyrics` | Linii sincronizate `{ startMs, endMs, text, sectionId? }` (gata pentru LRC) |
| `humanLog` | Cine ce a făcut: `{ op, actor: human \| ai, ts, detail? }`, adăugat de server la fiecare editare |

Milisecundele sunt sursa de adevăr; măsurile și timpii se deduc din `meta.bpm` și `meta.timeSignature`.

**Piste.** `role` este unul dintre `voice`, `music`, `sfx`, `drums`, `bass`, `keys`, `guitar`, `vocal`, `lead`, `pad`, `fx`, `bus`, `podcast_host`, `podcast_guest`. `kind` este `audio` (implicit), `midi` (conține doar `midiClips`) sau `bus` (fără clipuri; celelalte piste ajung la ea prin `sends`). `fx` este un lanț de cel mult 16 efecte (`eq`, `compressor`, `reverb`, `delay`, `limiter`, `gate`, `deesser`, `pitch`, `chorus`, `saturation`) cu `params` numerici și `bypass`; anvelopele din `automation` țintesc `gainDb`, `pan` sau `fx.<fxId>.<param>`.

**Clipuri.** `{ id, assetId, startMs, inMs?, outMs?, gainDb?, pan?, fadeInMs?, fadeOutMs?, fadeCurve?, stretch?, pitchSemitones?, loop?, duck?, color?, generation?, locked? }`. `inMs` / `outMs` sunt decalaje în asset-ul **sursă**: un clip se termină pe cronologie la `startMs + (outMs − inMs) × stretch`. `fadeCurve` este `linear`, `exp` sau `s`; `stretch` (0,25–4) păstrează tonalitatea; `generation` reține cum a fost generat un clip (furnizorul și modelul public codai, promptul, seed-ul, clipul părinte, operația).

**Atenuare automată.** Pistele de muzică ale unei creații audio își coboară automat volumul sub clipurile `voice`, `vocal`, `podcast_host` și `podcast_guest` (atac 150 ms, eliberare 400 ms, 12 dB); orice clip poate activa sau dezactiva asta prin `duck`.

## Editarea prin operații [#editarea-prin-operații]

Creațiile audio acceptă toate operațiile comune (`setMeta`, `setAsset`, `setAudioClip`, `removeAudioClip`, `setLocale`…) plus 16 operații audio, trimise la `POST /v1/studio/creatives/{id}/ops` ca orice altă editare:

| Operație | Formă |
| --- | --- |
| Secțiuni | `addSection { section }`, `updateSection { target, patch }`, `removeSection { target }`, `moveSection { target, startMs }` |
| Piste | `addTrack { track, index? }`, `updateTrack { target, patch }`, `removeTrack { target }` |
| Clipuri | `splitClip { clipId, atMs, newId }`, `trimClip { clipId, startMs?, endMs? }`, `moveClip { clipId, startMs?, trackId? }`, `setFades { clipId, fadeInMs?, fadeOutMs?, fadeCurve? }` |
| MIDI | `addMidiClip { trackId, clip }`, `removeMidiClip { clipId }`, `updateMidiNotes { clipId, update?, remove?, add?, replace? }` |
| Master și versuri | `setMaster { master }`, `setLyrics { lines }` |

`setMeta` acceptă și `audio` (un patch al lui `meta`), iar `setAudioClip` un `trackId`. În orice patch, `null` șterge un câmp opțional, așa că fiecare editare are un invers exact și poate fi anulată.

```json
{
  "base_seq": 4,
  "ops": [
    { "op": "addSection", "section": { "id": "chorus1", "kind": "chorus", "startMs": 32000, "durationMs": 16000 } },
    { "op": "setFades", "clipId": "c7", "fadeInMs": 500, "fadeCurve": "s" },
    { "op": "setMaster", "master": { "targetLufs": -14, "truePeakDb": -1, "limiter": true } }
  ]
}
```

## Ținte de mastering [#ținte-de-mastering]

`meta.loudnessTarget` primește un preset sau un număr de LUFS integrați (−40…−5):

| Preset | LUFS | Utilizare |
| --- | --- | --- |
| `streaming` | −14 | Spotify, Apple Music, YouTube (implicit când nu e setat nimic) |
| `podcast` | −16 | Platforme de podcast |
| `broadcast` | −23 | Radio și TV EBU R128 |

`master.targetLufs` are prioritate față de preset; vârful real implicit este −1 dBTP. Pentru masteringul unui fișier de mixaj rulează [`audio.master`](./media-ops.mdx) cu `target_lufs` −14, −16 sau −23.

## Verificare [#verificare]

[Verificarea](./creatives.mdx) adaugă cinci reguli audio: `clipping_risk` (câștigul însumat al clipurilor peste 0 dB), `missing_lyrics` (o strofă / pre-refren / refren / punte fără versuri când melodia are o pistă vocală), `missing_loudness_target`, `audio_overlap` (clipuri suprapuse pe aceeași pistă) și `audio_out_of_range` (un clip sau o notă în afara sursei ori a cronologiei).

## Operații media pentru audio [#operații-media-pentru-audio]

Piesele de bază ale unei melodii sau ale unui episod vin din [operațiile media](./media-ops.mdx): `music.generate_ace`, `music.repaint`, `music.extend` și `music.cover` pentru melodii, `sfx.generate` pentru efecte, `audio.separate_stems` ca să împarți un mix în piste de voce / tobe / bas / restul, `audio.denoise` ca să cureți o voce, `audio.to_midi` ca să transformi o melodie într-un clip MIDI, `audio.analyze` ca să citești BPM-ul, tonalitatea și loudness-ul în `meta`, și `audio.master` pentru loudness-ul final. Fiecare rezultat este un asset nou pe care îl pui pe o pistă cu `setAudioClip`; proveniența lui (`parent_asset_id`, `op`) rămâne pe asset.

## Randare și exporturi [#randare-și-exporturi]

`POST /v1/studio/creatives/{id}/render` pe o creație audio randează **mixajul**: fiecare pistă, clip, notă MIDI, efect, send și automatizare se mixează cu ffmpeg, se masterizează la ținta de loudness (loudnorm în două treceri + limitator de vârf real) și se exportă. Răspunsul e `202` cu id-ul randării; interoghezi `GET /v1/studio/renders/{id}` ca la orice randare.

| Câmp | Implicit | Ce face |
| --- | --- | --- |
| `formats` | `["wav", "mp3"]` | 1–3 dintre `wav` (24 de biți), `mp3` (320 kb/s), `flac`, fiecare un fișier separat |
| `stems` | `false` | Și câte un WAV pentru fiecare pistă audibilă (piste audio cu clipuri, piste MIDI cu note) |
| `lrc` | activ când documentul are versuri sincronizate | Un fișier LRC din `doc.audio.lyrics`; `true` fără versuri dă `400 no_lyrics` |
| `loudness` | `master.targetLufs` / `meta.loudnessTarget` al documentului, altfel −14 | `streaming` (−14), `podcast` (−16), `broadcast` (−23) sau LUFS (−40…−5) |
| `title` | titlul creației | Se salvează cu randarea |

```bash
curl https://ai.codai.ro/v1/studio/creatives/$ID/render \
  -H "Authorization: Bearer $CODAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: mix-12" \
  -d '{ "formats": ["wav", "mp3"], "stems": true, "loudness": "podcast" }'
```

Răspunsul 202 listează ieșirile planificate (`outputs`: `kind` `mix` / `stem` / `lrc`, `format`, `track_id`), `target_lufs` și `true_peak_db` rezolvate, `duration_seconds` și `quote_micro_usd`. După `succeeded`, `data[]` conține **câte un asset pe ieșire** (`url` semnat valabil o oră, `output`, `format`, `track_id`), iar `qa` valorile măsurate `lufs`, `true_peak_db` și `clipping`. Fiecare fișier poartă marcajul IA în interior (WAV RIFF ICMT, MP3 ID3v2.4, FLAC comentariu Vorbis), iar proveniența lui indică randarea.

**Preț**: 0,001 USD pe secundă de ieșire (0,06 USD pe minut), minimum 0,01 USD; `stems: true` adaugă 50 %. Oferta se rezervă în portofel înainte de pornire (`402 insufficient_funds` dacă nu ajunge), iar durata măsurată se facturează o singură dată. Cel mult 20 de minute pe randare (`400 too_long`); un document fără nimic audibil dă `400 empty_audio`; fiecare asset referit trebuie să fie al tău și gata (`400 asset_not_found`).

Versurile melodiei vin din [scriitorul de versuri](./lyrics-jam.mdx), iar sincronizarea karaoke din alinierea versurilor.

## SDK-uri [#sdk-uri]

TypeScript: `creatives.create({ kind: 'audio' })`, `creatives.edit(id, { baseSeq, ops })` (tipurile `CreativeAudio`, `CreativeOp`), `creatives.renderAudio(id, { formats, stems, lrc, loudness })` (tipurile `CreativeAudioRenderRequest`, `CreativeAudioRenderAccepted`, `StudioAudioRender`), plus `mediaOps` și `lyrics`. Python: `client.creatives.create(...)`, `client.creatives.edit(...)`, `client.creatives.render_audio(id, formats=, stems=, lrc=, loudness=)`, `client.media_ops` și `client.lyrics`.
