工作原理
面向二开:沿文件追踪数据流、控制流与输出边界。
音频路径
Apple Music 负责媒体访问与解码。Hook 接入其受支持的音频接口;解码结果以 float32 的 P0 表示进入 AMExclusive,再经队列与映射器生成设备所需的 PCM。
Apple Music decoder → P0 float32 → ApplePcmTap → PcmQueue
→ QueuedPcmSource / sample mapper → WasapiExclusiveSink → DAC核心文件与职责
| 源码文件 | 职责与修改入口 |
|---|---|
| mod/src/HookDll.cpp | Hook 安装和 Apple 音频调用入口;搜索 AudioConverterFillComplexBuffer 与 g_audioCoreRuntime。 |
| mod/src/ApplePrivateOffsets.h | 版本相关的私有偏移;适配应用版本时先核对此处与 Hook 安装条件。 |
| mod/src/audio_v2/AudioCoreRuntime.h | AudioCoreRuntime:连接 converter、原生音频图与协调器的运行时入口。 |
| mod/src/audio_v2/ApplePcmOutput.h | ApplePcmFormatView / ApplePcmOutputView:描述回调中的格式与缓冲区。 |
| mod/src/audio_v2/ApplePcmTap.h | ApplePcmTap::BindActive、OnInterleaved、OnPlanar:将指定 converter 的音频交给协调器。 |
| mod/src/audio_v2/AudioCoreCoordinator.h | Enable、PushP0Interleaved、PushP0Planar、OpenEndpoint、Start:队列与输出生命周期的组装层。 |
| mod/src/audio_v2/PcmQueue.h | PcmQueue::TryPush / TryPushPlanar:预分配 SPSC 队列;分块并规范化平面声道。 |
| mod/src/audio_v2/QueuedPcmSource.h | QueuedPcmSource / PcmMappingPolicy:消费音频块并选择整数源精确映射或本地浮点转换。 |
| mod/src/audio_v2/WasapiExclusiveSink.cpp | WasapiExclusiveSink::InitializeClient:格式探测、独占初始化;GetBuffer / ReleaseBuffer 是设备提交边界。 |
| mod/src/audio_v2/AudioCoreRuntime.cpp | AudioCoreRuntime 实现:格式候选、converter 观察、P0 接入和运行时协调。 |
| mod/src/audio_v2/AudioCoreConverterRegistry.h | ConverterRegistration 与有界 converter 登记;保存源精度、格式与代际信息。 |
数据格式与实时约束
PcmTypes.h 中 PcmFormat 区分采样率、声道数、有效位数和容器位数;PcmBlock 携带 mediaGeneration、sequence、firstFrame、discontinuity 与 endOfStream,不能只保留样本而丢掉这些边界信息。
当前定义支持双声道,每块最多 2048 帧。PcmQueue 使用 rigtorp/SPSCQueue;Apple 回调只负责有界入队,不应在此加入等待、文件 I/O 或额外分配。队列满与格式拒绝是失败路径,不是无限缓冲。
| 源码文件 | 职责与修改入口 |
|---|---|
| mod/src/audio_v2/PcmTypes.h | PcmFormat、PcmBlock、kSupportedChannels、kMaxBlockFrames。 |
WASAPI 输出
输出端通过 IsFormatSupported 检查设备格式,再以 AUDCLNT_SHAREMODE_EXCLUSIVE 和 EVENTCALLBACK 初始化。渲染线程等待设备事件,将 PCM 写入 WASAPI 缓冲区,绕过 Windows 共享混音器。
输出格式按音源采样率与整数 PCM 格式确定;设备或驱动必须支持该格式。硬件缓冲设置决定请求的缓冲时长。
- 验证不支持格式、设备占用、驱动拒绝、暂停/恢复、切歌、拖动进度及独占开关;须检查真实设备播放。
| 源码文件 | 职责与修改入口 |
|---|---|
| mod/src/audio_v2/WasapiExclusiveSink.cpp | InitializeClient:格式检查、独占初始化、设备事件与缓冲提交;修改缓冲或设备输出从此入手。 |
| mod/src/audio_v2/WasapiExclusiveSink.h | WasapiSinkConfig 与 WasapiExclusiveSink:输出配置和生命周期接口。 |
| mod/src/audio_v2/AudioCoreCoordinator.cpp | 协调 PCM 队列与输出启动/停止;修改输出交接时一起检查。 |
| mod/src/audio_v2/AudioCoreGate.h | AudioCoreGate:Off → Armed → Capturing → Prebuffered → Active/Faulted;代际 token 限制旧回调。 |
| mod/src/audio_v2/AppleOutputGate.h | AppleOutputGate::CommitCutover:替代输出启动成功后才抑制原生输出;退役时清除门控。 |
| mod/src/audio_v2/NativeRenderGateProxy.h | 原生 IAudioClient/IAudioRenderClient 代理声明和内部输出绕过守卫。 |
float32 与整数源映射
整数源解码后的 float32 样本必须仍落在原整数 PCM 格点上。ExactSampleMapper.h::MapP0Sample 检查有限值、范围与有效位数,将样本精确缩放到左对齐的 PCM32 容器;非整数结果或不合法填充位会被拒绝,而非四舍五入。
LocalFloatIntegerizer.h::IntegerizeLocalFloatSample 面向本地原生浮点音源,执行独立的量化/裁剪统计。不要为了兼容浮点音源放宽 ExactSampleMapper 的规则,否则会混淆两类输出承诺。
- 修改格式或样本处理时,同时检查 PcmTypes.h、QueuedPcmSource.h 和两个 mapper,不能只改 WASAPI 格式声明。
| 源码文件 | 职责与修改入口 |
|---|---|
| mod/src/audio_v2/ExactSampleMapper.h | MapP0Sample:整数源精确映射。 |
| mod/src/audio_v2/LocalFloatIntegerizer.h | IntegerizeLocalFloatSample:本地浮点转换。 |
| mod/src/AudioFormatPolicy.h | ApplePcmFormat 与格式判定:源格式解析、位深及本地 PCM 候选策略。 |
| mod/src/audio_v2/BitPerfectVerifier.h | BitPerfectVerifier:对照相同 P0 块的精确映射检查已提交整数样本,统计变化与映射失败。 |
| mod/src/AudioErrors.h | 项目自定义 HRESULT 与 IsPlaybackRejection;统一音频拒绝原因。 |
| mod/src/SampleConversion.h | 公开仓库中的空占位文件,无有效转换实现;样本转换应修改两个 mapper。 |
无损音质选择
音质选择与独占输出独立。策略保留当前曲目最高可用的无损采样率,带宽重新评估不能放行更低规格候选。最高规格尚未就绪时可能等待;只有有损版本的曲目无法因此变成无损。
- 修改后检查有无无损版本、最高规格未就绪与带宽降低时的选择结果;音质策略与独占输出开关保持独立。
| 源码文件 | 职责与修改入口 |
|---|---|
| mod/src/LosslessQualityPolicy.h | Selection::Observe / Accept:最高候选采样率的记录与接受条件。 |
| mod/src/LosslessQualityLock.cpp | 音质锁 Hook 接入与候选过滤;策略变化需同步检查调用方。 |
| mod/src/LosslessQualityLock.h | Install、SetEnabled、CreateStrictLosslessFilter:音质锁对调用方的接口。 |
控制流、UI 与音质策略
- 设置界面从 UiAdapter.cpp 入手;协议变更同时更新 IpcProtocol.h、Broker.cpp 与 HookDll.cpp。
| 源码文件 | 职责与修改入口 |
|---|---|
| mod/src/Broker.cpp | 伴生进程入口、目标 Apple Music 进程管理与配置协调。 |
| mod/src/UiAdapter.cpp | 独占开关和硬件缓冲控件;修改显示、输入校验或交互从此入手。 |
| mod/src/IpcProtocol.h | MessageType、Message 等通信契约;修改消息时同时检查两端。 |
| mod/src/IpcTransport.cpp | IPC 传输实现;与协议和调用方一起阅读。 |
| mod/src/LosslessQualityLock.cpp | 音质锁的 Hook 接入与候选过滤。 |
| mod/src/LosslessQualityPolicy.h | Selection::Observe / Accept:记录最高候选采样率并限制接受条件。 |
| mod/src/audio_v2/NativeRenderGateProxy.cpp | 原生渲染代理与输出交接;调整切换逻辑时必须连同协调器、生命周期门控一起检查。 |
| mod/src/IpcTransport.h | ReadMessage/WriteMessage 等传输接口与 PipeSecurity。 |
| mod/src/MediaSessionControl.cpp | Windows.Media.Control 会话控制与恢复日志;对应独立 media_control 工具。 |
| mod/src/BoundedLog.h | 有界日志与轮转辅助;供 Broker、Hook 和媒体控制使用。 |