CRI ADX  Last Updated: 2024-07-17 10:48 p
关于CriAtomDbas
CriAtomDbas是用于管理流缓冲区的模块。
用CRI Atom执行流播放时所需的流缓冲区由D-BAS集中管理。

创建D-BAS的基本方法

以下代码是使用预设设置创建D-BAS的示例代码。
CriAtomDbasConfig dbas_config;
CriSint32 dbas_wrok_size;
void* dbas_work;
CriAtomDbasId dbas_id;
dbas_wrok_size = criAtomDbas_CalculateWorkSize(&dbas_config);
dbas_work = malloc((size_t)dbas_wrok_size);
dbas_id = criAtomDbas_Create(&dbas_config, dbas_work, dbas_wrok_size);
CriSint32 CriAtomDbasId
Atom D-BAS ID
Definition: cri_le_atom.h:2513
CriAtomDbasId criAtomDbas_Create(const CriAtomDbasConfig *config, void *work, CriSint32 work_size)
Create D-BAS
#define criAtomDbas_SetDefaultConfig(p_config)
Set default parameters for CriAtomDbasConfig
Definition: cri_le_atom.h:427
CriSint32 criAtomDbas_CalculateWorkSize(const CriAtomDbasConfig *config)
Calculate work area size for creating D-BAS
D-BAS creation parameter structure
Definition: cri_le_atom.h:2527
 
如果创建D-BAS成功,则criAtomDbas_Create 函数返回有效的D-BAS ID。 如果创建D-BAS失败,则criAtomDbas_Create 函数返回::CRIATOMDBAS_ILLEGAL_ID 。

创建D-BAS的参数

D-BAS管理的流缓冲区大小根据创建D-BAS的参数而变化。 主要的创建参数是最大流数 CriAtomDbasConfig::max_streams 和最大比特率 CriAtomDbasConfig::max_bps 。 至于哪些参数对于流缓冲区有多大影响, 将根据参数的组合而变化。
大致标准是流缓冲区的大小与::CriAtomDbasConfigmax_streams 成正比, ::CriAtomDbasConfigmax_bps 越大,增加的速度就越快。
此外,即使尝试为max_bps设置超出设备读取性能的值,D-BAS的创建也将失败。 原因是当播放比特率超出设备读取性能的数据,流播放必然会中断。
以下是2个立体声48 kHz ADX数据、2个立体声48 kHz 高质量HCA数据,流播放合计4个数据时的设置。
CriSint32 adx_bps;
CriSint32 hca_bps;
CriAtomDbasConfig dbas_config;
CriSint32 dbas_wrok_size;
void* dbas_work;
CriAtomDbasId dbas_id;
/* 计算立体声 48 kHz ADX数据的比特率 */
adx_bps = criAtom_CalculateAdxBitrate(2, 48000);
/* 计算立体声 48 kHz 高质量 HCA数据的比特率 */
/* 流数量合计4个 */
dbas_config.max_streams = 4;
/* 设置2个立体声 48 kHz ADX数据、2个立体声 48 kHz 高质量HCA数据的总比特率 */
dbas_config.max_bps = adx_bps * 2 + hca_bps * 2;
dbas_wrok_size = criAtomDbas_CalculateWorkSize(&dbas_config);
dbas_work = malloc((size_t)dbas_wrok_size);
dbas_id = criAtomDbas_Create(&dbas_config, dbas_work, dbas_wrok_size);
CriSint32 criAtom_CalculateAdxBitrate(CriSint32 num_channels, CriSint32 sampling_rate)
Calculate bit rate of ADX data
CriSint32 criAtom_CalculateHcaBitrate(CriSint32 num_channels, CriSint32 sampling_rate, CriAtomEncodeQuality quality)
Calculate bit rate of HCA data
@ CRIATOM_ENCODE_QUALITY_HIGH
Definition: cri_le_atom.h:894
CriSint32 max_bps
Maximum bit rate
Definition: cri_le_atom.h:2558
CriSint32 max_streams
Maximum number of streaming
Definition: cri_le_atom.h:2545
 

