跳转至

AWE 自定义模块数据结构分析

源码路径:../source/dspc_xisnd/ 分析目标:awe_modXisndDemomInstance 及其依赖的所有 AWE 框架结构体 用途:作为前端数据模型重新设计的参考依据


一、整体架构概览

AudioWeaver (AWE) 框架采用 C 语言模拟面向对象,核心结构体嵌套关系如下:

awe_modXisndDemomInstance          ← 具体算法模块实例
  └── ModuleInstanceDescriptor     ← 所有模块的通用实例基类(32 bytes)
        └── ModInstanceDescriptor  ← 最基础的对象实例头(12 bytes)
              └── pModClassDescriptor → ModClassModule  ← 类描述符(vtable,40 bytes)
        └── pWires[] → WireInstance ← 输入/输出/临时 wire(每条 wire 独立描述音频流格式)
              └── m_pBoundPin → IOPinDescriptor  ← 绑定的硬件 I/O pin

内存堆内独立分配:
  ├── TuningBuffer   (80,000 words)  ← 在线调音缓冲区
  └── AlgoMem        (3,000,116 words) ← 算法全部工作内存
        └── adsp_v1_platform         ← 算法平台对象(布局在 AlgoMem 起始处)
              ├── ptr_FunTab → adsp_audio_vtbl_t  ← 算法 vtable
              └── ptr_Param  → HandlWrapper       ← 初始化参数包装
                    ├── mFmtInput  → MediaFmt     ← 输入流格式
                    └── mFmtOutput → MediaFmt     ← 输出流格式

二、awe_modXisndDemomInstance 结构体详解

2.1 头文件定义(include/ModXisndDemom.h,最新版本)

typedef struct _awe_modXisndDemomInstance {
    ModuleInstanceDescriptor instance;   // 基类,32 bytes
    INT32   enable;          // 算法使能标志
    UINT32  VehicleCfg;      // 车型配置
    UINT32  AlgoChanNum;     // 算法处理通道数
    UINT32  NumOutChan;      // 输出通道数
    UINT32  MemSize_Algo;    // 算法内存大小(单位: word)
    UINT32  MemSize_Arch;    // 架构内存大小(单位: word)
    UINT32  MemSize_Tune;    // 调音内存大小(单位: word)
    UINT32* TuningBuffer;    // 在线调音缓冲区指针
    UINT32* AlgoMem;         // 算法全量内存指针
} awe_modXisndDemomInstance;

output/release/customModule/include/ModXisndDemom.h 是旧版导出文件,字段名不同(xisndVehicleCfgxisndMemSize_algo 等)且缺少 AlgoChanNum/NumOutChan 两个字段。应以 include/ModXisndDemom.h 为准。

2.2 完整字段说明

序号 字段名 类型 属性 说明
0 enable INT32 公开 算法使能(0=关闭,1=开启)
1 VehicleCfg UINT32 公开 车型配置,通过 Param ID=0x16670006 传递
2 AlgoChanNum UINT32 公开 算法处理通道数,通过 Param ID=0x16670002 传递
3 NumOutChan UINT32 公开 输出通道数
4 MemSize_Algo UINT32 公开 算法核心内存需求,单位 word
5 MemSize_Arch UINT32 公开 架构/平台适配内存,单位 word
6 MemSize_Tune UINT32 公开 调音参数内存,单位 word
7 TuningBuffer UINT32* 私有 在线调音缓冲区,分配 80,000 words
8 AlgoMem UINT32* 私有 算法全量内存,分配 3,000,116 words

ClassModule_PackArgCounts(7, 2) → 7 个公开参数 + 2 个私有参数(指针),共 9 个字段。

2.3 变量掩码(MASK / OFFSET)

每个可 Set/Get 的字段都有对应的掩码,用于 awe_modXisndDemomSet(mask) 的 switch-case 选择:

