แท็กอารมณ์บน Paxa TTS Flash (v1)
แท็กอารมณ์คือคำในวงเล็บเหลี่ยมอย่าง [happy] หรือ [sad:0.5] ที่เขียนไว้ในข้อความของคำขอสร้างเสียงพูด รวมเสียงที่อ่านแท็กได้ รายการแท็ก น้ำหนัก ค่าบริการ และข้อผิดพลาด
หมายเหตุ
แท็กอารมณ์ใช้ได้เฉพาะบน Paxa TTS Flash (paxa-tts-flash-v1) ส่วนบน Paxa TTS Flash v2 ทุกเสียงอ่านคำกำกับที่เขียนเป็นภาษาธรรมชาติ เช่น [whispering] หรือ [อบอุ่น พูดช้า ๆ]
แท็กอารมณ์คือคำในวงเล็บเหลี่ยมที่เขียนไว้ใน text ของ POST /v1/tts เพื่อเปลี่ยนน้ำเสียงของข้อความที่ตามมา น้ำเสียงเปลี่ยนตรงแท็กและคงอยู่จนถึงแท็กถัดไป ข้อความก่อนแท็กแรกใช้น้ำเสียงเดิมของเสียงนั้น เสียงรุ่นทดลอง ขนมชั้น และ กะเพรา อ่านแท็กได้ ส่วนเสียงอื่นของ v1 ทุกเสียงจะข้ามแท็ก และทุกเสียงของ Paxa TTS Flash v2 อ่านแท็กคำกำกับแทน
curl -X POST https://api.paxalabs.com/v1/tts \
-H "Authorization: Bearer $PAXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "[happy] ได้ข่าวว่าสอบผ่านแล้ว ดีใจด้วยนะ [sad:0.6] แต่ต่อไปคงไม่ค่อยได้เจอกันแล้ว",
"voice": "khanomchan",
"model": "paxa-tts-flash-v1"
}' \
--output speech.mp3import { writeFile } from "node:fs/promises";
const response = await fetch("https://api.paxalabs.com/v1/tts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAXA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "[happy] ได้ข่าวว่าสอบผ่านแล้ว ดีใจด้วยนะ [sad:0.6] แต่ต่อไปคงไม่ค่อยได้เจอกันแล้ว",
voice: "khanomchan",
model: "paxa-tts-flash-v1",
}),
});
if (!response.ok) throw new Error(`TTS failed: ${response.status}`);
await writeFile("speech.mp3", Buffer.from(await response.arrayBuffer()));import os
import requests
response = requests.post(
"https://api.paxalabs.com/v1/tts",
headers={"Authorization": f"Bearer {os.environ['PAXA_API_KEY']}"},
json={"text": "[happy] ได้ข่าวว่าสอบผ่านแล้ว ดีใจด้วยนะ [sad:0.6] แต่ต่อไปคงไม่ค่อยได้เจอกันแล้ว", "voice": "khanomchan", "model": "paxa-tts-flash-v1"},
)
response.raise_for_status()
with open("speech.mp3", "wb") as f:
f.write(response.content)เสียงที่อ่านแท็กได้#
| เสียง | id | เพศ |
|---|---|---|
| ขนมชั้น | khanomchan | หญิง |
| กะเพรา | kaprao | ชาย |
GET /v1/voices แสดงแท็กที่แต่ละเสียงอ่านได้ในฟิลด์ emotion_tags ซึ่งว่างสำหรับเสียงที่ข้ามแท็ก และระบุเสียงเหล่านี้ด้วย experimental: true เสียงรุ่นทดลองใช้ไอดีเดิมตลอด ส่วนน้ำเสียงอาจเปลี่ยนระหว่างที่เราปรับจูน
รายการแท็ก#
เสียงด้านบนอ่านคำเหล่านี้ได้ โดยเขียนไว้หน้าข้อความที่ต้องการให้มีน้ำเสียงนั้น: [neutral], [calm], [normal], [plain], [happy], [excited], [cheerful], [joyful], [amazed], [laughing], [sad], [crying], [sorrowful], [gloomy], [disappointed], [angry], [shouting], [furious], [annoyed], [frustrated], [afraid], [scared], [fearful], [nervous], [terrified], [anxious]
วิธีอ่านแท็ก#
- ตัวพิมพ์เล็กหรือใหญ่ไม่มีผล และ
_กับ-อ่านเป็นช่องว่าง[Sad]และ[sad_]จึงเป็น[sad]เหมือนกัน - คำในวงเล็บที่ไม่อยู่ในรายการ เช่น
[laughs]ได้คำตอบ 400 tag_invalid - วงเล็บที่ไม่ได้มีคำอยู่ข้างใน เช่น
[1]หรือ[ไทย]เป็นข้อความและถูกอ่านออกเสียง คำนอกรายการที่ตามด้วยโคลอน เช่น[Fig:2]หรือ[note: see below]ก็เป็นข้อความเช่นกัน - ข้อความที่มีแต่แท็กได้คำตอบ 422 unspeakable_text โดยยังไม่คิดเครดิต
กำหนดน้ำหนัก#
น้ำหนักหลังโคลอนกำหนดว่าแท็กมีผลมากแค่ไหน ตั้งแต่ 0 ถึง 1 เช่น [sad:0.5] เขียนเป็นตัวเลขตั้งแต่ 0 ถึง 1 หรือเป็นเปอร์เซ็นต์ เช่น [sad:.25] [sad:0,5] หรือ [sad:50%] API อ่านละเอียดถึงหลักพัน และค่าที่เกินปลายด้านใดอ่านเป็นปลายด้านนั้น [angry:1.5] จึงเท่ากับ [angry] แท็กที่น้ำหนัก 0 ไม่มีผล น้ำหนักที่ไม่ใช่ตัวเลข เช่น [sad:half] ได้คำตอบ tag_invalid
ค่าบริการ#
แท็กคือข้อความ ทุกตัวอักษรของแท็กนับรวมในความยาวคำขอและค่าบริการ ตามอัตราต่อตัวอักษรของโมเดล ตัวอย่างด้านบนยาว 81 ตัวอักษรรวมแท็ก คิด 0.81 เครดิต เครดิตและการคิดค่าบริการ อธิบายการปัดเศษและค่าขั้นต่ำ
เสียงอื่น#
เสียงของ v1 ที่ไม่อ่านแท็กจะข้ามแท็กในรายการทุกคำ ไม่ว่าน้ำหนักเท่าไร แล้วอ่านข้อความที่เหลือ เสียงเหล่านี้ไม่ปฏิเสธคำขอ คำในวงเล็บที่ไม่อยู่ในรายการ เช่น [laughs] เป็นข้อความและถูกอ่านออกเสียง ตัวอักษรของแท็กที่ถูกข้ามยังนับรวมในค่าบริการ
แท็กบนการเชื่อมต่อสด#
บนการเชื่อมต่อสด เฟรม text ที่มีแท็กซึ่งเสียงอ่านไม่ได้จะได้อีเวนต์ error พร้อม tag_invalid และบัฟเฟอร์คงข้อความเดิมก่อนเฟรมนั้นไว้ การส่งอัตโนมัติจะเก็บแท็กที่ยังเปิดค้างอยู่ท้ายบัฟเฟอร์ไว้ก่อน แท็กที่ถูกแบ่งข้ามเฟรมจึงถูกอ่านครบทั้งคำ ส่วนแท็กที่เปิดค้างเกินเกณฑ์ความยาวที่ใช้ส่งข้อความทั่วไปจะถูกอ่านเป็นข้อความ โดยไม่ถูกตรวจสอบในฐานะแท็ก แท็กที่ยังไม่มีคำตามมาจะรอคำเหล่านั้นอยู่ในบัฟเฟอร์ การสังเคราะห์แต่ละช่วงเริ่มด้วยน้ำเสียงที่ช่วงก่อนหน้าจบไว้ แท็กที่ยกมานี้ไม่คิดค่าบริการแต่นับรวมใน max_chars และใช้ได้ไม่เกินครึ่งหนึ่งของค่านี้ เฟรมที่ทำให้แท็กที่ยกมายาวเกินครึ่งหนึ่ง หรือทำให้แท็กที่รออยู่ในบัฟเฟอร์รวมกับแท็กที่ยกมาเกิน max_chars จะได้ text_too_long ส่วน cancel พาการเชื่อมต่อกลับสู่น้ำเสียงเดิมของเสียงนั้น
หมายเหตุ
ช่วงเวลาของไทม์สแตมป์ครอบคลุมข้อความที่ถูกพูด แท็กไม่มีช่วงเวลาของตัวเอง เอนด์พอยต์ที่เข้ากันได้กับ OpenAI อ่านแท็กใน input ตามกฎเดียวกัน