调整创建D-BAS的参数

根据游戏场景不同,流的数量和播放比特率经常会随着场景而发生变化, 例如在某个场景中使用1个5.1ch 48 kHz 最高质量 HCA数据, 在其他场景中使用8个单声道 24 kHz 最高压缩 HCA数据等。
即使情况发生变化,D-BAS本身也始终管理创建D-BAS时分配的全体流缓冲区。 某些场景可能只需要减少流缓冲区, 但在另一个场景下则可能出现流缓冲区不足的情况。
为了能够在任何场景下都能够为D-BAS分配足够的流缓冲区, 应用程序必须为每个场景重新创建D-BAS, 或按照在任何场景下流缓冲区都足够用的标准来创建D-BAS。

为每个场景重新创建D-BAS

为每个场景重新创建D-BAS的方法比较简单。场景切换时 只需执行::criAtomDbas_Destroy函数 ,丢弃现有的D-BAS后, 使用::criAtomDbas_Create 函数重新创建新的D-BAS。
CriSint32 adx_bps;
CriSint32 hca_bps;
CriAtomDbasConfig dbas_config;
CriSint32 dbas_wrok_size;
void* dbas_work;
CriAtomDbasId dbas_id;
/* 计算立体声 48 kHz ADX数据的比特率 */
adx_bps = criAtom_CalculateAdxBitrate(2, 48000);
/* 计算立体声 48 kHz 高质量 HCA数据的比特率 */
/* 流数量合计4个 */
dbas_config.max_streams = 4;
/* 设置2个立体声 48 kHz ADX数据、2个立体声 48 kHz 高质量HCA数据的总比特率 */
dbas_config.max_bps = adx_bps * 2 + hca_bps * 2;
dbas_wrok_size = criAtomDbas_CalculateWorkSize(&dbas_config);
dbas_work = malloc((size_t)dbas_wrok_size);
dbas_id = criAtomDbas_Create(&dbas_config, dbas_work, dbas_wrok_size);
:
:
:
/* 场景转换 */
:
:
:
/* 丢弃现有的D-BAS */
/* 注意)正在流播放的声音,会因等待停止而被阻断 */
/* 更改参数并重新创建 */
/* 将流数量更改为总数2 */
dbas_config.max_streams = 2;
/* 全部为立体声 48 kHz 高质量 HCA数据 */
dbas_config.max_bps = hca_bps * 2;
dbas_wrok_size = criAtomDbas_CalculateWorkSize(&dbas_config);
dbas_work = malloc((size_t)dbas_wrok_size);
dbas_id = criAtomDbas_Create(&dbas_config, dbas_work, dbas_wrok_size);
void criAtomDbas_Destroy(CriAtomDbasId atom_dbas_id)
Destroy D-BAS
 
此方法可以将各场景的内存消耗降到最低, 但存在如下缺点:由于要删除D-BAS,无法在场景转换中播放流BGM。

创建支持所有场景的D-BAS

创建支持所有场景的D-BAS时,最简单的方法是针对各种流数量和播放比特率, 设置应用程序中的最差值。
例如、 场景A的流数量16个,播放比特率1mbps, 场景B的流数量4个,2mbps时,分别采用最大值创建D-BAS。
CriAtomDbasConfig dbas_config;
CriSint32 dbas_wrok_size;
void* dbas_work;
CriAtomDbasId dbas_id;
/* 设置场景A的流数量 */
dbas_config.max_streams = 16;
/* 设置场景B的播放比特率 */
dbas_config.max_bps = 2 * 1000 * 1000; /* 2 mbps */
dbas_wrok_size = criAtomDbas_CalculateWorkSize(&dbas_config);
dbas_work = malloc((size_t)dbas_wrok_size);
dbas_id = criAtomDbas_Create(&dbas_config, dbas_work, dbas_wrok_size);
 
CriAtomDbasConfig::max_streams 也是使用D-BAS的流播放数量的上限。 因此,当所有场景使用通用D-BAS时, 应当为::CriAtomDbasConfig::max_streams 设置所有场景中最大的流播放数量。

