Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Request] F1 2011 - Codemasters i3DS format w/o txth #1414

Open
Sukotto-1999 opened this issue Sep 3, 2023 · 3 comments
Open

[Request] F1 2011 - Codemasters i3DS format w/o txth #1414

Sukotto-1999 opened this issue Sep 3, 2023 · 3 comments

Comments

@Sukotto-1999
Copy link

Sukotto-1999 commented Sep 3, 2023

I partially ported the code from .txth to source code. Should edit now. Format is basically a standard i3DS header with or without interleave value, no interleave last value in header, then two CWAV headers, then interleaved data with no padding. at the end of the source part, there's some code to at least automatically generate the interleave last value.

Format metadata:
NGC_DSP_I3DS
Codemasters i3DS header

#include "meta.h"
#include "../util.h"
#include "../coding/coding.h"

/* .3DS [from F1 2011 (3DS)] /
VGMSTREAM
init_vgmstream_ngc_dsp_i3ds(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
uint32_t start_offset;
uint32_t cwav_l_offset, cwav_r_offset, data_size;
size_t data_size;
int channels, sample_rate, interleave;

/* checks */
if (!is_id32be(0x00,sf, "i3DS"))
    goto fail;

/* .3ds: actual extension */
if (!check_extensions(sf, "3ds"))
    goto fail;


/* format is two "CWAV" headers then interleaved data */
cwav_l_offset = read_u32be(0x10, sf);
if (!is_id32be(cwav_l_offset,sf, "CWAV"))
    goto fail;
cwav_r_offset = read_u32be(0xd0, sf);
if (!is_id32be(cwav_r_offset,sf, "CWAV"))
    goto fail;

start_offset = 0x1A0;
interleave = read_u32le(0x0c, sf);
data_size =  read_u32be(cwav_l_offset + 0x4b, sf);

sample_rate = read_u32be(cwav_l_offset + 0x4b, sf);
channels = 2;

if (sample_rate != read_u32be(cwav_l_offset + 0x4b, sf))
    goto fail;


/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channels);
if (!vgmstream) goto fail;

vgmstream->meta_type = meta_NGC_DSP_I3DS;
vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = data_size;

vgmstream->coding_type = coding_NGC_DSP;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = interleave;
if (vgmstream->interleave_block_size)
    vgmstream->interleave_last_block_size =
            (data_size % (vgmstream->interleave_block_size*vgmstream->channels)) / vgmstream->channels;
			
dsp_read_coefs(vgmstream,sf, 0x8C);
dsp_read_hist(vgmstream, sf, 0xC0);

if (!vgmstream_open_stream(vgmstream, sf, start_offset))
    goto fail;
return vgmstream;

fail:
close_vgmstream(vgmstream);
return NULL;
}

end of code

@bnnm
Copy link
Collaborator

bnnm commented Sep 10, 2023

While it could be added at some point it has very low priority since TXTH is adecuate enough for those odd single game formats. It may be more interesting if this format is used in other games or similar variations for other consoles. Plus, the above code doesn't handle i3DS mono files (that do exist) so adding it as-is wouldn't be very interesting either.

@Sukotto-1999
Copy link
Author

Sukotto-1999 commented Sep 11, 2023

Okay, should edit the code properly to properly handle i3DS files. thx @bnnm

@Sukotto-1999
Copy link
Author

Sukotto-1999 commented Nov 28, 2023

Hi @bnnm. I just looked at a mono i3DS file from the game, turns out, mono i3DS files have no interleave value in header. That's easy, to identify if it is a mono i3DS file or not, the value at offset 0x0c is checked to make sure value is different that 0. if it isn't, should play as a mono channel. Thank you.

Well, unfortuanently, i3DS file format was only seen on F1 2011 for 3DS and only that game.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants