mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-15 02:57:38 +01:00
commit
709b897754
1068
cli/txtp_maker.py
1068
cli/txtp_maker.py
File diff suppressed because it is too large
Load Diff
23
doc/TXTP.md
23
doc/TXTP.md
@ -462,13 +462,22 @@ Wrong loop values (for example loop end being much larger than file's samples) w
|
|||||||
|
|
||||||
**Jewels Ocean (PC)**
|
**Jewels Ocean (PC)**
|
||||||
```
|
```
|
||||||
bgm01.ogg#I32.231 # from ~1421387 samples to end
|
bgm01.ogg #I32.231 # from ~1421387 samples to end
|
||||||
|
```
|
||||||
#bgm01.ogg#I 0:32.231 # equivalent
|
```
|
||||||
#bgm01.ogg#I 1421387 4212984 # equivalent, end is 4212984
|
bgm01.ogg #I 0:32.231 # equivalent
|
||||||
#bgm01.ogg#I32.231 1_35.533 # equivalent, end over file samples (~4213005) but adjusted to 4212984
|
```
|
||||||
#bgm01.ogg#I 1421387 4212985 # ignored, end over file samples
|
```
|
||||||
#bgm01.ogg#I32.231 1_37 # ignored, end over file (~4277700) but clearly wrong
|
bgm01.ogg #I 1421387 4212984 # equivalent, end is 4212984
|
||||||
|
```
|
||||||
|
```
|
||||||
|
bgm01.ogg #I32.231 1_35.533 # equivalent, end over file samples (~4213005) but adjusted to 4212984
|
||||||
|
```
|
||||||
|
```
|
||||||
|
bgm01.ogg #I 1421387 4212985 # ignored, end over file samples
|
||||||
|
```
|
||||||
|
```
|
||||||
|
bgm01.ogg #I32.231 1_37 # ignored, end over file (~4277700) but clearly wrong
|
||||||
```
|
```
|
||||||
|
|
||||||
Use this feature responsibly, though. If you find a format that should loop using internal values that vgmstream doesn't detect correctly, consider reporting the bug for the benefit of all users and other games using the same format, and don't throw out the original loop definitions (as sometimes they may not take into account "encoder delay" and must be carefully adjusted).
|
Use this feature responsibly, though. If you find a format that should loop using internal values that vgmstream doesn't detect correctly, consider reporting the bug for the benefit of all users and other games using the same format, and don't throw out the original loop definitions (as sometimes they may not take into account "encoder delay" and must be carefully adjusted).
|
||||||
|
@ -598,7 +598,7 @@ static STREAMFILE *open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks)
|
|||||||
|
|
||||||
/* EA MPF/MUS combo - used in older 7th gen games for storing interactive music */
|
/* EA MPF/MUS combo - used in older 7th gen games for storing interactive music */
|
||||||
VGMSTREAM * init_vgmstream_ea_mpf_mus_eaac(STREAMFILE* sf) {
|
VGMSTREAM * init_vgmstream_ea_mpf_mus_eaac(STREAMFILE* sf) {
|
||||||
uint32_t num_tracks, track_start, track_hash, mus_sounds, mus_stream = 0;
|
uint32_t num_tracks, track_start, track_hash = 0, mus_sounds, mus_stream = 0;
|
||||||
uint8_t version, sub_version;
|
uint8_t version, sub_version;
|
||||||
off_t tracks_table, samples_table, eof_offset, table_offset, entry_offset, snr_offset, sns_offset;
|
off_t tracks_table, samples_table, eof_offset, table_offset, entry_offset, snr_offset, sns_offset;
|
||||||
int32_t(*read_32bit)(off_t, STREAMFILE*);
|
int32_t(*read_32bit)(off_t, STREAMFILE*);
|
||||||
|
@ -78,9 +78,6 @@ static const uint8_t key_gh5[] = { 0xFC,0xF9,0xE4,0xB3,0xF5,0x57,0x5C,0xA5,0xAC,
|
|||||||
/* Sekiro: Shadows Die Twice (PC) */ //"G0KTrWjS9syqF7vVD6RaVXlFD91gMgkC"
|
/* Sekiro: Shadows Die Twice (PC) */ //"G0KTrWjS9syqF7vVD6RaVXlFD91gMgkC"
|
||||||
static const uint8_t key_sek[] = { 0x47,0x30,0x4B,0x54,0x72,0x57,0x6A,0x53,0x39,0x73,0x79,0x71,0x46,0x37,0x76,0x56,0x44,0x36,0x52,0x61,0x56,0x58,0x6C,0x46,0x44,0x39,0x31,0x67,0x4D,0x67,0x6B,0x43 };
|
static const uint8_t key_sek[] = { 0x47,0x30,0x4B,0x54,0x72,0x57,0x6A,0x53,0x39,0x73,0x79,0x71,0x46,0x37,0x76,0x56,0x44,0x36,0x52,0x61,0x56,0x58,0x6C,0x46,0x44,0x39,0x31,0x67,0x4D,0x67,0x6B,0x43 };
|
||||||
|
|
||||||
/* Stacking (X360) */ //"DFm3t4lFTW"
|
|
||||||
static const uint8_t key_sta[] = { 0x44,0x46,0x6d,0x33,0x74,0x34,0x6c,0x46,0x54,0x57 };
|
|
||||||
|
|
||||||
// Unknown:
|
// Unknown:
|
||||||
// - Battle: Los Angeles
|
// - Battle: Los Angeles
|
||||||
// - Guitar Hero: Warriors of Rock, DJ hero FSB
|
// - Guitar Hero: Warriors of Rock, DJ hero FSB
|
||||||
@ -144,7 +141,6 @@ static const fsbkey_info fsbkey_list[] = {
|
|||||||
{ 0,1, sizeof(key_mtj),key_mtj },// FSB3
|
{ 0,1, sizeof(key_mtj),key_mtj },// FSB3
|
||||||
{ 0,1, sizeof(key_gh5),key_gh5 },// FSB4
|
{ 0,1, sizeof(key_gh5),key_gh5 },// FSB4
|
||||||
{ 1,0, sizeof(key_sek),key_sek },// FSB5
|
{ 1,0, sizeof(key_sek),key_sek },// FSB5
|
||||||
{ 0,1, sizeof(key_sta),key_sta },// FSB4
|
|
||||||
|
|
||||||
};
|
};
|
||||||
static const int fsbkey_list_count = sizeof(fsbkey_list) / sizeof(fsbkey_list[0]);
|
static const int fsbkey_list_count = sizeof(fsbkey_list) / sizeof(fsbkey_list[0]);
|
||||||
|
424
src/meta/ivaud.c
424
src/meta/ivaud.c
@ -1,192 +1,232 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../layout/layout.h"
|
#include "../layout/layout.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int is_music;
|
int is_music;
|
||||||
|
|
||||||
int total_subsongs;
|
int total_subsongs;
|
||||||
|
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
int codec;
|
int codec;
|
||||||
int num_samples;
|
int num_samples;
|
||||||
|
|
||||||
size_t block_count;
|
size_t block_count;
|
||||||
size_t block_size;
|
size_t block_size;
|
||||||
|
|
||||||
off_t stream_offset;
|
off_t stream_offset;
|
||||||
size_t stream_size;
|
size_t stream_size;
|
||||||
|
|
||||||
} ivaud_header;
|
int big_endian;
|
||||||
|
} ivaud_header;
|
||||||
static int parse_ivaud_header(STREAMFILE* streamFile, ivaud_header* ivaud);
|
|
||||||
|
static int parse_ivaud_header(STREAMFILE* sf, ivaud_header* ivaud);
|
||||||
|
|
||||||
/* .ivaud - from GTA IV (PC) */
|
|
||||||
VGMSTREAM * init_vgmstream_ivaud(STREAMFILE *streamFile) {
|
/* .ivaud - from GTA IV (PC/PS3/X360) */
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM* init_vgmstream_ivaud(STREAMFILE* sf) {
|
||||||
ivaud_header ivaud = {0};
|
VGMSTREAM* vgmstream = NULL;
|
||||||
int loop_flag;
|
ivaud_header ivaud = {0};
|
||||||
|
int loop_flag;
|
||||||
/* checks */
|
|
||||||
/* (hashed filenames are likely extensionless and .ivaud is added by tools) */
|
/* checks */
|
||||||
if (!check_extensions(streamFile, "ivaud,"))
|
/* (hashed filenames are likely extensionless and .ivaud is added by tools) */
|
||||||
goto fail;
|
if (!check_extensions(sf, "ivaud,"))
|
||||||
|
goto fail;
|
||||||
/* check header */
|
|
||||||
if (!parse_ivaud_header(streamFile, &ivaud))
|
/* check header */
|
||||||
goto fail;
|
if (!parse_ivaud_header(sf, &ivaud))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
loop_flag = 0;
|
|
||||||
|
loop_flag = 0;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(ivaud.channel_count,loop_flag);
|
/* build the VGMSTREAM */
|
||||||
if (!vgmstream) goto fail;
|
vgmstream = allocate_vgmstream(ivaud.channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
vgmstream->sample_rate = ivaud.sample_rate;
|
|
||||||
vgmstream->num_samples = ivaud.num_samples;
|
vgmstream->sample_rate = ivaud.sample_rate;
|
||||||
vgmstream->num_streams = ivaud.total_subsongs;
|
vgmstream->num_samples = ivaud.num_samples;
|
||||||
vgmstream->stream_size = ivaud.stream_size;
|
vgmstream->num_streams = ivaud.total_subsongs;
|
||||||
vgmstream->meta_type = meta_IVAUD;
|
vgmstream->stream_size = ivaud.stream_size;
|
||||||
|
vgmstream->meta_type = meta_IVAUD;
|
||||||
switch(ivaud.codec) {
|
|
||||||
case 0x0001: /* common in sfx, uncommon in music (ex. EP2_SFX/MENU_MUSIC) */
|
switch(ivaud.codec) {
|
||||||
vgmstream->coding_type = coding_PCM16LE;
|
case 0x0001: /* common in sfx, uncommon in music (ex. EP2_SFX/MENU_MUSIC) */
|
||||||
vgmstream->layout_type = ivaud.is_music ? layout_blocked_ivaud : layout_none;
|
vgmstream->coding_type = coding_PCM16LE;
|
||||||
vgmstream->full_block_size = ivaud.block_size;
|
vgmstream->layout_type = ivaud.is_music ? layout_blocked_ivaud : layout_none;
|
||||||
break;
|
vgmstream->full_block_size = ivaud.block_size;
|
||||||
|
break;
|
||||||
case 0x0400:
|
|
||||||
vgmstream->coding_type = coding_IMA_int;
|
#ifdef VGM_USE_FFMPEG
|
||||||
vgmstream->layout_type = ivaud.is_music ? layout_blocked_ivaud : layout_none;
|
case 0x0000: { /* XMA2 (X360) */
|
||||||
vgmstream->full_block_size = ivaud.block_size;
|
uint8_t buf[0x100];
|
||||||
break;
|
size_t bytes;
|
||||||
|
|
||||||
default:
|
if (ivaud.is_music) {
|
||||||
VGM_LOG("IVAUD: unknown codec 0x%x\n", ivaud.codec);
|
goto fail;
|
||||||
goto fail;
|
}
|
||||||
}
|
else {
|
||||||
|
/* regular XMA for sfx */
|
||||||
|
bytes = ffmpeg_make_riff_xma1(buf, 0x100, ivaud.num_samples, ivaud.stream_size, ivaud.channel_count, ivaud.sample_rate, 0);
|
||||||
if (!vgmstream_open_stream(vgmstream,streamFile,ivaud.stream_offset))
|
vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, ivaud.stream_offset, ivaud.stream_size);
|
||||||
goto fail;
|
if (!vgmstream->codec_data) goto fail;
|
||||||
return vgmstream;
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
fail:
|
|
||||||
close_vgmstream(vgmstream);
|
xma_fix_raw_samples(vgmstream, sf, ivaud.stream_offset, ivaud.stream_size, 0, 0,0); /* samples are ok? */
|
||||||
return NULL;
|
}
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
/* Parse Rockstar's .ivaud header (much info from SparkIV). */
|
#endif
|
||||||
static int parse_ivaud_header(STREAMFILE* streamFile, ivaud_header* ivaud) {
|
|
||||||
int target_subsong = streamFile->stream_index;
|
#ifdef VGM_USE_MPEG
|
||||||
|
case 0x0100: { /* MPEG (PS3) */
|
||||||
|
mpeg_custom_config cfg = {0};
|
||||||
/* use bank's stream count to detect */
|
|
||||||
ivaud->is_music = (read_32bitLE(0x10,streamFile) == 0);
|
if (ivaud.is_music) {
|
||||||
|
goto fail;
|
||||||
if (ivaud->is_music) {
|
}
|
||||||
off_t block_table_offset, channel_table_offset, channel_info_offset;
|
else {
|
||||||
|
cfg.chunk_size = ivaud.block_size;
|
||||||
/* music header */
|
cfg.big_endian = ivaud.big_endian;
|
||||||
block_table_offset = read_32bitLE(0x00,streamFile); /* 64b */
|
|
||||||
ivaud->block_count = read_32bitLE(0x08,streamFile);
|
vgmstream->codec_data = init_mpeg_custom(sf, ivaud.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, &cfg);
|
||||||
ivaud->block_size = read_32bitLE(0x0c,streamFile); /* 64b, uses padded blocks */
|
if (!vgmstream->codec_data) goto fail;
|
||||||
channel_table_offset = read_32bitLE(0x14,streamFile); /* 64b */
|
vgmstream->layout_type = layout_none;
|
||||||
/* 0x1c(8): block_table_offset again? */
|
}
|
||||||
ivaud->channel_count = read_32bitLE(0x24,streamFile);
|
break;
|
||||||
/* 0x28(4): unknown entries? */
|
}
|
||||||
ivaud->stream_offset = read_32bitLE(0x2c,streamFile);
|
#endif
|
||||||
channel_info_offset = channel_table_offset + ivaud->channel_count*0x10;
|
|
||||||
|
case 0x0400: /* PC */
|
||||||
if ((ivaud->block_count * ivaud->block_size) + ivaud->stream_offset != get_streamfile_size(streamFile)) {
|
vgmstream->coding_type = coding_IMA_int;
|
||||||
VGM_LOG("IVAUD: bad file size\n");
|
vgmstream->layout_type = ivaud.is_music ? layout_blocked_ivaud : layout_none;
|
||||||
goto fail;
|
vgmstream->full_block_size = ivaud.block_size;
|
||||||
}
|
break;
|
||||||
|
|
||||||
/* channel table (one entry per channel, points to channel info) */
|
default:
|
||||||
/* 0x00(8): offset within channel_info_offset */
|
VGM_LOG("IVAUD: unknown codec 0x%x\n", ivaud.codec);
|
||||||
/* 0x08(4): hash */
|
goto fail;
|
||||||
/* 0x0c(4): size */
|
}
|
||||||
|
|
||||||
/* channel info (one entry per channel) */
|
|
||||||
/* 0x00(8): offset within data (should be 0) */
|
if (!vgmstream_open_stream(vgmstream,sf,ivaud.stream_offset))
|
||||||
/* 0x08(4): hash */
|
goto fail;
|
||||||
/* 0x0c(4): half num_samples? */
|
return vgmstream;
|
||||||
ivaud->num_samples = read_32bitLE(channel_info_offset+0x10,streamFile);
|
|
||||||
/* 0x14(4): unknown (-1) */
|
fail:
|
||||||
/* 0x18(2): sample rate */
|
close_vgmstream(vgmstream);
|
||||||
/* 0x1a(2): unknown */
|
return NULL;
|
||||||
ivaud->codec = read_32bitLE(channel_info_offset+0x1c,streamFile);
|
}
|
||||||
/* (when codec is IMA) */
|
|
||||||
/* 0x20(8): adpcm states offset, 0x38: num states? (reference for seeks?) */
|
/* Parse Rockstar's .ivaud header (much info from SparkIV). */
|
||||||
/* rest: unknown data */
|
static int parse_ivaud_header(STREAMFILE* sf, ivaud_header* ivaud) {
|
||||||
|
int target_subsong = sf->stream_index;
|
||||||
/* block table (one entry per block) */
|
uint64_t (*read_u64)(off_t,STREAMFILE*);
|
||||||
/* 0x00: data size processed up to this block (doesn't count block padding) */
|
uint32_t (*read_u32)(off_t,STREAMFILE*);
|
||||||
ivaud->sample_rate = read_32bitLE(block_table_offset + 0x04,streamFile);
|
uint16_t (*read_u16)(off_t,STREAMFILE*);
|
||||||
/* sample_rate should agree with each channel in the channel table */
|
|
||||||
|
|
||||||
|
ivaud->big_endian = read_u32be(0x00, sf) == 0; /* table offset at 0x04 > BE (64b) */
|
||||||
ivaud->total_subsongs = 1;
|
read_u64 = ivaud->big_endian ? read_u64be : read_u64le;
|
||||||
ivaud->stream_size = get_streamfile_size(streamFile);
|
read_u32 = ivaud->big_endian ? read_u32be : read_u32le;
|
||||||
}
|
read_u16 = ivaud->big_endian ? read_u16be : read_u16le;
|
||||||
else {
|
|
||||||
off_t stream_table_offset, stream_info_offset, stream_entry_offset;
|
/* use bank's stream count to detect */
|
||||||
|
ivaud->is_music = (read_u32(0x10,sf) == 0);
|
||||||
/* bank header */
|
|
||||||
stream_table_offset = read_32bitLE(0x00,streamFile); /* 64b */
|
if (ivaud->is_music) {
|
||||||
/* 0x08(8): header size? start offset? */
|
off_t block_table_offset, channel_table_offset, channel_info_offset;
|
||||||
ivaud->total_subsongs = read_32bitLE(0x10,streamFile);
|
|
||||||
/* 0x14(4): unknown */
|
/* music header */
|
||||||
ivaud->stream_offset = read_32bitLE(0x18,streamFile); /* base start_offset */
|
block_table_offset = read_u64(0x00,sf);
|
||||||
|
ivaud->block_count = read_u32(0x08,sf);
|
||||||
if (target_subsong == 0) target_subsong = 1;
|
ivaud->block_size = read_u32(0x0c,sf); /* uses padded blocks */
|
||||||
if (target_subsong < 0 || target_subsong > ivaud->total_subsongs || ivaud->total_subsongs < 1) goto fail;
|
/* 0x10(4): stream count */
|
||||||
|
channel_table_offset = read_u64(0x14,sf);
|
||||||
if (stream_table_offset != 0x1c)
|
/* 0x1c(8): block_table_offset again? */
|
||||||
goto fail;
|
ivaud->channel_count = read_u32(0x24,sf);
|
||||||
stream_info_offset = stream_table_offset + 0x10*ivaud->total_subsongs;
|
/* 0x28(4): unknown entries? */
|
||||||
|
ivaud->stream_offset = read_u32(0x2c,sf);
|
||||||
/* stream table (one entry per stream, points to stream info) */
|
channel_info_offset = channel_table_offset + ivaud->channel_count * 0x10;
|
||||||
stream_entry_offset = read_32bitLE(stream_table_offset + 0x10*(target_subsong-1) + 0x00,streamFile); /* within stream info */
|
|
||||||
/* 0x00(8): offset within stream_info_offset */
|
if ((ivaud->block_count * ivaud->block_size) + ivaud->stream_offset != get_streamfile_size(sf)) {
|
||||||
/* 0x08(4): hash */
|
VGM_LOG("IVAUD: bad file size\n");
|
||||||
/* 0x0c(4): size */
|
goto fail;
|
||||||
|
}
|
||||||
/* stream info (one entry per stream) */
|
|
||||||
ivaud->stream_offset += read_32bitLE(stream_info_offset+stream_entry_offset+0x00,streamFile); /* 64b, within data */
|
/* channel table (one entry per channel, points to channel info) */
|
||||||
/* 0x08(4): hash */
|
/* 0x00(8): offset within channel_info_offset */
|
||||||
/* 0x0c(4): half num_samples? */
|
/* 0x08(4): hash */
|
||||||
ivaud->num_samples = read_32bitLE(stream_info_offset+stream_entry_offset+0x10,streamFile);
|
/* 0x0c(4): size */
|
||||||
/* 0x14(4): unknown (-1) */
|
|
||||||
ivaud->sample_rate = (uint16_t)read_16bitLE(stream_info_offset+stream_entry_offset+0x18,streamFile);
|
/* channel info (one entry per channel) */
|
||||||
/* 0x1a(2): unknown */
|
/* 0x00(8): offset within data (should be 0) */
|
||||||
ivaud->codec = read_32bitLE(stream_info_offset+stream_entry_offset+0x1c,streamFile);
|
/* 0x08(4): hash */
|
||||||
/* (when codec is IMA) */
|
/* 0x0c(4): half num_samples? */
|
||||||
/* 0x20(8): adpcm states offset, 0x38: num states? (reference for seeks?) */
|
ivaud->num_samples = read_u32(channel_info_offset+0x10,sf);
|
||||||
/* rest: unknown data */
|
/* 0x14(4): unknown (-1) */
|
||||||
|
/* 0x18(2): sample rate */
|
||||||
ivaud->channel_count = 1;
|
/* 0x1a(2): unknown */
|
||||||
|
ivaud->codec = read_u32(channel_info_offset+0x1c,sf);
|
||||||
/* ghetto size calculator (could substract offsets but streams are not ordered) */
|
/* (when codec is IMA) */
|
||||||
switch(ivaud->codec) {
|
/* 0x20(8): adpcm states offset, 0x38: num states? (reference for seeks?) */
|
||||||
case 0x0001:
|
/* rest: unknown data */
|
||||||
ivaud->stream_size = ivaud->num_samples * 2; /* double 16b PCM */
|
|
||||||
break;
|
/* block table (one entry per block) */
|
||||||
case 0x0400:
|
/* 0x00: data size processed up to this block (doesn't count block padding) */
|
||||||
ivaud->stream_size = ivaud->num_samples / 2; /* half nibbles */
|
ivaud->sample_rate = read_u32(block_table_offset + 0x04,sf);
|
||||||
break;
|
/* sample_rate should agree with each channel in the channel table */
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
ivaud->total_subsongs = 1;
|
||||||
}
|
ivaud->stream_size = get_streamfile_size(sf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
return 1;
|
off_t stream_table_offset, stream_info_offset, stream_entry_offset, offset;
|
||||||
fail:
|
|
||||||
return 0;
|
/* bank header */
|
||||||
}
|
stream_table_offset = read_u64(0x00,sf);
|
||||||
|
/* 0x08(8): header size? start offset? */
|
||||||
|
ivaud->total_subsongs = read_u32(0x10,sf);
|
||||||
|
/* 0x14(4): unknown */
|
||||||
|
ivaud->stream_offset = read_u32(0x18,sf); /* base start_offset */
|
||||||
|
|
||||||
|
if (target_subsong == 0) target_subsong = 1;
|
||||||
|
if (target_subsong < 0 || target_subsong > ivaud->total_subsongs || ivaud->total_subsongs < 1) goto fail;
|
||||||
|
|
||||||
|
if (stream_table_offset != 0x1c)
|
||||||
|
goto fail;
|
||||||
|
stream_info_offset = stream_table_offset + 0x10*ivaud->total_subsongs;
|
||||||
|
|
||||||
|
/* stream table (one entry per stream, points to stream info) */
|
||||||
|
stream_entry_offset = read_u64(stream_table_offset + 0x10*(target_subsong-1) + 0x00,sf); /* within stream info */
|
||||||
|
/* 0x00(8): offset within stream_info_offset */
|
||||||
|
/* 0x08(4): hash */
|
||||||
|
/* 0x0c(4): some offset/size */
|
||||||
|
|
||||||
|
/* stream info (one entry per stream) */
|
||||||
|
offset = stream_info_offset + stream_entry_offset;
|
||||||
|
ivaud->stream_offset += read_u64(offset+0x00,sf); /* within data */
|
||||||
|
/* 0x08(4): hash */
|
||||||
|
ivaud->stream_size = read_u32(offset+0x0c,sf);
|
||||||
|
ivaud->num_samples = read_u32(offset+0x10,sf);
|
||||||
|
/* 0x14(4): unknown (-1) */
|
||||||
|
ivaud->sample_rate = read_u16(offset+0x18,sf);
|
||||||
|
/* 0x1a(2): unknown */
|
||||||
|
ivaud->codec = read_u32(offset+0x1c,sf);
|
||||||
|
/* (when codec is IMA) */
|
||||||
|
/* 0x20(8): adpcm states offset, 0x38: num states? (reference for seeks?) */
|
||||||
|
/* rest: unknown data */
|
||||||
|
|
||||||
|
ivaud->channel_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
fail:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -57,6 +57,7 @@ void vgmstream_set_play_forever(VGMSTREAM* vgmstream, int enabled) {
|
|||||||
* (play config is left untouched, should mix ok as this flag is only used during
|
* (play config is left untouched, should mix ok as this flag is only used during
|
||||||
* render, while config is always prepared as if play forever wasn't enabled) */
|
* render, while config is always prepared as if play forever wasn't enabled) */
|
||||||
vgmstream->config.play_forever = enabled;
|
vgmstream->config.play_forever = enabled;
|
||||||
|
setup_vgmstream(vgmstream); /* update config */
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vgmstream_get_samples(VGMSTREAM* vgmstream) {
|
int32_t vgmstream_get_samples(VGMSTREAM* vgmstream) {
|
||||||
|
Loading…
Reference in New Issue
Block a user