之后检查应当为D-BAS设置的参数

如果无法事先掌握整个应用程序执行什么样的流播放, 将无法正确设置创建D-BAS的参数。 但是,如果既要设置流数量又要设置播放比特率,则很难事先掌握。
因此可以采用如下方法:首先创建一个大的D-BAS, 再使用::criAtom_GetStreamingInfo 函数获取实际播放的流数量和播放比特率,确定D-BAS的创建参数。
criAtom_GetStreamingInfo 函数是获取调用瞬间的流数量和播放比特率的函数。 在应用程序运行期间,定期记录流数量和播放比特率, 记住组合并稍后将这些值反映到D-BAS,可以毫无浪费地准备流缓冲区。
CriAtomStreamingInfo streaming_info;
CriBool is_succeeded;
is_succeeded = criAtom_GetStreamingInfo(streaming_info);
if (is_succeeded == CRI_TRUE) {
/* 记住最大值 */
if (actual_max_streams < streaming_info.num_streaming) {
actual_max_streams = streaming_info.num_streaming;
}
/* 记住最大值 */
if (actual_max_bps < streaming_info.total_bps) {
actual_max_bps = streaming_info.total_bps;
}
}
:
:
:
/* 应用程序结束时的控制台输出 */
printf("Actual Max Streams:%d\n", actual_max_streams);
printf("Actual Max Bitrate:%d\n", actual_max_bps);
CriBool criAtom_GetStreamingInfo(CriAtomStreamingInfo *streaming_info)
Acquire streaming info
Streaming information
Definition: cri_le_atom.h:976
CriFloat32 total_bps
Current total streaming bit rate
Definition: cri_le_atom.h:992
CriSint32 num_streaming
Current number of streaming sounds
Definition: cri_le_atom.h:983
 

与Sofdec2(CRI Mana)的关系

在多重串流播放中,除音频数据外,还可能会播放视频数据。
在CRIWARE中,ADX负责播放音频数据,Sofdec2负责播放视频数据。
同时多重串流播放音频数据和视频数据时, 流的整体流量管理不会区分音频数据和视频数据。 因此同时使用Sofdec2时,需要将用于视频播放的流数量和播放比特率添加到::CriAtomDbasConfig::max_streams 、 CriAtomDbasConfig::max_bps
另一方面,D-BAS仅管理ADX使用的流缓冲区。 因为Sofdec2自己有流缓冲区, 所以即使在播放视频的情况下,也不会消耗D-BAS的流缓冲区。
所以,为避免D-BAS浪费视频流缓冲区, 为::max_mana_streams、::max_mana_bps 设置视频播放数量、视频的播放比特率。
以下是假定同时播放4个音频和1个视频场景下的D-BAS设置示例。
CriAtomDbasConfig dbas_config;
CriSint32 dbas_wrok_size;
void* dbas_work;
CriAtomDbasId dbas_id;
const CriSint32 atom_streams = 4; /* 4个音频流 */
const CriSint32 atom_bps = 320 * 1000; /* 320 kbps */
const CriSint32 mana_streams = 1; /* 1个视频流 */
const CriSint32 mana_bps = 15 * 1000 * 1000; /* 15 mbps */
/* 添加视频部分 */ dbas_config.max_streams = atom_streams + mana_streams;
dbas_config.max_bps = atom_bps + mana_bps;
/* 将视频量的流数量、比特率传递给D-BAS */ dbas_config.max_mana_streams = mana_streams;
dbas_config.max_mana_bps = mana_bps;
dbas_wrok_size = criAtomDbas_CalculateWorkSize(&dbas_config);
dbas_work = malloc((size_t)dbas_wrok_size);
dbas_id = criAtomDbas_Create(&dbas_config, dbas_work, dbas_wrok_size);
CriSint32 max_mana_streams
Maximum number of streams played back by CRI Mana
Definition: cri_le_atom.h:2567
CriSint32 max_mana_bps
Maximum bit rate for CRI Mana playback
Definition: cri_le_atom.h:2576