#define MASK_XisndDemom_enable       0x00000100   // OFFSET: 0x08
#define MASK_XisndDemom_VehicleCfg   0x00000200   // OFFSET: 0x09
#define MASK_XisndDemom_AlgoChanNum  0x00000400   // OFFSET: 0x0A
#define MASK_XisndDemom_NumOutChan   0x00000800   // OFFSET: 0x0B
#define MASK_XisndDemom_MemSize_Algo 0x00001000   // OFFSET: 0x0C
#define MASK_XisndDemom_MemSize_Arch 0x00002000   // OFFSET: 0x0D
#define MASK_XisndDemom_MemSize_Tune 0x00004000   // OFFSET: 0x0E
#define MASK_XisndDemom_TuningBuffer 0x00008000   // OFFSET: 0x0F(在线调音读写)
#define MASK_XisndDemom_AlgoMem      0x00010000   // OFFSET: 0x10

#define SETALLMASK 0xFFFFFF00  // 触发全量初始化(模块构造后调用)

TuningBuffer 的 Set 比较特殊:通过缓冲区内容区分读写命令: - COMMAND_HEADER_WRITE = 0x44332211 → 写参数 - COMMAND_HEADER_READ = 0xAABBCCDD → 读参数

2.4 类 ID

#define CLASSID_XISNDDEMOM  (CLASS_ID_MODBASE + 60070)

三、ModuleInstanceDescriptor 通用基类(32 bytes)

所有 AWE 模块实例的第一个成员,称为"基类"(C 语言继承)。

typedef struct _ModuleInstanceDescriptor {
    ModInstanceDescriptor instanceDescriptor;  // 偏移 0,12 bytes
    struct _LayoutInstance *pOwner;             // 偏移 12,所属 Layout
    WireInstance **pWires;                      // 偏移 16,wire 数组指针
    void (*pProcessFunc)(void *pInstance);      // 偏移 20,当前处理函数
    UINT32 packedFlags;                         // 偏移 24,控制标志
    UINT32 profileTime;                         // 偏移 28,性能计数(cycles × 256)
} ModuleInstanceDescriptor;  // 32 bytes

packedFlags 位域布局

位范围 宏/含义 说明
[7:0] nInWires (via PackFlags) 输入 wire 数量(最多 255)
[15:8] nOutWires 输出 wire 数量(最多 255)
[23:16] nScratchWires 临时 wire 数量
[25:24] MODULE_ACTIVE_MASK 模块状态:00=Active, 01=Bypass, 10=Mute, 11=Inactive
[27] MODULE_GENERAL_DEFERRED_SET 延迟 Set 标志(在主线程中执行)
[31:28] MODULE_GENERAL_MASK 通用标志位(模块自定义)
// Wire 数量打包
#define ClassModule_PackFlags(nIn, nOut, nScratch) \
    ((((nScratch) & 0xff) << 16) | (((nOut) & 0xff) << 8) | ((nIn) & 0xff))

// 模块状态常量
#define MODULE_ACTIVE    0x00000000
#define MODULE_BYPASS    0x01000000
#define MODULE_MUTE      0x02000000
#define MODULE_INACTIVE  0x03000000

四、ModInstanceDescriptor 最基础对象头(12 bytes)

typedef struct _ModInstanceDescriptor {
    struct _ModInstanceDescriptor *pNextInstance;    // 偏移 0,链表指针(遍历所有模块实例)
    const ModClassModule *pModClassDescriptor;        // 偏移 4,指向类描述符(vtable)
    UINT32 nUniqueInstanceID;                         // 偏移 8,唯一实例 ID
} ModInstanceDescriptor;  // 12 bytes

nUniqueInstanceID 是每个模块实例在 AWE 中全局唯一的 ObjectID,上位机通过该 ID 定位并操作具体模块。


五、ModClassModule 类描述符(vtable,40 bytes)

typedef struct _ModClassModule {
    ModClassDescriptor modClassDescriptor;    // 偏移 0,8 bytes(含 Constructor + classID)
    void (*pProcessFunc)(void *pInstance);    // 偏移 8,实时处理函数
    void (*pBypassFunc)(void *pInstance);     // 偏移 12,Bypass 函数
    UINT32 (*pSet)(void *pInstance, UINT32 mask);  // 偏移 16,Set 参数函数
    UINT32 (*pGet)(void *pInstance, UINT32 mask);  // 偏移 20,Get 参数函数
    UINT32 nModuleVersion;                    // 偏移 24,模块版本号
    UINT32 nPackedParameters;                 // 偏移 28,打包的参数数量(公开|私有)
    UINT32 bitVectorFloat[2];                 // 偏移 32,浮点参数位向量(64位)
} ModClassModule;  // 40 bytes

