# 声音资源 (Voice Resources) API

声音资源 API 用于管理 TTS 语音合成的声音配置。

## 基础信息

| 项目 | 值 |
|------|-----|
| Base URL | `/api/v1/voices` |
| 认证方式 | Bearer Token (预留) |

---

## 数据模型

### Voice

```typescript
interface Voice {
  id: string;           // 声音ID
  user_id?: number;      // 所属用户ID (系统声音可为null)
  name: string;         // 声音名称
  vendor: string;       // 供应商: "Ali" | "Volcano" | "Minimax" | "硅基流动"
  gender: string;       // 性别: "Male" | "Female"
  language: string;     // 语言: "zh" | "en"
  description: string;  // 描述
  // 扩展参数 (voice_params)
  model?: string;        // 语音模型标识
  voice_key?: string;   // 厂商voice_key
  speed?: number;       // 默认语速 (0.5-2.0)
  gain?: number;        // 音量增益 (-10~10 dB)
  pitch?: number;       // 音调调整
  enabled: boolean;
  is_system: boolean;   // 是否系统预设
  created_at: string;
}
```

### VoiceParams

```typescript
interface VoiceParams {
  speed: number;       // 语速 0.5-2.0
  gain: number;        // 音量增益 -10~10 dB
  pitch: number;       // 音调调整
```

---

## API 端点

### 1. 获取声音列表

```http
GET /api/v1/voices
```

**Query Parameters:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| vendor | string | 否 | 过滤供应商 |
| gender | string | 否 | 过滤性别: "Male" \| "Female" |
| language | string | 否 | 过滤语言: "zh" \| "en" |
| is_system | boolean | 否 | 是否系统预设 |

**Response:**

```json
{
  "total": 15,
  "list": [
    {
      "id": "voice_001",
      "user_id": null,
      "name": "晓云",
      "vendor": "Ali",
      "gender": "Female",
      "language": "zh",
      "description": "温柔女声，适合客服场景",
      "model": "paimeng",
      "voice_key": "xiaoyun",
      "speed": 1.0,
      "gain": 0,
      "pitch": 0,
      "enabled": true,
      "is_system": true,
      "created_at": "2024-01-15T10:30:00Z"
    },
    {
      "id": "voice_002",
      "user_id": null,
      "name": "Kevin",
      "vendor": "Volcano",
      "gender": "Male",
      "language": "en",
      "description": "专业男声，适合商务场景",
      "model": "知心",
      "voice_key": "kevin_male",
      "speed": 1.0,
      "gain": 0,
      "enabled": true,
      "is_system": true
    },
    {
      "id": "voice_003",
      "user_id": 1,
      "name": "定制客服女声",
      "vendor": "Minimax",
      "gender": "Female",
      "language": "zh",
      "description": "定制的客服女声",
      "model": "abcs",
      "voice_key": "custom_voice_001",
      "speed": 1.1,
      "gain": 2,
      "enabled": true,
      "is_system": false
    }
  ]
}
```

---

### 2. 获取单个声音详情

```http
GET /api/v1/voices/{id}
```

**Response:**

```json
{
  "id": "voice_001",
  "user_id": null,
  "name": "晓云",
  "vendor": "Ali",
  "gender": "Female",
  "language": "zh",
  "description": "温柔女声，适合客服场景",
  "model": "paimeng",
  "voice_key": "xiaoyun",
  "speed": 1.0,
  "gain": 0,
  "pitch": 0,
  "enabled": true,
  "is_system": true,
  "created_at": "2024-01-15T10:30:00Z"
}
```

---

### 3. 创建声音配置

```http
POST /api/v1/voices
```

**Request Body:**

```json
{
  "name": "定制客服女声",
  "vendor": "Minimax",
  "gender": "Female",
  "language": "zh",
  "description": "定制的客服女声",
  "model": "abcs",
  "voice_key": "custom_voice_001",
  "speed": 1.1,
  "gain": 2,
  "pitch": 0,
  "enabled": true
}
```

