Add .cbx [Lego series (multi)]

This commit is contained in:
bnnm 2024-01-20 16:24:57 +01:00
parent 796e423615
commit f8f9239cf4
6 changed files with 92 additions and 37 deletions

View File

@ -44,23 +44,23 @@ static const uint8_t mask_table[8] = {
* note this table is mirrored: for (i = 1 .. 32) t[64 - i] = -t[i]) */
static const float utk_rc_table[64] = {
/* 6b index start */
+0.000000, -0.996776, -0.990327, -0.983879,
-0.977431, -0.970982, -0.964534, -0.958085,
-0.951637, -0.930754, -0.904960, -0.879167,
-0.853373, -0.827579, -0.801786, -0.775992,
+0.000000f, -0.996776f, -0.990327f, -0.983879f,
-0.977431f, -0.970982f, -0.964534f, -0.958085f,
-0.951637f, -0.930754f, -0.904960f, -0.879167f,
-0.853373f, -0.827579f, -0.801786f, -0.775992f,
/* 5b index start */
-0.750198, -0.724405, -0.698611, -0.670635,
-0.619048, -0.567460, -0.515873, -0.464286,
-0.412698, -0.361111, -0.309524, -0.257937,
-0.206349, -0.154762, -0.103175, -0.051587,
+0.000000, +0.051587, +0.103175, +0.154762,
+0.206349, +0.257937, +0.309524, +0.361111,
+0.412698, +0.464286, +0.515873, +0.567460,
+0.619048, +0.670635, +0.698611, +0.724405,
+0.750198, +0.775992, +0.801786, +0.827579,
+0.853373, +0.879167, +0.904960, +0.930754,
+0.951637, +0.958085, +0.964534, +0.970982,
+0.977431, +0.983879, +0.990327, +0.996776,
-0.750198f, -0.724405f, -0.698611f, -0.670635f,
-0.619048f, -0.567460f, -0.515873f, -0.464286f,
-0.412698f, -0.361111f, -0.309524f, -0.257937f,
-0.206349f, -0.154762f, -0.103175f, -0.051587f,
+0.000000f, +0.051587f, +0.103175f, +0.154762f,
+0.206349f, +0.257937f, +0.309524f, +0.361111f,
+0.412698f, +0.464286f, +0.515873f, +0.567460f,
+0.619048f, +0.670635f, +0.698611f, +0.724405f,
+0.750198f, +0.775992f, +0.801786f, +0.827579f,
+0.853373f, +0.879167f, +0.904960f, +0.930754f,
+0.951637f, +0.958085f, +0.964534f, +0.970982f,
+0.977431f, +0.983879f, +0.990327f, +0.996776f,
};
static const uint8_t utk_codebooks[2][256] = {
@ -145,23 +145,25 @@ static const struct {
{MDL_LARGEPULSE, 7, +6.0f}
};
/* In Lego Batman 2 gain[0] = 1.068 while other games (Lego Marvel, Lego SW) is 64.0f.
* The latter makes more sense and the former is audibly worse so it was probably a bug. */
static const float cbx_fixed_gains[64] = {
1.068, 68.351997, 72.999931, 77.963921,
83.265465, 88.927513, 94.974579, 101.43285,
108.33028, 115.69673, 123.5641, 131.96646,
140.94017, 150.52409, 160.75972, 171.69138,
183.36638, 195.83528, 209.15207, 223.3744,
238.56386, 254.78619, 272.11163, 290.6152,
310.37701, 331.48264, 354.02344, 378.09702,
403.80759, 431.26648, 460.59259, 491.91287,
525.36292, 561.08759, 599.24152, 639.98993,
683.50922, 729.98779, 779.62695, 832.64154,
889.26111, 949.73083, 1014.3125, 1083.2858,
1156.9491, 1235.6216, 1319.6438, 1409.3795,
1505.2173, 1607.572, 1716.8868, 1833.6351,
1958.3223, 2091.488, 2233.7092, 2385.6013,
2547.822, 2721.0737, 2906.1067, 3103.7219,
3314.7749, 3540.1794, 3780.9116, 4038.0134,
64.0f, 68.351997f, 72.999931f, 77.963921f,
83.265465f, 88.927513f, 94.974579f, 101.43285f,
108.33028f, 115.69673f, 123.5641f, 131.96646f,
140.94017f, 150.52409f, 160.75972f, 171.69138f,
183.36638f, 195.83528f, 209.15207f, 223.3744f,
238.56386f, 254.78619f, 272.11163f, 290.6152f,
310.37701f, 331.48264f, 354.02344f, 378.09702f,
403.80759f, 431.26648f, 460.59259f, 491.91287f,
525.36292f, 561.08759f, 599.24152f, 639.98993f,
683.50922f, 729.98779f, 779.62695f, 832.64154f,
889.26111f, 949.73083f, 1014.3125f, 1083.2858f,
1156.9491f, 1235.6216f, 1319.6438f, 1409.3795f,
1505.2173f, 1607.572f, 1716.8868f, 1833.6351f,
1958.3223f, 2091.488f, 2233.7092f, 2385.6013f,
2547.822f, 2721.0737f, 2906.1067f, 3103.7219f,
3314.7749f, 3540.1794f, 3780.9116f, 4038.0134f,
};
/* Bitreader in OG code can only read from set ptr; doesn't seem to check bounds though.
@ -223,14 +225,15 @@ static void consume_bits(struct bitreader_t* br, int count) {
static void parse_header(utk_context_t* ctx) {
if (ctx->type == UTK_CBX) {
/* CBX uses fixed parameters unlike EA-MT, probably encoder defaults for MT10:1 */
/* CBX uses fixed parameters unlike EA-MT, probably encoder defaults for MT10:1
* equivalent to EA-MT with base_thre = 8, base_gain = 7, base_mult = 28 (plus rounding diffs).
* OG CBX code uses values/tables directly rather than config though */
ctx->reduced_bandwidth = true;
ctx->multipulse_threshold = 32 - 8;
/* equivalent to EA-MT with base_gain = 8, base_mult = 28 (plus rounding diffs)
* then fixed_gain[0] is set to 1.068 afterwards.
* OG CBX code uses config/tables directly rather than copying though */
for (int i = 0; i < 64; i++) {
ctx->fixed_gains[0] = cbx_fixed_gains[0];
for (int i = 1; i < 64; i++) {
ctx->fixed_gains[i] = cbx_fixed_gains[i];
}
}

View File

@ -132,6 +132,7 @@ static const char* extension_list[] = {
"caf",
"cat",
"cbd2",
"cbx",
"cd",
"cfn", //fake extension for CAF (renamed, to be removed?)
"chd", //txth/reserved [Donkey Konga (GC), Star Fox Assault (GC)]
@ -1427,6 +1428,7 @@ static const meta_info meta_info_list[] = {
{meta_SNDS, "Sony SNDS header"},
{meta_NXOF, "Nihon Falcom FDK header"},
{meta_GWB_GWD, "Ubisoft GWB+GWD header"},
{meta_CBX, "Traveller's Tales CBX header"},
};
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {

46
src/meta/cbx.c Normal file
View File

@ -0,0 +1,46 @@
#include "meta.h"
#include "../coding/coding.h"
/* !B0X - Traveller's Tales speech files [Lego Batman 2 (PC), Lego Dimensions (PS3)] */
VGMSTREAM* init_vgmstream_cbx(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
uint32_t start_offset, pcm_size;
int loop_flag, channels, sample_rate;
/* checks */
if (!is_id32be(0x00,sf, "!B0X"))
return NULL;
if (!check_extensions(sf, "cbx"))
return NULL;
/* debug strings identify this as "Chatterbox"/"CBOX"/"CBX", while sound lib seems called "NuSound"
* (probably based on .utk) */
pcm_size = read_u32le(0x04, sf);
sample_rate = read_s32le(0x08, sf);
start_offset = 0x0c;
channels = 1;
loop_flag = 0;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_CBX;
vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = pcm_size / 2;
vgmstream->coding_type = coding_EA_MT;
vgmstream->layout_type = layout_none;
vgmstream->codec_data = init_ea_mt_cbx(vgmstream->channels);
if (!vgmstream->codec_data) goto fail;
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -1000,4 +1000,6 @@ VGMSTREAM* init_vgmstream_nxof(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_gwb_gwd(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_cbx(STREAMFILE* sf);
#endif /*_META_H*/

View File

@ -523,6 +523,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_nxof,
init_vgmstream_gwb_gwd,
init_vgmstream_s_pack,
init_vgmstream_cbx,
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
init_vgmstream_scd_pcm,

View File

@ -703,6 +703,7 @@ typedef enum {
meta_SNDS,
meta_NXOF,
meta_GWB_GWD,
meta_CBX,
} meta_t;