本模块的函数表:

// awe_modXisndDemomClass 初始化
.Constructor  = awe_modXisndDemomConstructor
.pProcessFunc = awe_modXisndDemomProcess
.pBypassFunc  = awe_modXisndDemomBypass
.pSet         = awe_modXisndDemomSet
.pGet         = awe_modXisndDemomGet
.nPackedParameters = ClassModule_PackArgCounts(7, 2)  // = 0x00020007


六、WireInstance 音频信号线(Wire)

Wire 是连接两个模块 Pin 之间的音频数据流描述对象,包含完整的流格式信息。

typedef struct _WireInstance {
    InstanceDescriptor instanceDescriptor;   // 基础实例头
    Sample *buffer;                          // 采样缓冲区指针
    float sampleRate;                        // 采样率(Hz)
    UINT32 wireInfo1;                        // 打包的流格式信息 1
    UINT32 wireInfo2;                        // 打包的流格式信息 2
    UINT32 wireInfo3;                        // 打包的流格式信息 3
    IOPinDescriptor *m_pBoundPin;            // 绑定的硬件 pin(可为 NULL)
} WireInstance;

wireInfo1 位域

位范围 宏名 位宽 说明
[9:0] NUM_CHANNELS 10 通道数(0~1023)
[26:10] MAX_BLOCKSIZE 17 最大 block 大小(0~131071)
[27] IS_COMPLEX 1 是否为复数信号
[31:28] SAMPLE_SIZE_BYTES 4 每采样字节数(0~15)
#define INFO1_PROPS(channels, maxBlockSize, complex, nSizeBytes) \
    ((channels & 0x3FF) | ((maxBlockSize & 0x1FFFF) << 10) | \
     ((complex & 1) << 27) | ((nSizeBytes & 0xF) << 28))

wireInfo2 位域

位范围 宏名 位宽 说明
[16:0] BLOCK_SIZE 17 当前 block 大小(0~131071)
[22:17] DATA_TYPE 6 数据类型枚举(float32/fract32/int16 等)
#define INFO2_PROPS(blockSize, dataType) \
    ((blockSize & 0x1FFFF) | ((dataType & 0x3F) << 17))

wireInfo3 位域

位范围 宏名 位宽 说明
[9:0] NUM_ROWS 10 矩阵行数
[19:10] NUM_COLUMNS 10 矩阵列数
[20] IS_IPC 1 跨核 IPC 传输标志
[21] IS_PRIVATE 1 私有 wire(不可被外部模块访问)
[22] IS_CLOCK_MASTER 1 是否为时钟主源

Wire 读取便利宏

ClassWire_GetChannelCount(W)   // 通道数
ClassWire_GetBlockSize(W)      // 当前 block 大小
ClassWire_GetMaxBlockSize(W)   // 最大 block 大小
ClassWire_GetDataType(W)       // 数据类型
ClassWire_GetSampleRate(W)     // 采样率(float)
ClassWire_GetNumSamples(W)     // 总采样数 = blockSize × channels
ClassWire_GetComplex(W)        // 是否复数
ClassWire_GetNSampleSize(W)    // 每采样字节数
ClassWire_GetIPC(W)            // IPC 标志
ClassWire_GetPrivate(W)        // 私有标志
ClassWire_GetClockMaster(W)    // 时钟主源标志

七、IOPinDescriptor 硬件 I/O Pin

Pin 是硬件输入/输出端口的描述,Wire 绑定到 Pin 后才能与实际硬件交互。