**Fields 说明:**

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | string | 是 | 声音名称 |
| vendor | string | 是 | 供应商 |
| gender | string | 是 | 性别: "Male" \| "Female" |
| language | string | 是 | 语言: "zh" \| "en" |
| description | string | 否 | 描述信息 |
| model | string | 是 | 厂商语音模型标识 |
| voice_key | string | 是 | 厂商voice_key |
| speed | number | 否 | 默认语速 (0.5-2.0)，默认 1.0 |
| gain | number | 否 | 音量增益 (-10~10 dB)，默认 0 |
| pitch | number | 否 | 音调调整，默认 0 |
| enabled | boolean | 否 | 是否启用，默认 true |

---

### 4. 更新声音配置

```http
PUT /api/v1/voices/{id}
```

**Request Body:** (部分更新)

```json
{
  "name": "优化版客服女声",
  "speed": 1.15,
  "gain": 1
}
```

---

### 5. 删除声音配置

```http
DELETE /api/v1/voices/{id}
```

**注意:** 系统预设声音不可删除

---

### 6. 预览声音

```http
POST /api/v1/voices/{id}/preview
```

**Request Body:**

```json
{
  "text": "您好，请问有什么可以帮助您？",
  "speed": 1.0,
  "gain": 0
}
```

**Response:**

```json
{
  "success": true,
  "audio_url": "https://storage.example.com/preview/voice_001_preview.mp3",
  "duration_ms": 2500
}
```

---

### 7. 获取供应商声音列表

```http
GET /api/v1/voices/vendors/{vendor}/available
```

**Path Parameters:**

| 参数 | 类型 | 说明 |
|------|------|------|
| vendor | string | 供应商名称 |

**Response:**

```json
{
  "vendor": "Ali",
  "voices": [
    {
      "model": "paimeng",
      "voice_key": "xiaoyun",
      "name": "晓云",
      "gender": "Female",
      "language": "zh"
    },
    {
      "model": "paimeng",
      "voice_key": "guang",
      "name": "广志",
      "gender": "Male",
      "language": "zh"
    },
    {
      "model": "maimeng",
      "voice_key": "sijia",
      "name": "思佳",
      "gender": "Female",
      "language": "zh"
    }
  ]
}
```

---

## 推荐的 Schema 定义

```python
# ============ Voice ============
class VoiceGender(str, Enum):
    MALE = "Male"
    FEMALE = "Female"

class VoiceBase(BaseModel):
    name: str
    vendor: str
    gender: str
    language: str  # "zh" | "en"
    description: str = ""
    model: str
    voice_key: str
    speed: float = 1.0
    gain: int = 0
    pitch: int = 0
    enabled: bool = True

class VoiceCreate(VoiceBase):
    pass

class VoiceUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    speed: Optional[float] = None
    gain: Optional[int] = None
    pitch: Optional[int] = None
    enabled: Optional[bool] = None

class VoiceOut(VoiceBase):
    id: str
    user_id: Optional[int] = None
    is_system: bool = False
    created_at: datetime

    class Config:
        from_attributes = True

class VoicePreviewRequest(BaseModel):
    text: str
    speed: Optional[float] = None
    gain: Optional[int] = None
    pitch: Optional[int] = None

class VoicePreviewResponse(BaseModel):
    success: bool
    audio_url: Optional[str] = None
    duration_ms: Optional[int] = None
    error: Optional[str] = None
```

---

## 供应商声音示例

### 阿里云

| voice_key | name | gender | language | description |
|-----------|------|--------|----------|-------------|
| xiaoyun | 晓云 | Female | zh | 温柔女声 |
| guang | 广志 | Male | zh | 磁性男声 |
| sijia | 思佳 | Female | zh | 知性女声 |
| yunxiang | 云翔 | Male | zh | 活力男声 |

### 火山引擎

| voice_key | name | gender | language | description |
|-----------|------|--------|----------|-------------|
| doubao | 豆包 | Female | zh | 活泼女声 |
| kevin | Kevin | Male | en | 专业男声 |
| lucy | Lucy | Female | en | 甜美女声 |

### MiniMax

| voice_key | name | gender | language | description |
|-----------|------|--------|----------|-------------|
| abby | Abby | Female | en | 自然女声 |
| john | John | Male | en | 成熟男声 |
