|
68 | 68 | #define STEAMAUDIO_PARAM_NEAR_FIELD 0x1028 |
69 | 69 | #define STEAMAUDIO_PARAM_NONLINEAR_WAVE 0x1029 |
70 | 70 | #define STEAMAUDIO_PARAM_RAW_SCENE 0x1030 |
| 71 | +#define STEAMAUDIO_PARAM_BATTLE_BLEED 0x1031 |
| 72 | +#define STEAMAUDIO_PARAM_VOICE_LOD 0x1032 |
71 | 73 |
|
72 | 74 | #define STEAMAUDIO_MAX_PROBES 64 |
73 | 75 | #define STEAMAUDIO_MAX_PROBE_QUERIES 8 |
|
78 | 80 | #define STEAMAUDIO_MAX_VOLUMETRIC_SOURCES 16 |
79 | 81 | #define STEAMAUDIO_MAX_PRIORITY_SOURCES 32 |
80 | 82 | #define STEAMAUDIO_MAX_ACTIVE_VOICES 16 |
| 83 | +#define STEAMAUDIO_MAX_LOD_SOURCES 256 |
81 | 84 |
|
82 | 85 | #define STEAMAUDIO_MAX_GRAPH_NODES 64 |
83 | 86 | #define STEAMAUDIO_MAX_GRAPH_EDGES_PER_NODE 8 |
@@ -138,7 +141,9 @@ enum steamaudio_step { |
138 | 141 | STEAMAUDIO_STEP_SOUND_BARRIER = 35, |
139 | 142 | STEAMAUDIO_STEP_NEAR_FIELD = 36, |
140 | 143 | STEAMAUDIO_STEP_NONLINEAR_WAVE = 37, |
141 | | - STEAMAUDIO_NUM_STEPS = 38, |
| 144 | + STEAMAUDIO_STEP_BATTLE_BLEED = 38, |
| 145 | + STEAMAUDIO_STEP_VOICE_LOD = 39, |
| 146 | + STEAMAUDIO_NUM_STEPS = 40, |
142 | 147 | }; |
143 | 148 |
|
144 | 149 | enum steamaudio_speaker_layout { |
@@ -406,30 +411,53 @@ struct __attribute__((packed)) steamaudio_compressed_metadata_packet { |
406 | 411 |
|
407 | 412 | /* Raw Autonomous Scene State Packet (Thin Host Shim -> Autonomous DSP) */ |
408 | 413 | #define STEAMAUDIO_RAW_SCENE_MAGIC 0x534D5441 /* 'SMTA' */ |
| 414 | +#define STEAMAUDIO_RAW_SCENE_VERSION 0x00010001 |
409 | 415 |
|
410 | | -struct __attribute__((packed)) raw_emitter_descriptor { |
| 416 | +struct __attribute__((packed, aligned(128))) raw_emitter_descriptor { |
411 | 417 | uint32_t source_id; |
| 418 | + uint32_t flags; |
412 | 419 | float pos[3]; |
413 | 420 | float velocity[3]; |
| 421 | + float ahead[3]; |
| 422 | + float up[3]; |
414 | 423 | float source_spl_db; |
415 | 424 | float directivity_weight; |
416 | | - uint32_t flags; |
| 425 | + float directivity_power; |
| 426 | + float min_distance; |
| 427 | + float max_distance; |
| 428 | + float volumetric_radius; |
| 429 | + float occlusion_factor; |
| 430 | + float transmission_low; |
| 431 | + float transmission_mid; |
| 432 | + float transmission_high; |
| 433 | + uint32_t reserved[8]; |
417 | 434 | }; |
418 | 435 |
|
419 | | -struct __attribute__((packed)) raw_scene_packet { |
| 436 | +struct __attribute__((packed, aligned(128))) raw_scene_packet { |
420 | 437 | uint32_t sync_word; |
| 438 | + uint32_t version; |
421 | 439 | uint32_t seq_id; |
422 | | - uint64_t pts; |
| 440 | + uint32_t num_emitters; |
| 441 | + uint32_t frame_index; |
| 442 | + uint32_t num_samples; |
| 443 | + uint32_t header_bytes; |
| 444 | + uint32_t emitter_stride; |
423 | 445 | float listener_pos[3]; |
424 | 446 | float listener_rotation[3][3]; |
425 | 447 | float listener_velocity[3]; |
426 | 448 | float ambient_temp_c; |
427 | 449 | float ambient_humidity; |
428 | 450 | float room_dimensions[3]; |
429 | | - uint32_t num_emitters; |
| 451 | + uint32_t flags; |
| 452 | + uint32_t pcm_offset; |
| 453 | + uint32_t pcm_bytes; |
| 454 | + uint32_t total_frame_bytes; |
430 | 455 | struct raw_emitter_descriptor emitters[]; |
431 | 456 | }; |
432 | 457 |
|
| 458 | +STATIC_ASSERT(sizeof(struct raw_emitter_descriptor) == 128, raw_emitter_descriptor_must_be_128_bytes); |
| 459 | +STATIC_ASSERT(sizeof(struct raw_scene_packet) == 128, raw_scene_packet_header_must_be_128_bytes); |
| 460 | + |
433 | 461 | /* Internal DSP Sub-Engine States */ |
434 | 462 | struct steamaudio_direct_state { |
435 | 463 | float coeffs[2][STEAMAUDIO_NUM_EQ_BANDS][5]; /* b0, b1, b2, a1, a2 */ |
@@ -1281,6 +1309,109 @@ struct dsp_nonlinear_wave_state { |
1281 | 1309 | uint32_t flags; |
1282 | 1310 | }; |
1283 | 1311 |
|
| 1312 | +/* Playback-to-Capture Loopback & Battle Bleed Mixer Structures */ |
| 1313 | +struct __attribute__((packed)) sof_steamaudio_battle_bleed_config { |
| 1314 | + uint32_t comp_type; /* STEAMAUDIO_PARAM_BATTLE_BLEED */ |
| 1315 | + float bleed_volume; /* 0.0 to 1.0 (default 0.15 = 15%) */ |
| 1316 | + float ducking_depth_db; /* Ducking attenuation in dB, e.g. 12.0 */ |
| 1317 | + float ducking_threshold_db; /* Voice detection threshold in dB, e.g. -30.0 */ |
| 1318 | + float attack_time_ms; /* Ducking attack time, e.g. 5.0 ms */ |
| 1319 | + float release_time_ms; /* Ducking release time, e.g. 150.0 ms */ |
| 1320 | + uint32_t sample_rate; /* Sample rate in Hz, e.g. 48000 */ |
| 1321 | + uint32_t flags; /* Bit 0: enabled, Bit 1: helmet acoustic filter */ |
| 1322 | + uint32_t reserved[24]; /* Pad to exact 128 bytes alignment */ |
| 1323 | +}; |
| 1324 | + |
| 1325 | +struct dsp_battle_bleed_biquad { |
| 1326 | + float b0, b1, b2; |
| 1327 | + float a1, a2; |
| 1328 | + float x1[STEAMAUDIO_MAX_SPEAKERS]; |
| 1329 | + float x2[STEAMAUDIO_MAX_SPEAKERS]; |
| 1330 | + float y1[STEAMAUDIO_MAX_SPEAKERS]; |
| 1331 | + float y2[STEAMAUDIO_MAX_SPEAKERS]; |
| 1332 | +}; |
| 1333 | + |
| 1334 | +struct dsp_battle_bleed_result { |
| 1335 | + float current_ducking_gain; |
| 1336 | + float current_ducking_db; |
| 1337 | + float mic_envelope_db; |
| 1338 | + uint32_t is_speaking; |
| 1339 | +}; |
| 1340 | + |
| 1341 | +struct dsp_battle_bleed_state { |
| 1342 | + struct sof_steamaudio_battle_bleed_config config; |
| 1343 | + struct dsp_battle_bleed_result result; |
| 1344 | + struct dsp_battle_bleed_biquad hp_filter; /* 150 Hz HPF */ |
| 1345 | + struct dsp_battle_bleed_biquad lp_filter; /* 4000 Hz LPF */ |
| 1346 | + float env_mic; |
| 1347 | + float duck_gain_current; |
| 1348 | + float alpha_attack; |
| 1349 | + float alpha_release; |
| 1350 | + float ducking_min_gain; |
| 1351 | + float ducking_threshold_lin; |
| 1352 | + uint32_t sample_rate; |
| 1353 | + bool enabled; |
| 1354 | + bool helmet_filter_enabled; |
| 1355 | +}; |
| 1356 | + |
| 1357 | +/* High Polyphony Voice Scaling & DSP 3-Tier Level-of-Detail (LOD) Structures */ |
| 1358 | +enum steamaudio_lod_tier { |
| 1359 | + STEAMAUDIO_LOD_TIER_CULLED = 0, |
| 1360 | + STEAMAUDIO_LOD_TIER_1 = 1, /* Near-Field: Full Binaural HRTF + Early Reflections + Air Absorption EQ */ |
| 1361 | + STEAMAUDIO_LOD_TIER_2 = 2, /* Mid-Field: 2nd-Order Ambisonics (HOA) Binning + Shared Reverb */ |
| 1362 | + STEAMAUDIO_LOD_TIER_3 = 3 /* Far-Field: Distance Gain + Diffuse Energy Field Accumulator */ |
| 1363 | +}; |
| 1364 | + |
| 1365 | +struct __attribute__((packed, aligned(128))) sof_steamaudio_voice_lod_config { |
| 1366 | + uint32_t comp_type; /* STEAMAUDIO_PARAM_VOICE_LOD */ |
| 1367 | + uint32_t enabled; /* 1 = active, 0 = bypass */ |
| 1368 | + uint32_t max_tier1_voices; /* Max Tier 1 HRTF voices (default: 32) */ |
| 1369 | + uint32_t max_tier2_voices; /* Max Tier 2 HOA voices (default: 64) */ |
| 1370 | + uint32_t max_tier3_voices; /* Max Tier 3 Diffuse voices (default: 160) */ |
| 1371 | + float tier1_distance_m; /* Distance threshold for Tier 1 (default: 15.0f) */ |
| 1372 | + float tier2_distance_m; /* Distance threshold for Tier 2 (default: 50.0f) */ |
| 1373 | + float hysteresis_m; /* Distance hysteresis band (default: 1.5f) */ |
| 1374 | + float occlusion_demote_db; /* Occlusion dB loss threshold to demote to Tier 2 (default: 12.0f) */ |
| 1375 | + uint32_t hoa_order; /* HOA order for Tier 2 (default: 2 -> 9 channels) */ |
| 1376 | + float crossfade_time_ms; /* Tier transition crossfade time in ms (default: 10.0f) */ |
| 1377 | + uint32_t reserved[21]; /* Exact 128-byte cacheline / DMA alignment */ |
| 1378 | +}; |
| 1379 | +STATIC_ASSERT(sizeof(struct sof_steamaudio_voice_lod_config) == 128, sof_steamaudio_voice_lod_config_must_be_128_bytes); |
| 1380 | + |
| 1381 | +struct dsp_voice_lod_source_state { |
| 1382 | + uint32_t source_id; |
| 1383 | + uint8_t current_tier; /* 1, 2, or 3 */ |
| 1384 | + uint8_t target_tier; /* 1, 2, or 3 */ |
| 1385 | + uint8_t previous_tier; /* 1, 2, or 3 */ |
| 1386 | + uint8_t active; /* 1 if active in current frame */ |
| 1387 | + float distance_m; /* Distance to listener in meters */ |
| 1388 | + float priority_score; /* Computed perceptual priority */ |
| 1389 | + float transition_gain; /* 0.0 to 1.0 crossfade progress */ |
| 1390 | + float attenuation; /* Distance + directivity attenuation */ |
| 1391 | +}; |
| 1392 | + |
| 1393 | +struct dsp_voice_lod_stats { |
| 1394 | + uint32_t total_active_emitters; |
| 1395 | + uint32_t tier1_voice_count; |
| 1396 | + uint32_t tier2_voice_count; |
| 1397 | + uint32_t tier3_voice_count; |
| 1398 | + uint32_t tier1_demotions; /* Sources demoted from Tier 1 due to budget */ |
| 1399 | + uint32_t tier2_demotions; /* Sources demoted from Tier 2 due to budget */ |
| 1400 | + float estimated_dsp_load_pct; |
| 1401 | + float peak_voice_priority; |
| 1402 | +}; |
| 1403 | + |
| 1404 | +struct dsp_voice_lod_state { |
| 1405 | + struct sof_steamaudio_voice_lod_config config; |
| 1406 | + struct dsp_voice_lod_stats stats; |
| 1407 | + struct dsp_voice_lod_source_state sources[STEAMAUDIO_MAX_LOD_SOURCES]; |
| 1408 | + float hoa_bed[STEAMAUDIO_MAX_HOA_CHANNELS][256]; |
| 1409 | + float diffuse_bed[2][256]; |
| 1410 | + uint32_t num_sources; |
| 1411 | + uint32_t sample_rate; |
| 1412 | + bool enabled; |
| 1413 | +}; |
| 1414 | + |
1284 | 1415 | /* Forward declare processing function pointer */ |
1285 | 1416 | struct steamaudio_comp_data; |
1286 | 1417 | typedef int (*steamaudio_func)(struct processing_module *mod, |
@@ -1333,6 +1464,8 @@ struct steamaudio_comp_data { |
1333 | 1464 | struct dsp_sound_barrier_state sound_barrier; |
1334 | 1465 | struct dsp_near_field_state near_field; |
1335 | 1466 | struct dsp_nonlinear_wave_state nonlinear_wave; |
| 1467 | + struct dsp_battle_bleed_state battle_bleed; |
| 1468 | + struct dsp_voice_lod_state voice_lod; |
1336 | 1469 |
|
1337 | 1470 | /* Autonomous DSP-Centric Engine & Hardware Cycle Governor State */ |
1338 | 1471 | uint32_t dsp_cycle_start; |
@@ -2196,6 +2329,33 @@ void steamaudio_dsp_derive_raw_scene(struct steamaudio_comp_data *cd, |
2196 | 2329 | const struct raw_scene_packet *scene); |
2197 | 2330 | void steamaudio_dsp_update_cycle_governor(struct steamaudio_comp_data *cd); |
2198 | 2331 |
|
| 2332 | +/* Playback-to-Capture Loopback & Battle Bleed Mixer API */ |
| 2333 | +void steamaudio_dsp_battle_bleed_init(struct dsp_battle_bleed_state *bbs, uint32_t sample_rate); |
| 2334 | +void steamaudio_dsp_battle_bleed_set_config(struct dsp_battle_bleed_state *bbs, |
| 2335 | + const struct sof_steamaudio_battle_bleed_config *cfg); |
| 2336 | +void steamaudio_dsp_battle_bleed_process(struct dsp_battle_bleed_state *bbs, |
| 2337 | + const float *in_playback, |
| 2338 | + const float *in_mic, |
| 2339 | + float *out_capture, |
| 2340 | + uint32_t frames, |
| 2341 | + uint32_t num_channels, |
| 2342 | + bool muted); |
| 2343 | + |
| 2344 | +/* High Polyphony Voice Scaling & DSP 3-Tier Level-of-Detail (LOD) API */ |
| 2345 | +void steamaudio_dsp_voice_lod_init(struct dsp_voice_lod_state *vls, uint32_t sample_rate); |
| 2346 | +void steamaudio_dsp_voice_lod_set_config(struct dsp_voice_lod_state *vls, |
| 2347 | + const struct sof_steamaudio_voice_lod_config *cfg); |
| 2348 | +void steamaudio_dsp_voice_lod_classify(struct dsp_voice_lod_state *vls, |
| 2349 | + const struct raw_scene_packet *scene, |
| 2350 | + uint8_t *out_tiers); |
| 2351 | +void steamaudio_dsp_voice_lod_process(struct steamaudio_comp_data *cd, |
| 2352 | + const struct raw_scene_packet *scene, |
| 2353 | + const float *in_pcm, |
| 2354 | + float *out_l, |
| 2355 | + float *out_r, |
| 2356 | + uint32_t frames, |
| 2357 | + bool muted); |
| 2358 | + |
2199 | 2359 | #endif /* __SOF_AUDIO_STEAMAUDIO_H__ */ |
2200 | 2360 |
|
2201 | 2361 |
|
0 commit comments