字段 偏移 说明
instanceDescriptor 0 基础实例头(12 bytes)
pOrigBuffer 12 Wire 分配的原始采样缓冲区
pSecondBuffer 16 双缓冲第二缓冲区
sampleRate 20 采样率(float)
wireInfo1 24 同 Wire 格式(通道/maxBlockSize/复数/采样宽)
wireInfo2 28 同 Wire 格式(blockSize/dataType)
wireInfo3 32 同 Wire 格式(rows/cols/IPC/private/clockMaster)
ctrlFlags 36 双缓冲控制标志
nBoundWires 40 绑定的 wire 数量
boundWires[1] 44 绑定 wire 数组(CoreWireDescr)
m_pinName[2] 52 Pin 名称(64位,ASCII 编码)
tmpCtrlFlags 60 临时控制标志
m_pin_flags 64 PIN_PUMP_MASK_FIRST / PIN_EXPORT_ONCE

八、算法平台封装结构体

这是 xisnd 算法层自定义的 C++ 风格封装(通过 C 实现),存放在 AlgoMem 堆内存中。

adsp_v1_platform(8 bytes)

struct adsp_v1_platform {
    const adsp_audio_vtbl_t* ptr_FunTab;   // 算法函数表指针
    HandlWrapper* ptr_Param;               // 初始化/运行参数
};

adsp_audio_vtbl_t(16 bytes,算法 vtable)

struct adsp_audio_vtbl_t {
    adi_adsp_err_t (*end)       (adsp_v1_platform*, ...);          // 销毁/关闭
    adi_adsp_err_t (*process)   (adsp_v1_platform*, pIn[], pOut[]);// 实时处理
    adi_adsp_err_t (*set_param) (adsp_v1_platform*, param_id, buf);// 设置参数
    adi_adsp_err_t (*get_param) (adsp_v1_platform*, param_id, buf);// 获取参数
};

HandlWrapper(44 bytes + 2×MediaFmt 指针)

typedef struct HandlWrapper_ {
    unsigned int vehicleCfg;   // 车型配置(来自 S->VehicleCfg)
    unsigned int enable;       // 使能(来自 S->enable)
    unsigned int AlgoChanNum;  // 算法通道数(来自 S->AlgoChanNum)
    unsigned int AlgoMemSize;  // 总算法内存 = MemSize_Algo + MemSize_Arch
    unsigned int TunMemSize;   // 调音内存(来自 S->MemSize_Tune)
    unsigned int POTMemSize;   // POT 内存大小
    MediaFmt* mFmtInput;       // 输入流格式
    MediaFmt* mFmtOutput;      // 输出流格式
    void* pAlgoMem;            // 算法核心内存指针
    void* pTunMem;             // 调音缓冲区指针(= S->TuningBuffer)
    void* pPOTMem;             // POT 内存指针
} HandlWrapper;

MediaFmt(28 bytes,音频流格式)

typedef struct MediaFmt_ {
    unsigned int num_port;         // 端口数(通常为 1)
    unsigned int num_chan;         // 通道数(来自 Wire)
    unsigned int is_interLeaved;   // 是否交织格式(1=交织)
    unsigned int fmt_stream;       // 流格式枚举(见 API_STREAM_FORMAT)
    unsigned int num_bytePerSmp;   // 每采样字节数(来自 Wire)
    unsigned int num_smpPerCh;     // 每通道采样数(= blockSize)
    float        smp_rate;         // 采样率(来自 Wire)
} MediaFmt;

API_STREAM_FORMAT 枚举:

含义
0 16 bits
1 24 bits
2 32 bits
3 32 bits with 27-factor scale
4 Float(float32)

九、内存布局分析

9.1 AlgoMem 内存布局(初始化时 Set mask=0xFFFFFFFF)

AlgoMem (UINT32*, 3,000,116 words = ~11.4 MB)
├── [0]    adsp_v1_platform          (8 bytes)
├── [2]    adsp_audio_vtbl_t         (16 bytes)
├── [6]    HandlWrapper              (44 bytes)
├── [17]   MediaFmt (Input)          (28 bytes)
├── [24]   MediaFmt (Output)         (28 bytes)
└── [31..] 算法核心内存 (pAlgoMem)   (MemSize_Algo + MemSize_Arch words)

9.2 TuningBuffer 内存布局(在线调音时 Set mask=MASK_TuningBuffer)

