# 01 · 项目结构与文件说明

## 工程目录

```
joyinside_client_demo/
├── CMakeLists.txt              顶层 CMake：管理编译选项、三方库、最终可执行文件
├─ cmake/                      CMake 工具链与辅助脚本
│   ├── aarch64-debian-cross.cmake   交叉编译工具链文件（aarch64）
│   └── JoyinsideThreads.cmake       线程库检测辅助
├── conf/                    运行配置
│   └── joyinside.conf.example  配置文件示例（gflags 格式）
├── doc/                        说明文档
├── joyinside_ws_client/        JoyInside WebSocket 客户端封装（可复用组件）
├── scripts/                    辅助脚本
│   └── cross-build.sh          一键交叉编译脚本
├── src/                        主程序源码
│   ├── audiobook/              有声书子模块
│   └── *.cpp / *.h             核心业务代码
└── thirdparty/                 第三方依赖（源码级集成）
    ├── gflags/                 命令行参数解析
    ├── libwebsockets/          WebSocket 协议库
    ├── minimp3/                轻量 MP3 解码器
    ├── opus/                   Opus 音频编解码
    ├── spdlog/                 日志库
    ├── speexdsp/               音频重采样（SpeexDSP）
    └── yyjson/                 高性能 JSON 解析
```

## 1. 主程序源码 `src/`

| 文件 | 说明 |
| --- | --- |
| `main.cpp` | 程序入口：解析配置 → 初始化日志 → 构建 Config → 启动 Application → 信号处理 → 退出 |
| `app_config.h/cpp` | 基于 gflags 的配置层：自动加载 `joyinside.conf`、命令行覆盖、配置文件未填写时自动从环境变量读取凭证 |
| `application.h/cpp` | **核心业务**：单例管理 WS 生命周期、事件分发、下行解析（ASR/EVENT/TTS/有声书）、上行调度 |
| `event_loop.h/cpp` | 事件循环线程：状态机（Starting/Idle/Conversing）、重连退避、idle/transport 超时 |
| `audio_capturer.h/cpp` | 麦克风采集：ALSA PCM → 重采样 → 混音/增益 → 送入编码管线 |
| `audio_player.h/cpp` | 播放器：接收解码 PCM → 重采样 → ALSA 写出 |
| `opus_codec.h/cpp` | Opus 编解码封装 |
| `ws_sender.h/cpp` | 上行发送器：从编码队列取 Opus 帧 → WS 二进制发送 |
| `audio_pcm_dumper.h/cpp` | 调试辅助：将 PCM 导出为 WAV 文件 |
| `joyinside_log.h/cpp` | spdlog 日志初始化 |
| `stats_monitor.h/cpp` | 压测/稳定性统计：周期打印内存、线程 CPU |
| `thread_safe_queue.h` | 无锁线程安全队列模板 |
| `utils.h` | 通用工具 |

### 有声书子模块 `src/audiobook/`

| 文件 | 说明 |
| --- | --- |
| `audiobook_session.h/cpp` | 有声书会话状态机：PendingTts → TtsDraining → ReadyToStart → Playing → Stopped |
| `audiobook_downloader.h/cpp` | HTTP/HTTPS 流式下载器：支持 Range 断点续传、环形缓冲 |
| `audiobook_mp3_decoder.h/cpp` | MP3 解码器：minimp3 解码 → speexdsp 重采样 → PCM 帧队列 |

## 2. WebSocket 客户端 `joyinside_ws_client/`

JoyInside 协议层：

| 文件 | 说明 |
| --- | --- |
| `joyinside_ws_client.h/cpp` | WebSocket 客户端封装：连接、回调、二进制/文本发送、心跳、通道超时、`voiceChat/update` 配置同步 |
| `joyinside_auth.h/cpp` | Token 鉴权：`POST /auth/getToken`（HMAC-SHA256 + 时间戳）；设备注册 |
| `joyinside_http_utils.h/cpp` | HTTPS GET/POST 工具（基于 libcurl） |
| `joyinside_curl_share.h/cpp` | libcurl share handle 管理（DNS/TLS session 复用） |
| `joyinside_utils.h/cpp` | UUID 生成、时间戳格式化等 |

## 3. CMake 工具链 `cmake/`

| 文件 | 说明 |
| --- | --- |
| `aarch64-debian-cross.cmake` | 交叉编译工具链：自动检测 Rockchip SDK 或 apt 工具链、sysroot 校验（OpenSSL/ALSA/pthread/crt）、include/link 路径设置 |
| `JoyinsideThreads.cmake` | 跨平台线程库检测（`find_package(Threads)` 封装） |

## 4. 第三方依赖 `thirdparty/`

所有三方库以源码方式集成，通过 `add_subdirectory()` 编译为静态库：

| 库 | 版本 | 用途 |
| --- | --- | --- |
| libwebsockets | — | WebSocket 客户端协议实现（TLS 支持） |
| opus | — | 音频编解码（16 kHz / 60 ms 帧） |
| speexdsp | — | 音频重采样（48 kHz ↔ 16 kHz） |
| minimp3 | — | 有声书 MP3 解码（header-only） |
| spdlog | — | 日志输出 |
| yyjson | — | JSON 解析/生成 |
| gflags | — | 命令行/配置文件参数解析 |

**系统依赖**（不包含在 thirdparty 中，需目标板安装）：
- libcurl（HTTPS 请求）
- OpenSSL（TLS）
- ALSA（libasound，音频 I/O）

## 5. 配置文件 `conf/`

`joyinside.conf.example` 为完整配置模板，使用 gflags `--flagfile` 格式，涵盖：
- 凭证（bot_id / access_key_id / access_key_secret）
- 连接参数（ws_url / token_url）
- 音频参数（采样率、声道、硬件采样率、设备名）
- 采集增益 / 播放增益
- 日志级别 / PCM 导出开关
- 稳定性统计开关

## 6. 脚本 `scripts/`

| 文件 | 说明 |
| --- | --- |
| `cross-build.sh` | 一键交叉编译：自动检测 Rockchip SDK 工具链 / apt 工具链、校验 sysroot 完整性、配置 CMake、编译、可选 `deploy` 直接 scp 到目标板 |

## 7. 核心线程模型

| 线程 | 创建处 | 职责 |
| --- | --- | --- |
| main | `main.cpp` | 配置解析、启动 Application、信号等待 |
| event_loop | `event_loop.cpp` | 事件状态机：WS 建连/断线/重连调度 |
| lws_service | `joyinside_ws_client.cpp` | libwebsockets 事件循环：收发/心跳/超时 |
| audio_capture | `audio_capturer.cpp` | ALSA 采集 → 重采样 → 编码队列 |
| ws_sender | `ws_sender.cpp` | Opus 帧队列 → WS 二进制发送 |
| audio_player | `audio_player.cpp` | PCM 队列 → 重采样 → ALSA 播放 |
| audiobook_tick | `application.cpp` | 有声书定时轮询：管线信号、心跳、WS 断线处理 |
| stats_monitor | `stats_monitor.cpp` | （可选）周期资源统计打印 |