mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
Merge pull request #1398 from bnnm/squeak2-etc
- Add more SqueakStream/SqueakSample codecs - Add SNDS format - Remove fake extension .sgx (use .sgh+sgd) - Remove fake extension .tydsp (use .mus) - Add .trs extension [Kamiwaza (PS2), Shinobido (PS2)]
This commit is contained in:
commit
5d494c52b0
5
.github/changelog.py
vendored
5
.github/changelog.py
vendored
@ -53,8 +53,9 @@ def load_git():
|
||||
raise ValueError("git exception")
|
||||
latest_tag = proc.stdout.decode('utf-8').strip()
|
||||
|
||||
# no apparent portable way to get a utc timezone in date=format
|
||||
#args = ['git','--no-pager','log', '--merges', '--date=format:"%Y-%m-%d %H:%M:%S"', '--max-count', str(GIT_MAX_MERGES) ]
|
||||
args = ['git','--no-pager','log', '--merges', '--date=format:"%Y-%m-%d %H:%M:%S"', '%s..HEAD' % (latest_tag)]
|
||||
args = ['git','--no-pager','log', '--merges', '--date=format:"%Y-%m-%d %H:%M:%S %z"', '%s..HEAD' % (latest_tag)]
|
||||
proc = subprocess.run(args, capture_output=True)
|
||||
if proc.returncode != 0:
|
||||
raise ValueError("git exception")
|
||||
@ -160,7 +161,7 @@ def get_lines(short_log=False):
|
||||
if short_log:
|
||||
lines = []
|
||||
else:
|
||||
curr_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
curr_date = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S %z")
|
||||
lines = [
|
||||
'### CHANGELOG',
|
||||
'(latest changes from previous release, generated on %s)' % (curr_date),
|
||||
|
@ -420,10 +420,6 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- CRI AIX header [*AIX*]
|
||||
- *aix*: `.aix`
|
||||
- Subfiles: *adx*
|
||||
- **ngc_tydsp.c**
|
||||
- .tydsp Header [*NGC_TYDSP*]
|
||||
- *ngc_tydsp*: `.tydsp`
|
||||
- Codecs: NGC_DSP
|
||||
- **wvs.c**
|
||||
- Swingin' Ape .WVS header [*WVS*]
|
||||
- *wvs_xbox*: `.wvs`
|
||||
@ -500,9 +496,9 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- *ngc_pdt*: `.pdt`
|
||||
- *ngc_pdt_split*: `.pdt`
|
||||
- Codecs: NGC_DSP
|
||||
- **mus_krone.c**
|
||||
- Krone .MUS header [*MUS_KRONE*]
|
||||
- *mus_krone*: `.mus`
|
||||
- **mus_krome.c**
|
||||
- Krome .MUS header [*MUS_KROME*]
|
||||
- *mus_krome*: `.mus`
|
||||
- Codecs: NGC_DSP
|
||||
- **dc_asd.c**
|
||||
- ASD Header [*DC_ASD*]
|
||||
@ -662,10 +658,6 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- **redspark.c**
|
||||
- RedSpark Header [*REDSPARK*]
|
||||
- Codecs: NGC_DSP
|
||||
- **ivaud.c**
|
||||
- Rockstar .ivaud header [*IVAUD*]
|
||||
- *ivaud*: `.ivaud .(extensionless)`
|
||||
- Codecs: PCM16LE XMA1 MPEG IMA_int
|
||||
- **ps2_sps.c**
|
||||
- Ape Escape 2 SPS Header [*PS2_SPS*]
|
||||
- *ps2_sps*: `.sps`
|
||||
@ -862,7 +854,7 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Codecs: PCM16LE
|
||||
- **sgxd.c**
|
||||
- Sony SGXD header [*SGXD*]
|
||||
- *sgxd*: `.sgb .sgx .sgd + .sgh .sgb`
|
||||
- *sgxd*: `.sgb .sgd + .sgh .sgb`
|
||||
- Codecs: PCM16BE OGG_VORBIS PSX ATRAC3 PSX_cfg FFmpeg(various)
|
||||
- **wii_ras.c**
|
||||
- RAS header [*WII_RAS*]
|
||||
@ -1040,9 +1032,9 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Microsoft XMA RIFF header [*XMA_RIFF*]
|
||||
- *xma*: `.xma .xma2 .wav .lwav .nps .str .kmx`
|
||||
- Codecs: XMA
|
||||
- **sxd.c**
|
||||
- Sony SXD header [*SXD*]
|
||||
- *sxd*: `.sxd .sxd2 .sxd3 + .sxd1`
|
||||
- **sndx.c**
|
||||
- Sony SNDX header [*SNDX*]
|
||||
- *sndx*: `.sxd .sxd2 .sxd3 + .sxd1`
|
||||
- Codecs: PSX HEVAG ATRAC9
|
||||
- **ogl.c**
|
||||
- Shin'en OGL header [*OGL*]
|
||||
@ -1793,7 +1785,10 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Torus SqueakStream header [*SQUEAKSTREAM*]
|
||||
- Torus SqueakSample header [*SQUEAKSAMPLE*]
|
||||
- *squeaksample*: `(base) + .asset .(external) .raw`
|
||||
- Codecs: NGC_DSP PCM16LE PCM16BE PSX PCM8 MS_IMA IMA
|
||||
- Codecs: NGC_DSP PCM16LE PCM16BE PSX PCM8 MS_IMA IMA XMA2 OGG_VORBIS SPEEX
|
||||
- **snds.c**
|
||||
- Sony SNDS header [*SNDS*]
|
||||
- Codecs: ATRAC9
|
||||
- **scd_pcm.c**
|
||||
- Lunar: Eternal Blue .PCM header [*SCD_PCM*]
|
||||
- *scd_pcm*: `.pcm`
|
||||
@ -1826,6 +1821,10 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Tiger Game.com .4 header [*TGC*]
|
||||
- *tgc*: `.4`
|
||||
- Codecs: TGC
|
||||
- **ivaud.c**
|
||||
- Rockstar .ivaud header [*IVAUD*]
|
||||
- *ivaud*: `.ivaud .(extensionless)`
|
||||
- Codecs: PCM16LE XMA1 MPEG IMA_int
|
||||
- **pos.c**
|
||||
- RIFF WAVE header (.pos looping) [*RIFF_WAVE_POS*]
|
||||
- *pos*: `.pos + .wav`
|
||||
|
@ -588,6 +588,7 @@ void free_celt_fsb(celt_codec_data* data);
|
||||
typedef struct speex_codec_data speex_codec_data;
|
||||
|
||||
speex_codec_data* init_speex_ea(int channels);
|
||||
speex_codec_data* init_speex_torus(int channels);
|
||||
void decode_speex(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_speex(speex_codec_data* data);
|
||||
void seek_speex(VGMSTREAM* vgmstream, int32_t num_sample);
|
||||
|
@ -10,15 +10,19 @@
|
||||
#define SPEEX_DECODE_OK 0 /* -1 for end of stream, -2 corrupt stream */
|
||||
|
||||
|
||||
typedef enum { EA, TORUS } type_t;
|
||||
|
||||
/* opaque struct */
|
||||
struct speex_codec_data {
|
||||
type_t type;
|
||||
|
||||
/* config */
|
||||
int channels;
|
||||
int samples_discard;
|
||||
int encoder_delay;
|
||||
|
||||
uint8_t buf[SPEEX_MAX_FRAME_SIZE];
|
||||
uint8_t frame_size;
|
||||
int frame_size;
|
||||
|
||||
int16_t* samples;
|
||||
int frame_samples;
|
||||
@ -32,7 +36,7 @@ struct speex_codec_data {
|
||||
|
||||
|
||||
/* raw SPEEX */
|
||||
speex_codec_data* init_speex_ea(int channels) {
|
||||
static speex_codec_data* init_speex(type_t type, int channels) {
|
||||
int res, sample_rate;
|
||||
speex_codec_data* data = NULL;
|
||||
|
||||
@ -40,7 +44,9 @@ speex_codec_data* init_speex_ea(int channels) {
|
||||
data = calloc(1, sizeof(speex_codec_data));
|
||||
if (!data) goto fail;
|
||||
|
||||
//TODO: EA uses N decoders, unknown layout (known samples are mono)
|
||||
data->type = type;
|
||||
|
||||
//TODO: unknown layout (known samples are mono, EA: N decoders, Torus: N too?)
|
||||
data->channels = channels;
|
||||
if (channels != 1)
|
||||
goto fail;
|
||||
@ -78,6 +84,14 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
speex_codec_data* init_speex_ea(int channels) {
|
||||
return init_speex(EA, channels);
|
||||
}
|
||||
|
||||
speex_codec_data* init_speex_torus(int channels) {
|
||||
return init_speex(TORUS, channels);
|
||||
}
|
||||
|
||||
|
||||
static int decode_frame(speex_codec_data* data) {
|
||||
int res;
|
||||
@ -102,8 +116,18 @@ fail:
|
||||
static int read_frame(speex_codec_data* data, VGMSTREAMCHANNEL* stream) {
|
||||
size_t bytes;
|
||||
|
||||
switch(data->type) {
|
||||
case EA:
|
||||
data->frame_size = read_u8(stream->offset, stream->streamfile);
|
||||
stream->offset += 0x01;
|
||||
break;
|
||||
case TORUS:
|
||||
data->frame_size = read_u16le(stream->offset, stream->streamfile);
|
||||
stream->offset += 0x02;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (data->frame_size == 0) goto fail;
|
||||
|
||||
bytes = read_streamfile(data->buf, stream->offset, data->frame_size, stream->streamfile);
|
||||
|
@ -498,7 +498,6 @@ static const char* extension_list[] = {
|
||||
"sgb",
|
||||
"sgd",
|
||||
"sgt",
|
||||
"sgx",
|
||||
"slb", //txth/reserved [THE Nekomura no Hitobito (PS2)]
|
||||
"sli",
|
||||
"smc",
|
||||
@ -559,10 +558,10 @@ static const char* extension_list[] = {
|
||||
"tmx",
|
||||
"tra",
|
||||
"trk",
|
||||
"trs", //txth/semi [Kamiwaza (PS2), Shinobido (PS2)]
|
||||
"tun",
|
||||
"txth",
|
||||
"txtp",
|
||||
"tydsp",
|
||||
|
||||
"u0",
|
||||
"ue4opus",
|
||||
@ -1073,7 +1072,6 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_PS2_VAS, "Konami .VAS header"},
|
||||
{meta_LP_AP_LEP, "Konami LP/AP/LEP header"},
|
||||
{meta_SDT, "High Voltage .sdt header"},
|
||||
{meta_NGC_TYDSP, ".tydsp Header"},
|
||||
{meta_WVS, "Swingin' Ape .WVS header"},
|
||||
{meta_DEC, "Falcom .DEC RIFF header"},
|
||||
{meta_VS, "Melbourne House .VS header"},
|
||||
@ -1088,7 +1086,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_YMF, "Yuke's .YMF Header"},
|
||||
{meta_FAG, "Radical .FAG Header"},
|
||||
{meta_PS2_MIHB, "Sony MultiStream MIC header"},
|
||||
{meta_MUS_KRONE, "Krone .MUS header"},
|
||||
{meta_MUS_KROME, "Krome .MUS header"},
|
||||
{meta_WII_SNG, "SNG DSP Header"},
|
||||
{meta_RSD, "Radical RSD header"},
|
||||
{meta_DC_ASD, "ASD Header"},
|
||||
@ -1242,7 +1240,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_ASTB, "Capcom ASTB header"},
|
||||
{meta_WWISE_RIFF, "Audiokinetic Wwise RIFF header"},
|
||||
{meta_UBI_RAKI, "Ubisoft RAKI header"},
|
||||
{meta_SXD, "Sony SXD header"},
|
||||
{meta_SNDX, "Sony SNDX header"},
|
||||
{meta_OGL, "Shin'en OGL header"},
|
||||
{meta_MC3, "Paradigm MC3 header"},
|
||||
{meta_GHS, "Hexadrive GHS/S_P_STH header"},
|
||||
@ -1412,6 +1410,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_AWD, "RenderWare Audio Wave Dictionary header"},
|
||||
{meta_SQUEAKSTREAM, "Torus SqueakStream header"},
|
||||
{meta_SQUEAKSAMPLE, "Torus SqueakSample header"},
|
||||
{meta_SNDS, "Sony SNDS header"},
|
||||
};
|
||||
|
||||
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
|
||||
|
@ -175,6 +175,7 @@
|
||||
<ClInclude Include="util\cri_keys.h" />
|
||||
<ClInclude Include="util\cri_utf.h" />
|
||||
<ClInclude Include="util\endianness.h" />
|
||||
<ClInclude Include="util\layout_utils.h" />
|
||||
<ClInclude Include="util\log.h" />
|
||||
<ClInclude Include="util\m2_psb.h" />
|
||||
<ClInclude Include="util\miniz.h" />
|
||||
@ -502,7 +503,7 @@
|
||||
<ClCompile Include="meta\musc.c" />
|
||||
<ClCompile Include="meta\musx.c" />
|
||||
<ClCompile Include="meta\mus_acm.c" />
|
||||
<ClCompile Include="meta\mus_krone.c" />
|
||||
<ClCompile Include="meta\mus_krome.c" />
|
||||
<ClCompile Include="meta\mus_vc.c" />
|
||||
<ClCompile Include="meta\myspd.c" />
|
||||
<ClCompile Include="meta\naac.c" />
|
||||
@ -523,7 +524,6 @@
|
||||
<ClCompile Include="meta\ngc_sck_dsp.c" />
|
||||
<ClCompile Include="meta\ngc_ssm.c" />
|
||||
<ClCompile Include="meta\ngc_str_cauldron.c" />
|
||||
<ClCompile Include="meta\ngc_tydsp.c" />
|
||||
<ClCompile Include="meta\nps.c" />
|
||||
<ClCompile Include="meta\nub.c" />
|
||||
<ClCompile Include="meta\nus3audio.c" />
|
||||
@ -627,6 +627,8 @@
|
||||
<ClCompile Include="meta\smp.c" />
|
||||
<ClCompile Include="meta\smpl.c" />
|
||||
<ClCompile Include="meta\smv.c" />
|
||||
<ClCompile Include="meta\snds.c" />
|
||||
<ClCompile Include="meta\sndx.c" />
|
||||
<ClCompile Include="meta\sndz.c" />
|
||||
<ClCompile Include="meta\spm.c" />
|
||||
<ClCompile Include="meta\spsd.c" />
|
||||
@ -651,7 +653,6 @@
|
||||
<ClCompile Include="meta\svg.c" />
|
||||
<ClCompile Include="meta\svs.c" />
|
||||
<ClCompile Include="meta\swav.c" />
|
||||
<ClCompile Include="meta\sxd.c" />
|
||||
<ClCompile Include="meta\tac.c" />
|
||||
<ClCompile Include="meta\tgc.c" />
|
||||
<ClCompile Include="meta\thp.c" />
|
||||
@ -737,6 +738,7 @@
|
||||
<ClCompile Include="util\companion_files.c" />
|
||||
<ClCompile Include="util\cri_keys.c" />
|
||||
<ClCompile Include="util\cri_utf.c" />
|
||||
<ClCompile Include="util\layout_utils.c" />
|
||||
<ClCompile Include="util\log.c" />
|
||||
<ClCompile Include="util\m2_psb.c" />
|
||||
<ClCompile Include="util\miniz.c" />
|
||||
|
@ -350,6 +350,9 @@
|
||||
<ClInclude Include="util\endianness.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\layout_utils.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\log.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -1327,7 +1330,7 @@
|
||||
<ClCompile Include="meta\mus_acm.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\mus_krone.c">
|
||||
<ClCompile Include="meta\mus_krome.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\mus_vc.c">
|
||||
@ -1390,9 +1393,6 @@
|
||||
<ClCompile Include="meta\ngc_str_cauldron.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ngc_tydsp.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\nps.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1702,6 +1702,12 @@
|
||||
<ClCompile Include="meta\smv.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\snds.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\sndx.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\sndz.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1774,9 +1780,6 @@
|
||||
<ClCompile Include="meta\swav.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\sxd.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\tac.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -2032,6 +2035,9 @@
|
||||
<ClCompile Include="util\cri_utf.c">
|
||||
<Filter>util\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\layout_utils.c">
|
||||
<Filter>util\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\log.c">
|
||||
<Filter>util\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
|
||||
typedef struct {
|
||||
int is_music;
|
||||
@ -31,13 +32,13 @@ VGMSTREAM* init_vgmstream_ivaud(STREAMFILE* sf) {
|
||||
int loop_flag;
|
||||
|
||||
/* checks */
|
||||
/* (hashed filenames are likely extensionless and .ivaud is added by tools) */
|
||||
/* (hashed filenames are likely extensionless, .ivaud is added by tools) */
|
||||
if (!check_extensions(sf, "ivaud,"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* check header */
|
||||
if (!parse_ivaud_header(sf, &ivaud))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
|
||||
loop_flag = 0;
|
||||
@ -121,9 +122,9 @@ fail:
|
||||
/* Parse Rockstar's .ivaud header (much info from SparkIV). */
|
||||
static int parse_ivaud_header(STREAMFILE* sf, ivaud_header* ivaud) {
|
||||
int target_subsong = sf->stream_index;
|
||||
uint64_t (*read_u64)(off_t,STREAMFILE*);
|
||||
uint32_t (*read_u32)(off_t,STREAMFILE*);
|
||||
uint16_t (*read_u16)(off_t,STREAMFILE*);
|
||||
read_u64_t read_u64;
|
||||
read_u32_t read_u32;
|
||||
read_u16_t read_u16;
|
||||
|
||||
|
||||
ivaud->big_endian = read_u32be(0x00, sf) == 0; /* table offset at 0x04 > BE (64b) */
|
||||
@ -131,6 +132,10 @@ static int parse_ivaud_header(STREAMFILE* sf, ivaud_header* ivaud) {
|
||||
read_u32 = ivaud->big_endian ? read_u32be : read_u32le;
|
||||
read_u16 = ivaud->big_endian ? read_u16be : read_u16le;
|
||||
|
||||
uint64_t table_offset = read_u64(0x00,sf);
|
||||
if (table_offset > 0x10000) /* arbitrary max, typically 0x1c~0x1000 */
|
||||
return 0;
|
||||
|
||||
/* use bank's stream count to detect */
|
||||
ivaud->is_music = (read_u32(0x10,sf) == 0);
|
||||
|
||||
@ -138,7 +143,7 @@ static int parse_ivaud_header(STREAMFILE* sf, ivaud_header* ivaud) {
|
||||
off_t block_table_offset, channel_table_offset, channel_info_offset;
|
||||
|
||||
/* music header */
|
||||
block_table_offset = read_u64(0x00,sf);
|
||||
block_table_offset = table_offset;
|
||||
ivaud->block_count = read_u32(0x08,sf);
|
||||
ivaud->block_size = read_u32(0x0c,sf); /* uses padded blocks */
|
||||
/* 0x10(4): stream count */
|
||||
@ -185,7 +190,7 @@ static int parse_ivaud_header(STREAMFILE* sf, ivaud_header* ivaud) {
|
||||
off_t stream_table_offset, stream_info_offset, stream_entry_offset, offset;
|
||||
|
||||
/* bank header */
|
||||
stream_table_offset = read_u64(0x00,sf);
|
||||
stream_table_offset = table_offset;
|
||||
/* 0x08(8): header size? start offset? */
|
||||
ivaud->total_subsongs = read_u32(0x10,sf);
|
||||
/* 0x14(4): unknown */
|
||||
|
@ -257,8 +257,6 @@ VGMSTREAM * init_vgmstream_sdt(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_aix(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_tydsp(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_wvs_xbox(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_wvs_ngc(STREAMFILE* sf);
|
||||
|
||||
@ -298,7 +296,7 @@ VGMSTREAM * init_vgmstream_ps2_mihb(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_ngc_pdt_split(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_ngc_pdt(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_mus_krone(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_mus_krome(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_rsd(STREAMFILE * streamFile);
|
||||
|
||||
@ -574,7 +572,7 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_pasx(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile);
|
||||
VGMSTREAM * init_vgmstream_sndx(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ogl(STREAMFILE *streamFile);
|
||||
|
||||
@ -981,5 +979,6 @@ VGMSTREAM* init_vgmstream_pwb(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_squeakstream(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_squeaksample(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_snds(STREAMFILE* sf);
|
||||
|
||||
#endif /*_META_H*/
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* .mus - from Star Wars: The Force Unleashed (Wii) */
|
||||
VGMSTREAM* init_vgmstream_mus_krone(STREAMFILE* sf) {
|
||||
/* .mus - from Krome games [Ty: The Tasmanian Tiger 2 (GC), Star Wars: The Force Unleashed (Wii)] */
|
||||
VGMSTREAM* init_vgmstream_mus_krome(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t start_offset, data_size;
|
||||
int channels, loop_flag, interleave;
|
||||
@ -36,7 +36,7 @@ VGMSTREAM* init_vgmstream_mus_krone(STREAMFILE* sf) {
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_MUS_KRONE;
|
||||
vgmstream->meta_type = meta_MUS_KROME;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->sample_rate = read_u16be(0x6c,sf);
|
||||
|
@ -1,72 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* TYDSP (Ty - The Tasmanian Tiger) */
|
||||
VGMSTREAM * init_vgmstream_ngc_tydsp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("tydsp",filename_extension(filename))) goto fail;
|
||||
|
||||
loop_flag = 1;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = read_32bitBE(0x08,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = (uint16_t)(read_16bitBE(0x6C,streamFile));
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x00,streamFile);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x00,streamFile);
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile);
|
||||
vgmstream->meta_type = meta_NGC_TYDSP;
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x10+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->channels) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x3E +i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=start_offset+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -216,6 +216,7 @@ VGMSTREAM* init_vgmstream_sdrh_old(STREAMFILE* sf) {
|
||||
* 0x30: file name in a custom 40-char (RADIX style) encoding
|
||||
* others: ? (change in old/new)
|
||||
*/
|
||||
/* there is also an older version in Shadow Hearts 2, more basic (no section table) and may contain sequences */
|
||||
|
||||
/* parse section */
|
||||
{
|
||||
|
@ -3,16 +3,15 @@
|
||||
#include "../util/chunks.h"
|
||||
|
||||
|
||||
/* SGXD - Sony/SCEI's format (SGB+SGH / SGD / SGX) */
|
||||
/* SGXD - Sony/SCEI's SGX lib (cousin of RXWS) */
|
||||
VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sf_head = NULL;
|
||||
STREAMFILE* sf_body = NULL;
|
||||
off_t start_offset, data_offset, chunk_offset, name_offset = 0;
|
||||
size_t stream_size;
|
||||
uint32_t base1_offset, base2_offset, base3_offset;
|
||||
|
||||
int is_sgx, is_sgd = 0;
|
||||
uint32_t /*base1_offset,*/ base2_offset, base3_offset;
|
||||
int is_sgd = 0;
|
||||
int loop_flag, channels, codec, sample_rate;
|
||||
int32_t num_samples, loop_start_sample, loop_end_sample;
|
||||
int total_subsongs, target_subsong = sf->stream_index;
|
||||
@ -28,35 +27,31 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
}
|
||||
|
||||
if (!is_id32be(0x00,sf_head, "SGXD"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* checks */
|
||||
/* .sgx: header+data (Genji)
|
||||
* .sgd: header+data (common)
|
||||
/* .sgd: header+data (common)
|
||||
* .sgh+sgd: header+data (streams) */
|
||||
if (!check_extensions(sf,"sgx,sgd,sgb"))
|
||||
goto fail;
|
||||
if (!check_extensions(sf,"sgd,sgb"))
|
||||
return NULL;
|
||||
|
||||
/* SGXD base (size 0x10), always LE even on PS3 */
|
||||
/* 0x04: SGX = full header size
|
||||
SGD/SGH = bank name offset (part of NAME table, usually same as filename) */
|
||||
/* 0x08: SGX = first chunk offset? (0x10)
|
||||
SGD/SGH = full header size */
|
||||
/* 0x0c: SGX/SGH = full data size with padding /
|
||||
SGD = full data size ^ (1<<31) with padding */
|
||||
base1_offset = read_u32le(0x04, sf_head);
|
||||
/* 0x04: SGD/SGH = bank name offset (part of NAME table, usually same as filename) */
|
||||
/* 0x08: SGD/SGH = full header size */
|
||||
/* 0x0c: SGH = full data size with padding
|
||||
* SGD = full data size ^ (1<<31) with padding */
|
||||
//base1_offset = read_u32le(0x04, sf_head);
|
||||
base2_offset = read_u32le(0x08, sf_head);
|
||||
base3_offset = read_u32le(0x0c, sf_head);
|
||||
|
||||
is_sgx = base2_offset == 0x10; /* fixed size */
|
||||
is_sgd = base3_offset & (1 << 31); /* flag */
|
||||
|
||||
/* Ogg SGXD don't have flag (probably due to codec hijack, or should be split), allow since it's not so obvious */
|
||||
if (!(is_sgx || is_sgd) && get_streamfile_size(sf_head) != base2_offset) /* sgh but wrong header size must be sgd */
|
||||
if (!(is_sgd) && get_streamfile_size(sf_head) != base2_offset) /* sgh but wrong header size must be sgd */
|
||||
is_sgd = 1;
|
||||
|
||||
/* for plugins that start with .sgh (and don't check extensions) */
|
||||
if (!(is_sgx || is_sgd) && sf == sf_head) {
|
||||
if (!(is_sgd) && sf == sf_head) {
|
||||
sf_body = open_streamfile_by_ext(sf, "sgb");
|
||||
if (!sf_body) goto fail;
|
||||
}
|
||||
@ -65,9 +60,7 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
}
|
||||
|
||||
|
||||
if (is_sgx) {
|
||||
data_offset = base1_offset;
|
||||
} else if (is_sgd) {
|
||||
if (is_sgd) {
|
||||
data_offset = base2_offset;
|
||||
} else {
|
||||
data_offset = 0x00;
|
||||
@ -76,7 +69,7 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
|
||||
/* Format per chunk:
|
||||
* - 0x00: id
|
||||
* - 0x04: SGX: unknown; SGD/SGH: chunk length
|
||||
* - 0x04: chunk length
|
||||
* - 0x08: null
|
||||
* - 0x0c: entries */
|
||||
|
||||
@ -103,14 +96,8 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
* - BUSS: bus config? */
|
||||
|
||||
/* WAVE chunk (size 0x10 + files * 0x38 + optional padding) */
|
||||
if (is_sgx) { /* position after chunk+size */
|
||||
if (!is_id32be(0x10,sf_head, "WAVE"))
|
||||
goto fail;
|
||||
chunk_offset = 0x18;
|
||||
} else {
|
||||
if (!find_chunk_le(sf_head, get_id32be("WAVE"),0x10,0, &chunk_offset, NULL))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check multi-streams (usually only SE containers; Puppeteer) */
|
||||
total_subsongs = read_s32le(chunk_offset+0x04,sf_head);
|
||||
@ -123,7 +110,6 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
chunk_offset += 0x08 + 0x38 * (target_subsong-1); /* position in target header*/
|
||||
|
||||
/* 0x00: ? (00/01/02) */
|
||||
if (!is_sgx) /* meaning unknown in .sgx; offset 0 = not a stream (a RGND sample) */
|
||||
name_offset = read_u32le(chunk_offset+0x04,sf_head);
|
||||
codec = read_u8(chunk_offset+0x08,sf_head);
|
||||
channels = read_u8(chunk_offset+0x09,sf_head);
|
||||
@ -141,13 +127,9 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
loop_end_sample = read_s32le(chunk_offset+0x28,sf_head);
|
||||
stream_size = read_u32le(chunk_offset+0x2c,sf_head); /* stream size (without padding) / interleave (for type3) */
|
||||
|
||||
if (is_sgx) {
|
||||
stream_offset = 0x0;
|
||||
} else{
|
||||
stream_offset = read_u32le(chunk_offset+0x30,sf_head);
|
||||
}
|
||||
/* 0x34: SGX = unknown
|
||||
* SGD/SGH = stream size (with padding) / interleave */
|
||||
|
||||
/* 0x34: SGD/SGH = stream size (with padding) / interleave */
|
||||
|
||||
loop_flag = loop_start_sample != -1 && loop_end_sample != -1;
|
||||
start_offset = data_offset + stream_offset;
|
||||
|
112
src/meta/snds.c
Normal file
112
src/meta/snds.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/chunks.h"
|
||||
|
||||
|
||||
/* SSDD - Sony/SCE's SNDS lib format (cousin of SGXD/SNDX) */
|
||||
VGMSTREAM* init_vgmstream_snds(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t stream_offset, stream_size;
|
||||
int loop_flag, channels, codec, sample_rate;
|
||||
int32_t num_samples, loop_start, loop_end, encoder_delay;
|
||||
uint32_t at9_config = 0;
|
||||
int total_subsongs, target_subsong = sf->stream_index;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "SSDD"))
|
||||
return NULL;
|
||||
|
||||
if (read_u32le(0x04, sf) != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
/* 0x10: file name */
|
||||
|
||||
/* (extensionless): no apparent extension in debug strings, though comparing other SCE libs possibly ".ssd" */
|
||||
if (!check_extensions(sf,""))
|
||||
return NULL;
|
||||
|
||||
/* from debug info seems to have free chunks but known files always use the same and 1 subsong */
|
||||
off_t base_offset = 0x60, wavs_offset = 0;
|
||||
if (!find_chunk_le(sf, get_id32be("WAVS"),base_offset,0, &wavs_offset,NULL))
|
||||
return NULL;
|
||||
|
||||
if (read_u16le(wavs_offset + 0x00, sf) != 0x2c) /* entry size? */
|
||||
return NULL;
|
||||
|
||||
total_subsongs = read_s16le(wavs_offset + 0x02, sf);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) return NULL;
|
||||
if (total_subsongs != 1) return NULL; /* not seen */
|
||||
|
||||
/* read stream header */
|
||||
{
|
||||
uint32_t head_offset = wavs_offset + 0x04 + 0x2c * (target_subsong - 1);
|
||||
/* 0x00: null/flags? */
|
||||
/* 0x04: null/offset? */
|
||||
/* 0x0c: null/offset? */
|
||||
codec = read_u8(head_offset + 0x0c, sf);
|
||||
channels = read_u16le(head_offset + 0x0d, sf);
|
||||
/* 0x0e: null? */
|
||||
sample_rate = read_u32le(head_offset + 0x10, sf);
|
||||
at9_config = read_u32le(head_offset + 0x14, sf); /* !!! (only known use of this lib is Android/iOS) */
|
||||
num_samples = read_s32le(head_offset + 0x18, sf);
|
||||
loop_start = read_s32le(head_offset + 0x1c, sf);
|
||||
loop_end = read_s32le(head_offset + 0x20, sf);
|
||||
encoder_delay = read_s32le(head_offset + 0x24, sf);
|
||||
stream_size = read_u32le(head_offset + 0x28, sf);
|
||||
|
||||
loop_flag = loop_end > 0;
|
||||
}
|
||||
|
||||
/* CUES chunk: cues (various fields, also names) */
|
||||
/* CUNS chunk: cue names (flags + hash + offset, then names) */
|
||||
|
||||
off_t wavd_offset = 0;
|
||||
if (!find_chunk_le(sf, get_id32be("WAVD"),wavs_offset - 0x08,0, &wavd_offset,NULL))
|
||||
return NULL;
|
||||
stream_offset = wavd_offset + 0x08;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_SNDS;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
vgmstream->stream_size = stream_size;
|
||||
|
||||
switch (codec) {
|
||||
#ifdef VGM_USE_ATRAC9
|
||||
case 0x41: {
|
||||
atrac9_config cfg = {0};
|
||||
|
||||
cfg.channels = channels;
|
||||
cfg.config_data = at9_config;
|
||||
cfg.encoder_delay = encoder_delay;
|
||||
|
||||
vgmstream->codec_data = init_atrac9(&cfg);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_ATRAC9;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
VGM_LOG("SNDS: unknown codec 0x%x\n", codec);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
if (!vgmstream_open_stream(vgmstream, sf, stream_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
#include "../util/chunks.h"
|
||||
|
||||
|
||||
/* SXD - Sony/SCE's SNDX lib format (cousin of SGXD) [Gravity Rush, Freedom Wars, Soul Sacrifice PSV] */
|
||||
VGMSTREAM* init_vgmstream_sxd(STREAMFILE* sf) {
|
||||
/* SXDF/SXDS - Sony/SCE's SNDX lib format (cousin of SGXD) [Gravity Rush, Freedom Wars, Soul Sacrifice PSV] */
|
||||
VGMSTREAM* init_vgmstream_sndx(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sf_sxd1 = NULL, *sf_sxd2 = NULL, *sf_data = NULL, *sf_h = NULL, *sf_b = NULL;
|
||||
off_t start_offset, chunk_offset, first_offset = 0x60, name_offset = 0;
|
||||
@ -180,7 +180,7 @@ VGMSTREAM* init_vgmstream_sxd(STREAMFILE* sf) {
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_SXD;
|
||||
vgmstream->meta_type = meta_SNDX;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
|
||||
vgmstream->num_samples = num_samples;
|
@ -2,9 +2,10 @@
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
#include "../util/layout_utils.h"
|
||||
|
||||
#define SQUEAK_MAX_CHANNELS 8 /* seen 3 in some voices */
|
||||
typedef enum { PCM16LE, PCM16BE, PCM8, DSP, PSX, MSIMA, IMA } squeak_type_t;
|
||||
#define SQUEAK_MAX_CHANNELS 6 /* seen 3 in some voices */
|
||||
typedef enum { PCM16LE, PCM16BE, PCM8, DSP, PSX, MSIMA, IMA, XMA2, VORBIS, SPEEX } squeak_type_t;
|
||||
|
||||
typedef struct {
|
||||
squeak_type_t type;
|
||||
@ -26,6 +27,8 @@ typedef struct {
|
||||
uint32_t coef_offset;
|
||||
uint32_t coef_spacing;
|
||||
|
||||
uint32_t data_offsets[SQUEAK_MAX_CHANNELS];
|
||||
uint32_t coef_offsets[SQUEAK_MAX_CHANNELS];
|
||||
uint32_t data_size;
|
||||
|
||||
bool big_endian;
|
||||
@ -37,22 +40,21 @@ typedef struct {
|
||||
static VGMSTREAM* init_vgmstream_squeak_common(STREAMFILE* sf, squeak_header_t* h);
|
||||
|
||||
|
||||
/* SqueakStream - from Torus games (as identified in .hnk subdirs) */
|
||||
/* SqueakStream - from Torus games (name/engine as identified in .hnk subdirs) */
|
||||
VGMSTREAM* init_vgmstream_squeakstream(STREAMFILE* sf) {
|
||||
squeak_header_t h = {0};
|
||||
bool is_old = false;
|
||||
|
||||
|
||||
/* checks */
|
||||
h.big_endian = false;
|
||||
if (is_id32be(0x00,sf, "RAWI")) {
|
||||
h.big_endian = false;
|
||||
if (is_id32be(0x00,sf, "RAWI") || is_id32be(0x00,sf, "VORB") || is_id32be(0x00,sf, "SPEX")) {
|
||||
h.big_endian = false; /* VORB/SPEX only use vorbis/speex but no apparent diffs */
|
||||
}
|
||||
else if (is_id32be(0x00,sf, "IWAR")) {
|
||||
h.big_endian = true; /* Wii/PS3/X360 */
|
||||
}
|
||||
else {
|
||||
/* no header id so test codec in dumb endian */
|
||||
/* no header id in early version so test codec in dumb endian */
|
||||
if ((read_u32le(0x00,sf) & 0x00FFFFFF) > 9 || (read_u32be(0x00,sf) & 0x00FFFFFF) > 9)
|
||||
return NULL;
|
||||
is_old = true;
|
||||
@ -139,11 +141,15 @@ VGMSTREAM* init_vgmstream_squeakstream(STREAMFILE* sf) {
|
||||
switch(h.codec) {
|
||||
case 0x00: h.type = DSP; break; /* Turbo Super Stunt Squad (Wii/3DS), Penguins of Madagascar (Wii/U/3DS) */
|
||||
case 0x01: h.type = PCM16LE; break; /* Falling Skies The Game (PC) */
|
||||
case 0x02: h.type = PCM16BE; break; /* Falling Skies The Game (X360) */
|
||||
case 0x02: h.type = h.big_endian ? PCM16BE : PCM16LE; break; /* Falling Skies The Game (X360)-be, Scooby Doo and the Spooky Swamp (PC)-le */
|
||||
case 0x03: h.type = PSX; break; /* How to Train Your Dragon 2 (PS3), Falling Skies The Game (PS3) */
|
||||
case 0x04: h.type = MSIMA; break; /* Barbie Dreamhouse Party (DS) */
|
||||
case 0x05: h.type = PCM8; break; /* Scooby Doo and the Spooky Swamp (DS), Scooby Doo! First Frights (DS) */
|
||||
case 0x07: h.type = SPEEX; break; /* Scooby Doo and the Spooky Swamp (PC) */
|
||||
case 0x08: h.type = VORBIS; break; /* Scooby Doo and the Spooky Swamp (PC) */
|
||||
case 0x09: h.type = MSIMA; break; /* Turbo Super Stunt Squad (DS) */
|
||||
default:
|
||||
VGM_LOG("SqueakStream: unknown codec %x\n", h.codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -151,7 +157,7 @@ VGMSTREAM* init_vgmstream_squeakstream(STREAMFILE* sf) {
|
||||
}
|
||||
|
||||
|
||||
/* SqueakSample - from Torus games (as identified in .hnk subdirs) */
|
||||
/* SqueakSample - from Torus games (name/engine as identified in .hnk subdirs) */
|
||||
VGMSTREAM* init_vgmstream_squeaksample(STREAMFILE* sf) {
|
||||
squeak_header_t h = {0};
|
||||
|
||||
@ -187,7 +193,6 @@ VGMSTREAM* init_vgmstream_squeaksample(STREAMFILE* sf) {
|
||||
h.loop_end = read_s32(offset + 0x0c,sf);
|
||||
if (h.loop_start > h.loop_end || h.loop_end > h.num_samples) return NULL;
|
||||
h.codec = read_s32(offset + 0x10,sf);
|
||||
if (h.codec > 0x09) return NULL;
|
||||
h.sample_rate = read_s32(offset + 0x14,sf);
|
||||
if (h.sample_rate > 48000 || h.sample_rate < 0) return NULL;
|
||||
|
||||
@ -206,14 +211,25 @@ VGMSTREAM* init_vgmstream_squeaksample(STREAMFILE* sf) {
|
||||
h.external_data = (h.data_offset & 0xF0000000);
|
||||
h.data_offset = h.data_offset & 0x0FFFFFFF;
|
||||
|
||||
/* absolute offsets, should read for each channel but simplify
|
||||
* (also channels may have padding, but files end with no padding) */
|
||||
/* each channel has its own info but mostly repeats (data may have padding, but files end with no padding) */
|
||||
{
|
||||
int separation = 0;
|
||||
switch(h.codec) {
|
||||
case 0xFFFE0001:
|
||||
case 0x0001FFFE:
|
||||
case 0x01660001: separation = 0x68; break;
|
||||
default: separation = 0x2c; break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < h.channels; i++) {
|
||||
h.data_offsets[i] = read_u32le(offset + 0x04 + i * separation, sf) & 0x0FFFFFFF;
|
||||
h.coef_offsets[i] = read_u32le(offset + 0x28 + i * separation, sf);
|
||||
}
|
||||
|
||||
if (h.channels > 1) {
|
||||
int separation = h.codec == 0xFFFE0001 ? 0x68 : 0x2c;
|
||||
uint32_t data_offset = read_u32le(offset + 0x04 + 1 * separation, sf) & 0x0FFFFFFF;
|
||||
uint32_t coef_offset = read_u32le(offset + 0x28 + 1 * separation, sf);
|
||||
h.interleave = data_offset - h.data_offset; /* distance */
|
||||
h.coef_spacing = coef_offset - h.coef_offset;
|
||||
h.interleave = h.data_offsets[1] - h.data_offsets[0];
|
||||
h.coef_spacing = h.coef_offsets[1] - h.coef_offsets[0];
|
||||
}
|
||||
}
|
||||
|
||||
switch(h.codec) {
|
||||
@ -223,8 +239,11 @@ VGMSTREAM* init_vgmstream_squeaksample(STREAMFILE* sf) {
|
||||
case 0x07: h.type = PSX; break; /* How to Train Your Dragon 2 (PS3), Falling Skies The Game (PS3) */
|
||||
case 0x08: /* (same as below for unlooped audio) */
|
||||
case 0x09: h.type = IMA; break; /* Scooby-Doo! First Frights (DS), Turbo Super Stunt Squad (DS) */
|
||||
case 0xFFFE0001: h.type = h.big_endian ? PCM16BE : PCM16LE; break; /* Falling Skies The Game (X360) */
|
||||
case 0xFFFE0001: h.type = PCM16BE; break; /* Falling Skies The Game (X360) */
|
||||
case 0x0001FFFE: h.type = PCM16LE; break; /* Scooby Doo and the Spooky Swamp (PC), Monster High: New Ghoul in School (PC) */
|
||||
case 0x01660001: h.type = XMA2; break; /* Rise of the Guardians (X360) */
|
||||
default:
|
||||
VGM_LOG("SqueakSample: unknown codec %x\n", h.codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -295,6 +314,7 @@ fail:
|
||||
static VGMSTREAM* init_vgmstream_squeak_common(STREAMFILE* sf, squeak_header_t* h) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sb = NULL;
|
||||
STREAMFILE* sf_body = NULL;
|
||||
|
||||
/* common */
|
||||
int loop_flag = h->loop_end > 0;
|
||||
@ -306,6 +326,7 @@ static VGMSTREAM* init_vgmstream_squeak_common(STREAMFILE* sf, squeak_header_t*
|
||||
if (!sb) goto fail;
|
||||
}
|
||||
|
||||
sf_body = sb ? sb : sf;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(h->channels, loop_flag);
|
||||
@ -334,12 +355,13 @@ static VGMSTREAM* init_vgmstream_squeak_common(STREAMFILE* sf, squeak_header_t*
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = h->interleave; /* not 0x02 */
|
||||
|
||||
break;
|
||||
|
||||
case PCM16BE:
|
||||
vgmstream->coding_type = coding_PCM16BE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = h->interleave; /* not 0x02 */
|
||||
|
||||
/* etbl_offset may set offsets to RIFF fmts per channel) */
|
||||
break;
|
||||
|
||||
case PSX:
|
||||
@ -358,7 +380,7 @@ static VGMSTREAM* init_vgmstream_squeak_common(STREAMFILE* sf, squeak_header_t*
|
||||
vgmstream->coding_type = coding_MS_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
//vgmstream->interleave_block_size = h->interleave; /* unused? (mono) */
|
||||
vgmstream->frame_size = 0x20;
|
||||
vgmstream->frame_size = h->codec == 0x04 ? 0x400 : 0x20;
|
||||
break;
|
||||
|
||||
case IMA:
|
||||
@ -370,8 +392,46 @@ static VGMSTREAM* init_vgmstream_squeak_common(STREAMFILE* sf, squeak_header_t*
|
||||
h->data_offset += 0x04;
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case XMA2: {
|
||||
/* uses separate mono streams */
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
for (int i = 0; i < h->channels; i++) {
|
||||
uint32_t offset = h->data_offsets[i];
|
||||
uint32_t next_offset = (i + 1 == h->channels) ? get_streamfile_size(sf_body) : h->data_offsets[i+1];
|
||||
uint32_t data_size = next_offset - offset;
|
||||
int layer_channels = 1;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_xma2_raw(sf_body, offset, data_size, h->num_samples, layer_channels, h->sample_rate, 0, 0);
|
||||
if (!layered_add_codec(vgmstream, 0, layer_channels))
|
||||
goto fail;
|
||||
}
|
||||
if (!layered_add_done(vgmstream))
|
||||
goto fail;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case VORBIS:
|
||||
vgmstream->codec_data = init_ogg_vorbis(sf_body, h->data_offset, 0, NULL);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_OGG_VORBIS;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
break;
|
||||
#endif
|
||||
#ifdef VGM_USE_SPEEX
|
||||
case SPEEX: {
|
||||
vgmstream->codec_data = init_speex_torus(h->channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_SPEEX;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
vgm_logi("RAWI: unknown codec %x (report)\n", h->codec);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
#ifndef _UTIL_ENDIAN_H
|
||||
#define _UTIL_ENDIAN_H
|
||||
#ifndef _ENDIANNESS_H
|
||||
#define _ENDIANNESS_H
|
||||
|
||||
#include "../streamfile.h"
|
||||
#include "reader_get.h"
|
||||
#include "reader_sf.h"
|
||||
|
||||
typedef uint64_t (*read_u64_t)(off_t, STREAMFILE*);
|
||||
typedef int64_t (*read_s64_t)(off_t, STREAMFILE*);
|
||||
typedef uint32_t (*read_u32_t)(off_t, STREAMFILE*);
|
||||
typedef int32_t (*read_s32_t)(off_t, STREAMFILE*);
|
||||
typedef uint16_t (*read_u16_t)(off_t, STREAMFILE*);
|
||||
|
71
src/util/layout_utils.c
Normal file
71
src/util/layout_utils.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include "layout_utils.h"
|
||||
|
||||
#include "../vgmstream.h"
|
||||
#include "../layout/layout.h"
|
||||
|
||||
bool layered_add_codec(VGMSTREAM* vs, int layers, int layer_channels) {
|
||||
if (!vs || !vs->codec_data) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!layer_channels)
|
||||
layer_channels = 1;
|
||||
if (!layers)
|
||||
layers = vs->channels / layer_channels;
|
||||
|
||||
int i;
|
||||
layered_layout_data* data;
|
||||
|
||||
switch(vs->layout_type) {
|
||||
case layout_segmented: //to be improved
|
||||
goto fail;
|
||||
|
||||
case layout_layered:
|
||||
data = vs->layout_data;
|
||||
|
||||
i = data->curr_layer;
|
||||
break;
|
||||
|
||||
default:
|
||||
data = init_layout_layered(layers);
|
||||
if (!data) goto fail;
|
||||
vs->layout_data = data;
|
||||
vs->layout_type = layout_layered;
|
||||
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
data->layers[i] = allocate_vgmstream(layer_channels, vs->loop_flag);
|
||||
if (!data->layers[i]) goto fail;
|
||||
|
||||
data->layers[i]->meta_type = vs->meta_type;
|
||||
data->layers[i]->sample_rate = vs->sample_rate;
|
||||
data->layers[i]->num_samples = vs->num_samples;
|
||||
data->layers[i]->loop_start_sample = vs->loop_start_sample;
|
||||
data->layers[i]->loop_end_sample = vs->loop_end_sample;
|
||||
|
||||
data->layers[i]->codec_data = vs->codec_data;
|
||||
if (!data->layers[i]->codec_data) goto fail;
|
||||
data->layers[i]->coding_type = vs->coding_type;
|
||||
data->layers[i]->layout_type = layout_none;
|
||||
|
||||
vs->codec_data = NULL; /* moved to layer, don't hold it */
|
||||
|
||||
data->curr_layer++;
|
||||
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool layered_add_done(VGMSTREAM* vs) {
|
||||
//TODO: some extra checks/setup?
|
||||
|
||||
if (!setup_layout_layered(vs->layout_data))
|
||||
goto fail;
|
||||
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
12
src/util/layout_utils.h
Normal file
12
src/util/layout_utils.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _LAYOUTS_UTIL_H
|
||||
#define _LAYOUTS_UTIL_H
|
||||
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* add a new layer from codec data (setups layout if needed)
|
||||
* codec is passed in the vs for easier free/etc control */
|
||||
bool layered_add_codec(VGMSTREAM* vs, int layers, int layer_channels);
|
||||
|
||||
/* call when done adding layers */
|
||||
bool layered_add_done(VGMSTREAM* vs);
|
||||
#endif
|
@ -103,7 +103,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_lp_ap_lep,
|
||||
init_vgmstream_sdt,
|
||||
init_vgmstream_aix,
|
||||
init_vgmstream_ngc_tydsp,
|
||||
init_vgmstream_wvs_xbox,
|
||||
init_vgmstream_wvs_ngc,
|
||||
init_vgmstream_dc_str,
|
||||
@ -129,7 +128,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_ps2_mihb,
|
||||
init_vgmstream_ngc_pdt_split,
|
||||
init_vgmstream_ngc_pdt,
|
||||
init_vgmstream_mus_krone,
|
||||
init_vgmstream_mus_krome,
|
||||
init_vgmstream_dc_asd,
|
||||
init_vgmstream_spsd,
|
||||
init_vgmstream_rsd,
|
||||
@ -170,7 +169,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_zsd,
|
||||
init_vgmstream_vgs_ps,
|
||||
init_vgmstream_redspark,
|
||||
init_vgmstream_ivaud,
|
||||
init_vgmstream_wii_wsd,
|
||||
init_vgmstream_dsp_ndp,
|
||||
init_vgmstream_ps2_sps,
|
||||
@ -284,7 +282,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_ubi_raki,
|
||||
init_vgmstream_pasx,
|
||||
init_vgmstream_xma,
|
||||
init_vgmstream_sxd,
|
||||
init_vgmstream_sndx,
|
||||
init_vgmstream_ogl,
|
||||
init_vgmstream_mc3,
|
||||
init_vgmstream_ghs,
|
||||
@ -523,6 +521,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_pwb,
|
||||
init_vgmstream_squeakstream,
|
||||
init_vgmstream_squeaksample,
|
||||
init_vgmstream_snds,
|
||||
|
||||
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
|
||||
init_vgmstream_scd_pcm,
|
||||
@ -533,6 +532,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_mic_koei,
|
||||
init_vgmstream_seb,
|
||||
init_vgmstream_tgc,
|
||||
init_vgmstream_ivaud,
|
||||
/* need companion files */
|
||||
init_vgmstream_pos,
|
||||
init_vgmstream_sli_loops,
|
||||
|
@ -273,6 +273,7 @@ typedef struct {
|
||||
int input_channels; /* internal buffer channels */
|
||||
int output_channels; /* resulting channels (after mixing, if applied) */
|
||||
int external_looping; /* don't loop using per-layer loops, but layout's own looping */
|
||||
int curr_layer; /* helper */
|
||||
} layered_layout_data;
|
||||
|
||||
|
||||
|
@ -257,7 +257,7 @@ typedef enum {
|
||||
meta_DSP_SADB, /* .sad */
|
||||
meta_DSP_WSI, /* .wsi */
|
||||
meta_IDSP_TT, /* Traveller's Tales games */
|
||||
meta_MUS_KRONE,
|
||||
meta_MUS_KROME,
|
||||
meta_DSP_WII_WSD, /* Phantom Brave (WII) */
|
||||
meta_WII_NDP, /* Vertigo (Wii) */
|
||||
meta_DSP_YGO, /* Konami: Yu-Gi-Oh! The Falsebound Kingdom (NGC), Hikaru no Go 3 (NGC) */
|
||||
@ -344,7 +344,6 @@ typedef enum {
|
||||
meta_PS2_VAS, /* Pro Baseball Spirits 5 */
|
||||
meta_LP_AP_LEP,
|
||||
meta_SDT, /* Baldur's Gate - Dark Alliance */
|
||||
meta_NGC_TYDSP, /* Ty - The Tasmanian Tiger */
|
||||
meta_DC_STR, /* SEGA Stream Asset Builder */
|
||||
meta_DC_STR_V2, /* variant of SEGA Stream Asset Builder */
|
||||
meta_SAP,
|
||||
@ -529,7 +528,7 @@ typedef enum {
|
||||
meta_ASTB,
|
||||
meta_WWISE_RIFF, /* Audiokinetic Wwise RIFF/RIFX */
|
||||
meta_UBI_RAKI, /* Ubisoft RAKI header (Rayman Legends, Just Dance 2017) */
|
||||
meta_SXD, /* Sony SXD (Gravity Rush, Freedom Wars PSV) */
|
||||
meta_SNDX,
|
||||
meta_OGL, /* Shin'en Wii/WiiU (Jett Rocket (Wii), FAST Racing NEO (WiiU)) */
|
||||
meta_MC3, /* Paradigm games (T3 PS2, MX Rider PS2, MI: Operation Surma PS2) */
|
||||
meta_GHS,
|
||||
@ -537,7 +536,7 @@ typedef enum {
|
||||
meta_MTA2,
|
||||
meta_XA_XA30,
|
||||
meta_XA_04SW,
|
||||
meta_TXTH, /* generic text header */
|
||||
meta_TXTH,
|
||||
meta_SK_AUD, /* Silicon Knights .AUD (Eternal Darkness GC) */
|
||||
meta_AHX,
|
||||
meta_STMA,
|
||||
@ -700,6 +699,7 @@ typedef enum {
|
||||
meta_AWD,
|
||||
meta_SQUEAKSTREAM,
|
||||
meta_SQUEAKSAMPLE,
|
||||
meta_SNDS,
|
||||
|
||||
} meta_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user