TuningBuffer (UINT32*, 80,000 words = ~312 KB)
├── [0]    isSet   COMMAND_HEADER_WRITE(0x44332211) 或 COMMAND_HEADER_READ(0xAABBCCDD)
├── [1]    pID     参数 ID
├── [2]    pSize   实际数据长度(read时返回实际读取长度)
└── [3..]  data    参数数据

9.3 关键 Param ID

Param ID 说明
0x16670001 HMI Enable
0x16670002 AlgoChanNum(算法通道数)
0x16670004 HMI Tuning(在线调音入口)
0x16670006 VehicleCfg(车型配置)

十、前端数据模型设计建议

基于以上分析,前端 TypeScript 模型应对应以下三个层次:

10.1 模块通用信息(对应 ModuleInstanceDescriptor

interface ModuleInstance {
  instanceId: string         // 对应 nUniqueInstanceID
  moduleTypeId: string       // 对应 classID (e.g. "xisnddemom_v1")
  state: 'active' | 'bypass' | 'mute' | 'inactive'  // 对应 packedFlags[25:24]
  inWireCount: number        // 对应 packedFlags[7:0]
  outWireCount: number       // 对应 packedFlags[15:8]
  profileTime?: number       // 对应 profileTime(cycles × 256)
}

10.2 Wire 信息(对应 WireInstance

interface WireInfo {
  sampleRate: number         // float
  channels: number           // wireInfo1[9:0]
  maxBlockSize: number       // wireInfo1[26:10]
  blockSize: number          // wireInfo2[16:0]
  dataType: WireDataType     // wireInfo2[22:17]
  isComplex: boolean         // wireInfo1[27]
  sampleSizeBytes: number    // wireInfo1[31:28]
  rows: number               // wireInfo3[9:0]
  cols: number               // wireInfo3[19:10]
  isIPC: boolean             // wireInfo3[20]
  isPrivate: boolean         // wireInfo3[21]
  isClockMaster: boolean     // wireInfo3[22]
}

type WireDataType = 'float32' | 'fract32' | 'int16' | 'int32' | 'int24'

10.3 模块专有参数(对应自定义字段,xisnd 示例)

interface XisndParams {
  // 公开参数(Build 配置阶段)
  enable: number             // 0 or 1
  vehicleCfg: number         // 车型配置值
  algoChanNum: number        // 算法通道数
  numOutChan: number         // 输出通道数
  memSizeAlgo: number        // 算法内存大小(words)
  memSizeArch: number        // 架构内存大小(words)
  memSizeTune: number        // 调音内存大小(words)
  // 私有参数(运行时,前端不直接修改)
  // tuningBuffer: 通过调音协议访问
  // algoMem: 运行时分配,前端只需知道大小
}

10.4 连接信息(对应 Wire 连接关系)

interface WireConnection {
  wireId: string             // wire 唯一 ID
  fromModule: string         // 源模块 instanceId
  fromPort: number           // 源模块输出 pin 索引
  toModule: string           // 目标模块 instanceId
  toPort: number             // 目标模块输入 pin 索引
  wireInfo: WireInfo         // wire 格式描述
}

10.5 链路(Layout)信息

interface LinkLayout {
  layoutId: string
  name: string
  global: {
    sampleRate: number
    blockSize: number
    dataType: WireDataType
  }
  modules: Record<string, ModuleInstance>
  wires: WireConnection[]
  // 各模块参数存储
  params: Record<string, Record<string, number | string>>
}

十一、字段名对照表(头文件 vs 前端建议命名)

注:旧版 output/release/customModule/include/ModXisndDemom.h 使用了不同的字段名(如 xisndVehicleCfg)。include/ModXisndDemom.h 为准。

头文件字段名(正确版) 前端建议字段名 说明
enable enable 算法使能
VehicleCfg vehicleCfg 车型配置
AlgoChanNum algoChanNum 算法通道数
NumOutChan numOutChan 输出通道数
MemSize_Algo memSizeAlgo 算法内存大小
MemSize_Arch memSizeArch 架构内存大小
MemSize_Tune memSizeTune 调音缓冲内存大小
TuningBuffer (透明处理) 在线调音通道,前端不直接操作
AlgoMem (透明处理) 算法内存,运行时分配

生成时间:2026-03-25