Versuri și jam live
Uneltele de compoziție din codai Studio — scrii versuri cu verificarea silabelor și a rimelor, le aliniezi la un clip vocal pentru sincronizare karaoke și LRC și cânți live cu muzică generată printr-un WebSocket.
Lângă creațiile audio stau trei unelte: un scriitor de versuri care verifică metrica și rima, alinierea versurilor care sincronizează rândurile cu un clip vocal și un jam live care transmite muzică generată pe care o dirijezi în timp real.
| Metodă | Cale | Rezultat | Facturare |
|---|---|---|---|
POST | /v1/studio/lyrics | Versuri cu raport de silabe și rime | Tokeni (codai::lyrics) |
POST | /v1/studio/lyrics/align | Rânduri sincronizate + LRC, aplicate ca setLyrics | Gratuit cu cuvinte din cache, altfel speech-to-text (codai::lyrics-align) |
WS | /v1/studio/jam | Audio PCM live dirijat prin prompturi | Pe minut început (codai::jam) |
Scrierea versurilor
curl https://ai.codai.ro/v1/studio/lyrics \
-H "Authorization: Bearer $CODAI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: song-7" \
-d '{
"brief": "o noapte de vară la mare, doi prieteni care se regăsesc",
"language": "ro",
"genre": "pop",
"structure": ["verse", "chorus", "verse", "chorus"],
"syllables_per_line": 8,
"rhyme_scheme": "AABB",
"lines_per_section": 4
}'| Câmp | Implicit | Observații |
|---|---|---|
brief | obligatoriu | 3–4000 de caractere; nu se jurnalizează niciodată |
language | obligatoriu | ro sau en; româna folosește diacriticele corecte (ș ț ă î â) |
genre, mood, title | — | Text liber (100 / 100 / 200 de caractere) |
structure | verse, chorus, verse, chorus, bridge, chorus | 1–12 dintre intro, verse, pre_chorus, chorus, bridge, outro, instrumental, custom |
syllables_per_line | — | 3–20; verificat cu o toleranță de ±1 |
rhyme_scheme | free | AABB, ABAB sau free |
lines_per_section | 4 | 2–8 |
Scriitorul rulează o singură tură codai limitată, cu un tool forțat, apoi verifică fiecare vers cu numărătorile proprii codai: silabe (regulile pentru română tratează diftongii, triftongii și hiatul; în engleză se numără grupurile de vocale după eliminarea unui -e / -es / -ed mut) și terminații de rimă (ultimul cuvânt de la vocala accentuată în română, de la ultimul grup de vocale în engleză, fără diacritice). Când peste 30 % din versuri nu se potrivesc — un număr de silabe în afara țintei ±1 sau un vers dintr-o pereche nerimată — o singură tură de reparare numește problemele și se întoarce cel mai bun dintre cele două răspunsuri (repaired: true când a câștigat reparația).
{
"object": "studio.lyrics",
"title": "Noapte de vară",
"language": "ro",
"rhyme_scheme": "AABB",
"syllables_per_line": 8,
"sections": [
{
"kind": "verse",
"lines": [
{ "text": "Marea cântă lin sub lună", "syllables": 8, "rhyme": "una", "letter": "A", "off": false },
{ "text": "Ne-am regăsit iar împreună", "syllables": 8, "rhyme": "una", "letter": "A", "off": false }
]
}
],
"text": "[verse]\nMarea cântă lin sub lună\nNe-am regăsit iar împreună",
"report": { "lines": 16, "off_lines": 1, "off_ratio": 0.063, "pairs": 8, "rhymed": 7, "repair_ratio": 0.125 },
"repaired": false,
"cost_micro_usd": "4210"
}text este tot cântecul, cu un antet [kind] pe secțiune — îl trimiți ca lyrics_text la aliniere sau ca parametrul lyrics al music.generate_ace.
Facturare. Turele se taxează după tokeni sub modelul public codai (model de utilizare codai::lyrics, prompt caching activ). Mai întâi se rezervă în portofel o sumă mică, 20 000 µUSD (402 insufficient_funds dacă nu încape), decontată apoi cu costul real în tokeni. Când modelul nu reușește deloc să producă versuri răspunsul este 422 no_lyrics și se taxează doar turele care au rulat.
Alinierea versurilor la un clip (karaoke)
Alinierea sincronizează versurile scrise cu un clip dintr-o creație audio (sau video) și le scrie în doc.audio.lyrics printr-o singură editare setLyrics:
curl https://ai.codai.ro/v1/studio/lyrics/align \
-H "Authorization: Bearer $CODAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"creative_id": "8a1c…",
"clip_id": "vox1",
"lyrics_text": "[verse]\nMarea cântă lin sub lună\nNe-am regăsit iar împreună",
"language": "ro"
}'| Câmp | Implicit | Observații |
|---|---|---|
creative_id, clip_id | obligatorii | Asset-ul clipului trebuie să fie un asset speech, music, video sau upload al tău, gata |
lyrics_text | obligatoriu | Cel mult 5000 de caractere; liniile antet [verse] / [chorus] încep secțiuni |
language | meta.language al documentului | Indiciu pentru transcriere, ro sau en |
apply | true | false întoarce rândurile sincronizate și LRC-ul fără să editeze creația |
base_seq | versiunea curentă | Versiunea pe care se bazează editarea; o editare în conflict dă 409 stale |
retranscribe | false | Ignoră cuvintele din cache și transcrie din nou (taxat) |
Gateway-ul ia marcajele de timp ale cuvintelor din asset-ul clipului — din cache-ul pe care subtitrările și alinierile anterioare îl lasă pe asset (gratuit, cached: true) sau dintr-o transcriere Whisper nouă a clipului (cel mult 25 MB) —, le mută pe cronologie ținând cont de tăierea, poziția și întinderea clipului și potrivește cuvintele versurilor cu cele transcrise printr-o aliniere tolerantă la diacritice și greșeli de tipar. Rândurile ale căror cuvinte nu s-au auzit se interpolează între vecini. Răspunsul:
{
"object": "studio.lyrics_alignment",
"creative_id": "8a1c…",
"clip_id": "vox1",
"applied": true,
"seq": 12,
"doc_hash": "…",
"lines": [{ "startMs": 12040, "endMs": 14880, "text": "Marea cântă lin sub lună", "sectionId": "verse1" }],
"lrc": "[ti:Noapte de vară]\n[00:12.04]Marea cântă lin sub lună\n…",
"match_ratio": 0.94,
"cached": false,
"cost_micro_usd": "18000"
}match_ratio este proporția cuvintelor din versuri potrivite cu un cuvânt auzit; sub aproximativ 0,6 sincronizarea e mai mult interpolată — verifică clipul și limba. LRC-ul se exportă și la randarea audio (lrc: true).
Facturare. Cuvintele din cache sunt gratuite. O transcriere nouă se taxează codai::lyrics-align la tariful speech-to-text — 6 000 µUSD pe minut început din clip — sub o rezervare în portofel. Alinierea are nevoie de un serviciu de transcriere din afara UE și nu e disponibilă pentru conturile cu rezidența datelor în UE (403 residency_unavailable); când transcrierea nu e configurată, răspunsul este 503 transcription_unavailable.
Jam live (WebSocket)
wss://ai.codai.ro/v1/studio/jam deschide o sesiune muzicală live pe Lyria RealTime: trimiți prompturi text ponderate și câteva controale muzicale, iar gateway-ul transmite înapoi audio generat continuu. OpenAPI nu poate descrie WebSockets, așa că protocolul e documentat aici.
Conectarea
| Client | Cum te autentifici |
|---|---|
| Runtime de server | Authorization: Bearer <cheie API sau token efemer> la upgrade |
| Browser | Subprotocoalele codai-jam și bearer.<token efemer>; serverul răspunde cu codai-jam și nu repetă niciodată credențialul |
| Browser (alternativ) | ?key=<token efemer> — o cheie de durată brută în query string e refuzată cu închiderea 4401 |
Tokenii efemeri se emit cu POST /v1/tokens (scope realtime sau live). ?session_id= se înregistrează pe rândul de utilizare.
Client → gateway (cadre text JSON)
| Mesaj | Câmpuri |
|---|---|
{ "type": "prompts", "prompts": [{ "text", "weight" }] } | 1–8 prompturi; text de cel mult 200 de caractere; weight între −10 și 10, diferit de 0 (negativ îndepărtează) |
{ "type": "config", "bpm"?, "density"?, "brightness"?, "scale"? } | bpm 60–200, density și brightness 0–1, scale una dintre C_MAJOR_A_MINOR … B_MAJOR_A_FLAT_MINOR sau SCALE_UNSPECIFIED; actualizările parțiale se combină cu ultima configurație, iar o schimbare de bpm sau scale resetează contextul muzical |
{ "type": "play" }, pause, stop, reset | Controlul redării |
Mesajele trimise înainte ca upstream-ul să fie gata se pun în coadă. Orice altceva — JSON invalid, un tip necunoscut, un cadru binar — închide sesiunea cu 4400.
Gateway → client
- Cadre binare: PCM16 little-endian brut, stereo intercalat, 48 000 Hz. Audio-ul se aruncă (nu se pune în buffer) cât timp socket-ul tău rămâne în urmă cu peste 4 MB.
{ "type": "status", "state": "connecting" | "ready" | "playing" | "paused" | "stopped", "remaining_ms", "sample_rate"?, "channels"? }—readyvine cusample_rate: 48000șichannels: 2.{ "type": "filtered", "text", "reason" }— filtrul de siguranță al modelului a ignorat un prompt.{ "type": "error", "code", "message" }— trimis înaintea unui refuz sau a unei închideri din upstream.
Coduri de închidere
| Cod | Înseamnă |
|---|---|
4400 | Mesaj invalid de la client |
4401 | Credențiale lipsă sau invalide, ori o cheie brută în query string |
4402 | Rezervarea pentru 10 minute nu încape în portofel (insufficient_funds) |
4403 | Cont cu rezidența datelor în UE, model nepermis pentru cheie sau plafon de cheltuieli atins |
4408 | S-a atins limita de 10 minute a sesiunii (max_duration) |
4409 | Ai deja un jam live deschis (jam_busy) — unul pe cont |
4502 | Modelul muzical din upstream a eșuat sau s-a închis |
4503 | Jam-ul live nu e configurat pe acest gateway (jam_unavailable) |
Prețuri
0,03 USD pe minut început din sesiunea upstream deschisă (model de utilizare codai::jam, upstream lyria-realtime-exp). Prețul pentru 10 minute (0,30 USD) se rezervă la deschiderea sesiunii și se decontează la închidere cu minutele folosite efectiv; o sesiune care nu ajunge la upstream nu se taxează. Lyria RealTime e un model experimental, așa că prețul se poate schimba. Prompturile și audio-ul nu se jurnalizează niciodată.
SDK-uri
const song = await codai.lyrics.write({ brief: 'o noapte de vară', language: 'ro', rhyme_scheme: 'AABB' });
const aligned = await codai.lyrics.align({ creative_id: id, clip_id: 'vox1', lyrics_text: song.text });
const jam = codai.jam.connect({ token }); // browser: token efemer
jam.on('audio', (ev) => player.push(new Int16Array(ev.data)));
jam.on('close', (ev) => console.log('închis', ev.code));
jam.prompts([{ text: 'pian lo-fi cald', weight: 1 }]);
jam.config({ bpm: 90, density: 0.4 });
jam.play();song = client.lyrics.write("o noapte de vară", "ro", rhyme_scheme="AABB", syllables_per_line=8)
aligned = client.lyrics.align(creative_id, "vox1", song["text"])TypeScript: lyrics.write / align, jam.connect (JamSession: prompts, config, play, pause, stop, reset, close, on; JAM_CLOSE_CODES). Python: lyrics.write / align; SDK-ul Python nu are un helper WebSocket — folosește orice client WebSocket cu protocolul de mai sus.
Operații media
Operațiile media din codai Studio — elimini fundalul, mărești rezoluția, repictezi zone, separi pistele, reduci zgomotul, faci mastering, transformi audio în MIDI și generezi muzică sau efecte sonore din asset-urile tale.
Music Room
Music Room din codai Studio — o echipă de agenți cu roluri scrie, cântă și mixează o piesă care sună cântată de oameni, cu trei porți de aprobare, o cotă lunară în plan și o creație audio editabilă.