mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 23:10:10 +01:00
commit
f4551cda37
@ -87,8 +87,8 @@ mode = layers
|
||||
```
|
||||
|
||||
|
||||
### Channel mapping
|
||||
TXTP can swap channels for custom channel mappings. Note that channel masking applies after mappings. Format is:
|
||||
### Channel swapping/mapping
|
||||
TXTP can swap channels for custom channel mappings. It does "swapping" rather than simpler "mapping" since vgmstream can't read a format's mappings or guess which channel is which. Format is:
|
||||
```
|
||||
#ch1 = first
|
||||
file1.ext#m2-3 # "FL BL FR BR" to "FL FR BL BR"
|
||||
@ -96,6 +96,7 @@ file1.ext#m2-3 # "FL BL FR BR" to "FL FR BL BR"
|
||||
#do note the order specified affects swapping
|
||||
file2.ext#m2-3,4-5,4-6 # ogg "FL CN FR BL BR SB" to wav "FL FR CN SB BL BR"
|
||||
```
|
||||
Note that channel masking applies after mappings.
|
||||
|
||||
|
||||
### Custom play settings
|
||||
|
@ -9,8 +9,9 @@ static const int EA_XA_TABLE[20] = {
|
||||
0, -1, -3, -4
|
||||
};
|
||||
|
||||
/* EA-XAS, evolution of EA-XA and cousin of MTA2. Layout: blocks of 0x4c per channel (128 samples),
|
||||
* divided into 4 headers + 4 vertical groups of 15 bytes (for parallelism?).
|
||||
/* EA-XAS, evolution of EA-XA and cousin of MTA2. From FFmpeg (general info) + MTA2 (layout) + EA-XA (decoding)
|
||||
*
|
||||
* Layout: blocks of 0x4c per channel (128 samples), divided into 4 headers + 4 vertical groups of 15 bytes (for parallelism?).
|
||||
* To simplify, always decodes the block and discards unneeded samples, so doesn't use external hist. */
|
||||
void decode_ea_xas(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int group, row, i;
|
||||
|
@ -151,15 +151,22 @@ void free_hca(hca_codec_data * data) {
|
||||
}
|
||||
|
||||
|
||||
#define HCA_KEY_MAX_BLANK_FRAMES 15 /* ignored up to N blank frames (not uncommon to have ~10, if more something is off) */
|
||||
#define HCA_KEY_MAX_TEST_FRAMES 10 /* 5~15 should be enough, but mostly silent or badly mastered files may need more */
|
||||
#define HCA_KEY_MAX_ACCEPTABLE_SCORE 150 /* more is unlikely to work correctly, 10~30 isn't uncommon */
|
||||
/* arbitrary scale to simplify score comparisons */
|
||||
#define HCA_KEY_SCORE_SCALE 10
|
||||
/* ignores beginning frames (~10 is not uncommon, Dragalia Lost vocal layers have lots) */
|
||||
#define HCA_KEY_MAX_SKIP_BLANKS 1200
|
||||
/* 5~15 should be enough, but almost silent or badly mastered files may need tweaks */
|
||||
#define HCA_KEY_MIN_TEST_FRAMES 5
|
||||
#define HCA_KEY_MAX_TEST_FRAMES 10
|
||||
/* score of 10~30 isn't uncommon in a single frame, too many frames over that is unlikely */
|
||||
#define HCA_KEY_MAX_FRAME_SCORE 150
|
||||
#define HCA_KEY_MAX_TOTAL_SCORE (HCA_KEY_MAX_TEST_FRAMES * 50*HCA_KEY_SCORE_SCALE)
|
||||
|
||||
/* Test a number of frames if key decrypts correctly.
|
||||
* Returns score: <0: error/wrong, 0: unknown/silent file, >0: good (the closest to 1 the better). */
|
||||
int test_hca_key(hca_codec_data * data, unsigned long long keycode) {
|
||||
size_t test_frame = 0, current_frame = 0, blank_frames = 0;
|
||||
int total_score = 0;
|
||||
size_t test_frames = 0, current_frame = 0, blank_frames = 0;
|
||||
int total_score = 0, found_regular_frame = 0;
|
||||
const unsigned int blockSize = data->info.blockSize;
|
||||
|
||||
/* Due to the potentially large number of keys this must be tuned for speed.
|
||||
@ -168,43 +175,56 @@ int test_hca_key(hca_codec_data * data, unsigned long long keycode) {
|
||||
|
||||
clHCA_SetKey(data->handle, keycode);
|
||||
|
||||
while (test_frame < HCA_KEY_MAX_TEST_FRAMES && current_frame < data->info.blockCount) {
|
||||
/* Test up to N non-blank frames or until total frames. */
|
||||
/* A final score of 0 (=silent) is only possible for short files with all blank frames */
|
||||
|
||||
while (test_frames < HCA_KEY_MAX_TEST_FRAMES && current_frame < data->info.blockCount) {
|
||||
off_t offset = data->info.headerSize + current_frame * blockSize;
|
||||
int score;
|
||||
size_t bytes;
|
||||
|
||||
/* read frame */
|
||||
/* read and test frame */
|
||||
bytes = read_streamfile(data->data_buffer, offset, blockSize, data->streamfile);
|
||||
if (bytes != blockSize) {
|
||||
total_score = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* test frame */
|
||||
score = clHCA_TestBlock(data->handle, (void*)(data->data_buffer), blockSize);
|
||||
if (score < 0) {
|
||||
if (score < 0 || score > HCA_KEY_MAX_FRAME_SCORE) {
|
||||
total_score = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
current_frame++;
|
||||
|
||||
/* skip blank block at the beginning */
|
||||
if (score == 0 && blank_frames < HCA_KEY_MAX_BLANK_FRAMES) {
|
||||
/* ignore silent frames at the beginning, up to a point */
|
||||
if (score == 0 && blank_frames < HCA_KEY_MAX_SKIP_BLANKS && !found_regular_frame) {
|
||||
blank_frames++;
|
||||
continue;
|
||||
}
|
||||
|
||||
test_frame++;
|
||||
found_regular_frame = 1;
|
||||
test_frames++;
|
||||
|
||||
/* scale values to make scores of perfect frames more detectable */
|
||||
switch(score) {
|
||||
case 1: score = 1; break;
|
||||
case 0: score = 3*HCA_KEY_SCORE_SCALE; break; /* blanks after non-blacks aren't very trustable */
|
||||
default: score = score*HCA_KEY_SCORE_SCALE;
|
||||
}
|
||||
|
||||
total_score += score;
|
||||
|
||||
/* too far, don't bother checking more frames */
|
||||
if (total_score > HCA_KEY_MAX_ACCEPTABLE_SCORE)
|
||||
|
||||
/* don't bother checking more frames, other keys will get better scores */
|
||||
if (total_score > HCA_KEY_MAX_TOTAL_SCORE)
|
||||
break;
|
||||
}
|
||||
//;VGM_LOG("HCA KEY: blanks=%i, tests=%i, score=%i\n", blank_frames, test_frames, total_score);
|
||||
|
||||
/* signal best possible score */
|
||||
if (total_score > 0 && total_score <= HCA_KEY_MAX_TEST_FRAMES) {
|
||||
/* signal best possible score (many perfect frames and few blank frames) */
|
||||
if (test_frames > HCA_KEY_MIN_TEST_FRAMES && total_score > 0 && total_score <= test_frames) {
|
||||
total_score = 1;
|
||||
}
|
||||
|
||||
|
@ -113,20 +113,28 @@ void decode_mta2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
frame_size = read_16bitBE(stream->offset+0x06,stream->streamfile); /* not including this header */
|
||||
/* 0x08(8): null */
|
||||
|
||||
/* EOF: 0-fill buffer (or, as track_channels = 0 > divs by 0) */
|
||||
if (num_track < 0) {
|
||||
|
||||
VGM_ASSERT(frame_size == 0, "MTA2: empty frame at %x\n", (uint32_t)stream->offset);
|
||||
/* frame_size 0 means silent/empty frame (rarely found near EOF for one track but not others)
|
||||
* negative track only happens for truncated files (EOF) */
|
||||
if (frame_size == 0 || num_track < 0) {
|
||||
for (i = 0; i < samples_to_do; i++)
|
||||
outbuf[i * channelspacing] = 0;
|
||||
stream->offset += 0x10;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
track_channels = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((channel_layout >> i) & 0x01)
|
||||
track_channels++;
|
||||
}
|
||||
|
||||
if (track_channels == 0) { /* bad data, avoid div by 0 */
|
||||
VGM_LOG("track_channels 0 at %x\n", (uint32_t)stream->offset);
|
||||
return;
|
||||
}
|
||||
|
||||
/* assumes tracks channels are divided evenly in all tracks (ex. not 2ch + 1ch + 1ch) */
|
||||
if (channel / track_channels == num_track)
|
||||
break; /* channel belongs to this track */
|
||||
|
@ -129,7 +129,7 @@ static const char* extension_list[] = {
|
||||
"e4x",
|
||||
"eam",
|
||||
"eda", //txth/reserved [Project Eden (PS2)]
|
||||
"emff",
|
||||
"emff", //fake extension for .mul (to be removed)
|
||||
"enm",
|
||||
"eno",
|
||||
"ens",
|
||||
@ -175,6 +175,7 @@ static const char* extension_list[] = {
|
||||
"idx",
|
||||
"ikm",
|
||||
"ild",
|
||||
"imc",
|
||||
"int",
|
||||
"isd",
|
||||
"isws",
|
||||
@ -249,6 +250,7 @@ static const char* extension_list[] = {
|
||||
"msvp",
|
||||
"mta2",
|
||||
"mtaf",
|
||||
"mul",
|
||||
"mus",
|
||||
"musc",
|
||||
"musx",
|
||||
@ -681,9 +683,8 @@ static const layout_info layout_info_list[] = {
|
||||
{layout_blocked_ws_aud, "blocked (Westwood Studios .aud)"},
|
||||
{layout_blocked_matx, "blocked (Matrix .matx)"},
|
||||
{layout_blocked_dec, "blocked (DEC)"},
|
||||
{layout_blocked_vs, "blocked (vs)"},
|
||||
{layout_blocked_emff_ps2, "blocked (EMFF PS2)"},
|
||||
{layout_blocked_emff_ngc, "blocked (EMFF NGC)"},
|
||||
{layout_blocked_vs, "blocked (Melbourne House VS)"},
|
||||
{layout_blocked_mul, "blocked (MUL)"},
|
||||
{layout_blocked_gsb, "blocked (GSB)"},
|
||||
{layout_blocked_thp, "blocked (THP Movie Audio)"},
|
||||
{layout_blocked_filp, "blocked (FILP)"},
|
||||
@ -692,7 +693,7 @@ static const layout_info layout_info_list[] = {
|
||||
{layout_blocked_bdsp, "blocked (BDSP)"},
|
||||
{layout_blocked_ivaud, "blocked (IVAUD)"},
|
||||
{layout_blocked_ps2_iab, "blocked (IAB)"},
|
||||
{layout_blocked_ps2_strlr, "blocked (The Bouncer STR)"},
|
||||
{layout_blocked_vs_str, "blocked (STR VS)"},
|
||||
{layout_blocked_rws, "blocked (RWS)"},
|
||||
{layout_blocked_hwas, "blocked (HWAS)"},
|
||||
{layout_blocked_tra, "blocked (TRA)"},
|
||||
@ -706,7 +707,7 @@ static const layout_info layout_info_list[] = {
|
||||
{layout_blocked_sthd, "blocked (STHD)"},
|
||||
{layout_blocked_h4m, "blocked (H4M)"},
|
||||
{layout_blocked_xa_aiff, "blocked (XA AIFF)"},
|
||||
{layout_blocked_vs_ffx, "blocked (Square VS)"},
|
||||
{layout_blocked_vs_square, "blocked (Square VS)"},
|
||||
};
|
||||
|
||||
static const meta_info meta_info_list[] = {
|
||||
@ -832,7 +833,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_NGC_WVS, "Metal Arms WVS Header (GameCube)"},
|
||||
{meta_XBOX_MATX, "assumed Matrix file by .matx extension"},
|
||||
{meta_DEC, "Falcom DEC RIFF header"},
|
||||
{meta_VS, "Men in Black VS Header"},
|
||||
{meta_VS, "Melbourne House .VS header"},
|
||||
{meta_DC_STR, "Sega Stream Asset Builder header"},
|
||||
{meta_DC_STR_V2, "variant of Sega Stream Asset Builder header"},
|
||||
{meta_XBOX_XMU, "XMU header"},
|
||||
@ -888,8 +889,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_VGS, "Guitar Hero VGS Header"},
|
||||
{meta_DC_DCSW_DCS, "Evil Twin DCS file with helper"},
|
||||
{meta_WII_SMP, "SMP DSP Header"},
|
||||
{meta_EMFF_PS2, "Eidos Music File Format Header"},
|
||||
{meta_EMFF_NGC, "Eidos Music File Format Header"},
|
||||
{meta_MUL, "Crystal Dynamics .MUL header"},
|
||||
{meta_THP, "THP Movie File Format Header"},
|
||||
{meta_STS_WII, "Shikigami no Shiro (WII) Header"},
|
||||
{meta_PS2_P2BT, "Pop'n'Music 7 Header"},
|
||||
@ -908,7 +908,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_ADS, "dhSS Header"},
|
||||
{meta_PS2_MCG, "Gunvari MCG Header"},
|
||||
{meta_ZSD, "ZSD Header"},
|
||||
{meta_RedSpark, "RedSpark Header"},
|
||||
{meta_REDSPARK, "RedSpark Header"},
|
||||
{meta_IVAUD, "Rockstar .ivaud header"},
|
||||
{meta_DSP_WII_WSD, ".WSD header"},
|
||||
{meta_WII_NDP, "Icon Games NDP header"},
|
||||
@ -986,7 +986,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_X360_TRA, "Terminal Reality .TRA raw header"},
|
||||
{meta_PS2_VGS, "Princess Soft VGS header"},
|
||||
{meta_PS2_IAB, "Runtime .IAB header"},
|
||||
{meta_PS2_STRLR, "The Bouncer STR header"},
|
||||
{meta_VS_STR, "Square .VS STR* header"},
|
||||
{meta_LSF_N1NJ4N, ".lsf !n1nj4n header"},
|
||||
{meta_VAWX, "feelplus VAWX header"},
|
||||
{meta_PC_SNDS, "assumed Heavy Iron IMA by .snds extension"},
|
||||
@ -1126,7 +1126,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_XWMA, "Microsoft XWMA RIFF header"},
|
||||
{meta_VA3, "Konami VA3 header" },
|
||||
{meta_XOPUS, "Exient XOPUS header"},
|
||||
{meta_VS_FFX, "Square VS header"},
|
||||
{meta_VS_SQUARE, "Square VS header"},
|
||||
{meta_NWAV, "Chunsoft NWAV header"},
|
||||
{meta_XPCM, "Circus XPCM header"},
|
||||
{meta_MSF_TAMASOFT, "Tama-Soft MSF header"},
|
||||
@ -1134,6 +1134,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_ZSND, "Vicarious Visions ZSND header"},
|
||||
{meta_DSP_ADPCMX, "AQUASTYLE ADPY header"},
|
||||
{meta_OGG_OPUS, "Ogg Opus header"},
|
||||
{meta_IMC, "iNiS .IMC header"},
|
||||
|
||||
};
|
||||
|
||||
|
@ -127,11 +127,8 @@ void block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
case layout_blocked_dec:
|
||||
block_update_dec(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_emff_ps2:
|
||||
block_update_emff_ps2(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_emff_ngc:
|
||||
block_update_emff_ngc(block_offset,vgmstream);
|
||||
case layout_blocked_mul:
|
||||
block_update_mul(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_gsb:
|
||||
block_update_gsb(block_offset,vgmstream);
|
||||
@ -166,8 +163,8 @@ void block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
case layout_blocked_ps2_iab:
|
||||
block_update_ps2_iab(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_ps2_strlr:
|
||||
block_update_ps2_strlr(block_offset,vgmstream);
|
||||
case layout_blocked_vs_str:
|
||||
block_update_vs_str(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_rws:
|
||||
block_update_rws(block_offset,vgmstream);
|
||||
@ -205,8 +202,8 @@ void block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
case layout_blocked_xa_aiff:
|
||||
block_update_xa_aiff(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_vs_ffx:
|
||||
block_update_vs_ffx(block_offset,vgmstream);
|
||||
case layout_blocked_vs_square:
|
||||
block_update_vs_square(block_offset,vgmstream);
|
||||
break;
|
||||
default: /* not a blocked layout */
|
||||
break;
|
||||
|
@ -1,34 +0,0 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_emff_ps2(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bitLE(
|
||||
vgmstream->current_block_offset+0x10,
|
||||
vgmstream->ch[0].streamfile);
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size+0x20;
|
||||
vgmstream->current_block_size/=vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+0x20+(vgmstream->current_block_size*i);
|
||||
}
|
||||
}
|
||||
|
||||
void block_update_emff_ngc(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bitBE(
|
||||
vgmstream->current_block_offset+0x20,
|
||||
vgmstream->ch[0].streamfile);
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size+0x40;
|
||||
vgmstream->current_block_size/=vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+0x40+(vgmstream->current_block_size*i);
|
||||
}
|
||||
}
|
||||
|
50
src/layout/blocked_mul.c
Normal file
50
src/layout/blocked_mul.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* process headered blocks with sub-headers */
|
||||
void block_update_mul(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
|
||||
int i, block_type;
|
||||
size_t block_size, block_header, data_size, data_header;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_32bitBE : read_32bitLE;
|
||||
|
||||
block_type = read_32bit(block_offset + 0x00,streamFile);
|
||||
block_size = read_32bit(block_offset + 0x04,streamFile); /* not including main header */
|
||||
|
||||
switch(vgmstream->coding_type) {
|
||||
case coding_NGC_DSP:
|
||||
block_header = 0x20;
|
||||
data_header = 0x20;
|
||||
break;
|
||||
default:
|
||||
block_header = 0x10;
|
||||
data_header = 0x10;
|
||||
break;
|
||||
}
|
||||
|
||||
if (block_type == 0x00 && block_size == 0) {
|
||||
/* oddity in some vid+audio files? bad extraction? */
|
||||
block_header = 0x10;
|
||||
data_header = 0x00;
|
||||
data_size = 0;
|
||||
}
|
||||
if (block_type == 0x00 && block_size != 0) {
|
||||
/* read audio sub-header */
|
||||
data_size = read_32bit(block_offset + block_header + 0x00,streamFile);
|
||||
}
|
||||
else {
|
||||
/* non-audio or empty audio block */
|
||||
data_header = 0x00;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = data_size / vgmstream->channels;
|
||||
vgmstream->next_block_offset = block_offset + block_header + block_size;
|
||||
|
||||
for (i = 0; i < vgmstream->channels; i++) {
|
||||
vgmstream->ch[i].offset = block_offset + block_header + data_header + vgmstream->current_block_size*i;
|
||||
//VGM_LOG("ch%i of=%lx\n", i, vgmstream->ch[i].offset);
|
||||
}
|
||||
//getchar();
|
||||
}
|
@ -1,17 +1,16 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
/* mini-blocks of size + data */
|
||||
void block_update_vs(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
|
||||
int i;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bitLE(
|
||||
vgmstream->current_block_offset,
|
||||
vgmstream->ch[0].streamfile);
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size + 0x4;
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset + 0x4;
|
||||
if(i==0) block_offset=vgmstream->next_block_offset;
|
||||
for (i = 0; i < vgmstream->channels; i++) {
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bitLE(vgmstream->current_block_offset,streamFile);
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size + 0x04;
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset + 0x04;
|
||||
if (i == 0) block_offset=vgmstream->next_block_offset;
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* Square "VS" headered blocks */
|
||||
void block_update_vs_ffx(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
void block_update_vs_square(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
size_t block_size = 0x800;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = block_size - 0x20;
|
||||
vgmstream->next_block_offset = block_offset + block_size;
|
||||
vgmstream->next_block_offset = block_offset + block_size*vgmstream->channels;
|
||||
/* 0x08: number of remaning blocks, 0x0c: blocks left */
|
||||
|
||||
for (i = 0; i < vgmstream->channels; i++) {
|
@ -2,7 +2,7 @@
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* The Bouncer STRx blocks, one block per channel when stereo */
|
||||
void block_update_ps2_strlr(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
void block_update_vs_str(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
|
||||
int i;
|
||||
|
@ -21,8 +21,7 @@ void block_update_ws_aud(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_matx(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_dec(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_vs(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_emff_ps2(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_emff_ngc(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_mul(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_gsb(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_xvas(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_thp(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
@ -33,7 +32,7 @@ void block_update_adm(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_bdsp(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_tra(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_ps2_iab(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_ps2_strlr(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_vs_str(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_rws(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_hwas(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_ea_sns(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
@ -46,7 +45,7 @@ void block_update_ea_wve_ad10(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_sthd(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_h4m(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_xa_aiff(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_vs_ffx(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_vs_square(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
/* other layouts */
|
||||
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||
|
@ -525,7 +525,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\emff.c"
|
||||
RelativePath=".\meta\mul.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -619,6 +619,10 @@
|
||||
<File
|
||||
RelativePath=".\meta\nub_idsp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\imc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ios_psnd.c"
|
||||
@ -1175,7 +1179,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_strlr.c"
|
||||
RelativePath=".\meta\vs_str.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -1227,7 +1231,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\vs_ffx.c"
|
||||
RelativePath=".\meta\vs_square.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -2007,7 +2011,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\blocked_vs_ffx.c"
|
||||
RelativePath=".\layout\blocked_vs_square.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -2031,7 +2035,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\blocked_emff.c"
|
||||
RelativePath=".\layout\blocked_mul.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -2079,7 +2083,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\blocked_ps2_strlr.c"
|
||||
RelativePath=".\layout\blocked_vs_str.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
@ -134,7 +134,7 @@
|
||||
<ClCompile Include="coding\mtaf_decoder.c" />
|
||||
<ClCompile Include="coding\mta2_decoder.c" />
|
||||
<ClCompile Include="layout\blocked_ps2_iab.c" />
|
||||
<ClCompile Include="layout\blocked_ps2_strlr.c" />
|
||||
<ClCompile Include="layout\blocked_vs_str.c" />
|
||||
<ClCompile Include="layout\layered.c" />
|
||||
<ClCompile Include="layout\blocked_tra.c" />
|
||||
<ClCompile Include="meta\akb.c" />
|
||||
@ -146,6 +146,7 @@
|
||||
<ClCompile Include="meta\ezw.c" />
|
||||
<ClCompile Include="meta\ffmpeg.c" />
|
||||
<ClCompile Include="meta\g1l.c" />
|
||||
<ClCompile Include="meta\imc.c" />
|
||||
<ClCompile Include="meta\ios_psnd.c" />
|
||||
<ClCompile Include="meta\ktss.c" />
|
||||
<ClCompile Include="meta\lsf.c" />
|
||||
@ -170,7 +171,7 @@
|
||||
<ClCompile Include="meta\mss.c" />
|
||||
<ClCompile Include="meta\ps2_mtaf.c" />
|
||||
<ClCompile Include="meta\ps2_spm.c" />
|
||||
<ClCompile Include="meta\ps2_strlr.c" />
|
||||
<ClCompile Include="meta\vs_str.c" />
|
||||
<ClCompile Include="meta\ps2_wmus.c" />
|
||||
<ClCompile Include="meta\ps3_ivag.c" />
|
||||
<ClCompile Include="meta\ps3_past.c" />
|
||||
@ -251,7 +252,7 @@
|
||||
<ClCompile Include="meta\ea_eaac.c" />
|
||||
<ClCompile Include="meta\ea_wve_au00.c" />
|
||||
<ClCompile Include="meta\ea_wve_ad10.c" />
|
||||
<ClCompile Include="meta\emff.c" />
|
||||
<ClCompile Include="meta\mul.c" />
|
||||
<ClCompile Include="meta\exakt_sc.c" />
|
||||
<ClCompile Include="meta\ffw.c" />
|
||||
<ClCompile Include="meta\flx.c" />
|
||||
@ -398,7 +399,7 @@
|
||||
<ClCompile Include="meta\ps2_vms.c" />
|
||||
<ClCompile Include="meta\ps2_voi.c" />
|
||||
<ClCompile Include="meta\vpk.c" />
|
||||
<ClCompile Include="meta\vs_ffx.c" />
|
||||
<ClCompile Include="meta\vs_square.c" />
|
||||
<ClCompile Include="meta\ps2_wad.c" />
|
||||
<ClCompile Include="meta\ps2_wb.c" />
|
||||
<ClCompile Include="meta\ps2_xa2.c" />
|
||||
@ -546,7 +547,7 @@
|
||||
<ClCompile Include="layout\blocked_awc.c" />
|
||||
<ClCompile Include="layout\blocked_ea_1snh.c" />
|
||||
<ClCompile Include="layout\blocked_vgs.c" />
|
||||
<ClCompile Include="layout\blocked_vs_ffx.c" />
|
||||
<ClCompile Include="layout\blocked_vs_square.c" />
|
||||
<ClCompile Include="layout\blocked_vawx.c" />
|
||||
<ClCompile Include="layout\blocked_xvag.c" />
|
||||
<ClCompile Include="layout\blocked_caf.c" />
|
||||
@ -555,7 +556,7 @@
|
||||
<ClCompile Include="layout\blocked_ea_sns.c" />
|
||||
<ClCompile Include="layout\blocked_ea_wve_au00.c" />
|
||||
<ClCompile Include="layout\blocked_ea_wve_ad10.c" />
|
||||
<ClCompile Include="layout\blocked_emff.c" />
|
||||
<ClCompile Include="layout\blocked_mul.c" />
|
||||
<ClCompile Include="layout\blocked_filp.c" />
|
||||
<ClCompile Include="layout\blocked_gsb.c" />
|
||||
<ClCompile Include="layout\blocked_h4m.c" />
|
||||
|
@ -334,7 +334,7 @@
|
||||
<ClCompile Include="meta\ea_wve_ad10.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\emff.c">
|
||||
<ClCompile Include="meta\mul.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\exakt_sc.c">
|
||||
@ -760,7 +760,7 @@
|
||||
<ClCompile Include="meta\vpk.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\vs_ffx.c">
|
||||
<ClCompile Include="meta\vs_square.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ps2_wad.c">
|
||||
@ -1192,7 +1192,7 @@
|
||||
<ClCompile Include="layout\blocked_vgs.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\blocked_vs_ffx.c">
|
||||
<ClCompile Include="layout\blocked_vs_square.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\blocked_vawx.c">
|
||||
@ -1213,7 +1213,7 @@
|
||||
<ClCompile Include="layout\blocked_ea_sns.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\blocked_emff.c">
|
||||
<ClCompile Include="layout\blocked_mul.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\blocked_filp.c">
|
||||
@ -1303,7 +1303,7 @@
|
||||
<ClCompile Include="meta\ps2_spm.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ps2_strlr.c">
|
||||
<ClCompile Include="meta\vs_str.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\wii_ras.c">
|
||||
@ -1315,7 +1315,7 @@
|
||||
<ClCompile Include="meta\ps2_iab.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\blocked_ps2_strlr.c">
|
||||
<ClCompile Include="layout\blocked_vs_str.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\blocked_ps2_iab.c">
|
||||
@ -1360,6 +1360,9 @@
|
||||
<ClCompile Include="meta\ios_psnd.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\imc.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\pc_adp.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
179
src/meta/emff.c
179
src/meta/emff.c
@ -1,179 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* EMFF - Eidos Music File Format (PS2),
|
||||
Legacy of Kain - Defiance, possibly more... */
|
||||
VGMSTREAM * init_vgmstream_emff_ps2(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int frequency;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("emff",filename_extension(filename))) goto fail;
|
||||
|
||||
/* do some checks on the file, cause we have no magic words to check the header...
|
||||
it seems if 0x800 and 0x804 = 0 then the file has only audio, if 0x800 = 1
|
||||
it has a text section, if both are 1 it's video with a text section included... */
|
||||
if (read_32bitBE(0x800,streamFile) == 0x01000000 || /* "0x01000000" */
|
||||
read_32bitBE(0x804,streamFile) == 0x01000000) /* "0x01000000" */
|
||||
goto fail;
|
||||
|
||||
frequency = read_32bitLE(0x0,streamFile);
|
||||
channel_count = read_32bitLE(0xC,streamFile);
|
||||
|
||||
if (frequency > 48000 ||
|
||||
channel_count > 8) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
loop_flag = (read_32bitLE(0x4,streamFile) != 0xFFFFFFFF);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x800;
|
||||
vgmstream->sample_rate = frequency;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
|
||||
vgmstream->layout_type = layout_blocked_emff_ps2;
|
||||
vgmstream->interleave_block_size = 0x10;
|
||||
vgmstream->meta_type = meta_EMFF_PS2;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calc num_samples */
|
||||
block_update_emff_ps2(start_offset,vgmstream);
|
||||
vgmstream->num_samples = read_32bitLE(0x8,streamFile);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x28,streamFile)-start_offset)*28/16/channel_count;
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x8,streamFile);
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* EMFF - Eidos Music File Format (NGC/WII),
|
||||
found in Tomb Raider Legend/Anniversary/Underworld, possibly more... */
|
||||
VGMSTREAM * init_vgmstream_emff_ngc(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int frequency;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("emff",filename_extension(filename))) goto fail;
|
||||
|
||||
/* do some checks on the file, cause we have no magic words to check the header...
|
||||
it seems if 0x800 and 0x804 = 0 then the file has only audio, if 0x800 = 1
|
||||
it has a text section, if both are 1 it's video with a text section included... */
|
||||
if (read_32bitBE(0x800,streamFile) == 0x00000001 || /* "0x00000001" */
|
||||
read_32bitBE(0x804,streamFile) == 0x00000001) /* "0x00000001" */
|
||||
goto fail;
|
||||
|
||||
frequency = read_32bitBE(0x0,streamFile);
|
||||
channel_count = read_32bitBE(0xC,streamFile);
|
||||
|
||||
if (frequency > 48000 ||
|
||||
channel_count > 8) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
loop_flag = (read_32bitBE(0x4,streamFile) != 0xFFFFFFFF);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x800;
|
||||
vgmstream->sample_rate = frequency;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
|
||||
/* Retrieving coefs and loops, depending on the file layout... */
|
||||
/* Found in Tomb Raider - Legend for GameCube */
|
||||
if (read_32bitBE(0xC8,streamFile) > 0x0) {
|
||||
off_t coef_table[8] = {0xC8,0xF6,0x124,0x152,0x180,0x1AE,0x1DC,0x20A};
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
/* Found in Tomb Raider - Anniversary for WII */
|
||||
} else if (read_32bitBE(0xCC,streamFile) > 0x0) {
|
||||
off_t coef_table[8] = {0xCC,0xFA,0x128,0x156,0x184,0x1B2,0x1E0,0x20E};
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
/* Found in Tomb Raider - Underworld for WII */
|
||||
} else if (read_32bitBE(0x2D0,streamFile) > 0x0) {
|
||||
off_t coef_table[8] = {0x2D0,0x2FE,0x32C,0x35A,0x388,0x3B6,0x3E4,0x412};
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_blocked_emff_ngc;
|
||||
vgmstream->interleave_block_size = 0x10;
|
||||
vgmstream->meta_type = meta_EMFF_NGC;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calc num_samples */
|
||||
block_update_emff_ngc(start_offset,vgmstream);
|
||||
vgmstream->num_samples = read_32bitBE(0x8,streamFile);;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x28,streamFile))*14/8/channel_count;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x8,streamFile);
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -88,8 +88,8 @@ static inline void test_key(hca_codec_data * hca_data, uint64_t key, uint16_t su
|
||||
if (score < 0)
|
||||
return;
|
||||
|
||||
/* score 0 is not trustable, update too if something better is found */
|
||||
if (*best_score < 0 || (score < *best_score && score > 0) || (*best_score == 0 && score == 1)) {
|
||||
/* update if something better is found */
|
||||
if (*best_score <= 0 || (score < *best_score && score > 0)) {
|
||||
*best_score = score;
|
||||
*best_keycode = key;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ static const hcakey_info hcakey_list[] = {
|
||||
// Taga Tame no Alchemist (iOS/Android)
|
||||
{5047159794308}, // 00000497222AAA84
|
||||
|
||||
// Shin Tennis no Ouji-sama: Rising Beat (iOS/Android)
|
||||
// Shin Tennis no Ouji-sama: Rising Beat (iOS/Android) voices?
|
||||
{4902201417679}, // 0000047561F95FCF
|
||||
|
||||
// Kai-ri-Sei Million Arthur (Vita)
|
||||
|
130
src/meta/imc.c
Normal file
130
src/meta/imc.c
Normal file
@ -0,0 +1,130 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .IMC - from iNiS Gitaroo Man (PS2) */
|
||||
VGMSTREAM * init_vgmstream_imc(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count, sample_rate, interleave, blocks;
|
||||
size_t file_size, data_size;
|
||||
|
||||
|
||||
/* checks */
|
||||
/* .imc: extension from the main container */
|
||||
if (!check_extensions(streamFile, "imc"))
|
||||
goto fail;
|
||||
|
||||
channel_count = read_32bitLE(0x00, streamFile);
|
||||
sample_rate = read_32bitLE(0x04, streamFile);
|
||||
interleave = read_32bitLE(0x08, streamFile) * 0x10; /* number of frames in a block */
|
||||
blocks = read_32bitLE(0x0c, streamFile); /* number of interleave blocks (even in mono) */
|
||||
|
||||
file_size = get_streamfile_size(streamFile);
|
||||
loop_flag = 0;
|
||||
start_offset = 0x10;
|
||||
VGM_LOG("3\n");
|
||||
/* extra checks since the header is so simple */
|
||||
if (channel_count < 1 || channel_count > 8 || sample_rate < 22000 || sample_rate > 48000)
|
||||
goto fail;
|
||||
VGM_LOG("4\n");
|
||||
if (interleave*blocks + start_offset != file_size)
|
||||
goto fail;
|
||||
VGM_LOG("5\n");
|
||||
|
||||
/* remove padding (important to play gapless subsongs, happens even for mono) */
|
||||
{
|
||||
off_t min_offset = file_size - interleave;
|
||||
off_t offset = file_size - 0x10;
|
||||
|
||||
data_size = file_size - start_offset;
|
||||
while (offset > min_offset) {
|
||||
if (read_32bitLE(offset, streamFile) != 0)
|
||||
break;
|
||||
data_size -= 0x10*channel_count;
|
||||
offset -= 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_IMC;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = ps_bytes_to_samples(data_size, channel_count);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ****************************************************************************** */
|
||||
|
||||
/* .IMC in containers */
|
||||
VGMSTREAM * init_vgmstream_imc_container(STREAMFILE *streamFile) {
|
||||
VGMSTREAM *vgmstream = NULL;
|
||||
STREAMFILE *temp_streamFile = NULL;
|
||||
off_t header_offset, subfile_offset, next_offset, name_offset;
|
||||
uint32_t flags1, flags2;
|
||||
|
||||
size_t subfile_size;
|
||||
int total_subsongs, target_subsong = streamFile->stream_index;
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "imc"))
|
||||
goto fail;
|
||||
|
||||
total_subsongs = read_32bitLE(0x00, streamFile);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
||||
|
||||
|
||||
header_offset = 0x04 + 0x20*(target_subsong-1);
|
||||
|
||||
name_offset = header_offset + 0x00;
|
||||
//flags1 = (uint32_t)read_32bitLE(header_offset + 0x08, streamFile);
|
||||
/* 0x0c: same for all songs in single .imc but varies between .imc */
|
||||
subfile_offset = read_32bitLE(header_offset + 0x10,streamFile);
|
||||
//flags2 = (uint32_t)read_32bitLE(header_offset + 0x14, streamFile);
|
||||
/* 0x18: same for all songs in single .imc but varies between .imc */
|
||||
/* 0x1c: flags? (0 or 2) */
|
||||
//VGM_LOG("1: %x, %x\n", flags1, flags2);
|
||||
// if (!(flags1 == 0x77DE2A70 || flags1 == 0x77DE2A00 || flags1 == 0x00000020 || flags1 == 0x00000000))
|
||||
// goto fail;
|
||||
// if (!(flags2 == 0x0000F095 || flags2 == 0x0012FA3C))
|
||||
// goto fail;
|
||||
//VGM_LOG("2\n");
|
||||
|
||||
if (target_subsong == total_subsongs) {
|
||||
next_offset = get_streamfile_size(streamFile);
|
||||
}
|
||||
else {
|
||||
next_offset = read_32bitLE(header_offset + 0x20 + 0x10,streamFile);
|
||||
}
|
||||
subfile_size = next_offset - subfile_offset;
|
||||
|
||||
|
||||
temp_streamFile = setup_subfile_streamfile(streamFile, subfile_offset,subfile_size, NULL);
|
||||
if (!temp_streamFile) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_imc(temp_streamFile);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
close_streamfile(temp_streamFile);
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
read_string(vgmstream->stream_name,0x08+1, name_offset,streamFile);
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_streamFile);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -361,8 +361,7 @@ VGMSTREAM * init_vgmstream_dc_dcsw_dcs(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_wii_smp(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_emff_ps2(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_emff_ngc(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_mul(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile);
|
||||
|
||||
@ -401,7 +400,7 @@ VGMSTREAM * init_vgmstream_zsd(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_vgs(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_RedSpark(STREAMFILE *streamFile);
|
||||
VGMSTREAM * init_vgmstream_redspark(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ivaud(STREAMFILE *streamFile);
|
||||
|
||||
@ -534,7 +533,7 @@ VGMSTREAM * init_vgmstream_x360_tra(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_iab(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_strlr(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_vs_str(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_lsf_n1nj4n(STREAMFILE* streamFile);
|
||||
|
||||
@ -802,7 +801,7 @@ VGMSTREAM * init_vgmstream_xwma(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_xopus(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_vs_ffx(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_vs_square(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_msf_banpresto_wmsf(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_msf_banpresto_2msf(STREAMFILE * streamFile);
|
||||
@ -822,4 +821,7 @@ VGMSTREAM * init_vgmstream_ogg_opus(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_nus3audio(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_imc(STREAMFILE * streamFile);
|
||||
VGMSTREAM * init_vgmstream_imc_container(STREAMFILE * streamFile);
|
||||
|
||||
#endif /*_META_H*/
|
||||
|
164
src/meta/mul.c
Normal file
164
src/meta/mul.c
Normal file
@ -0,0 +1,164 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
typedef enum { NONE, PSX, DSP, XBOX } mul_codec;
|
||||
|
||||
/* .MUL - from Crystal Dynamics games [Legacy of Kain: Defiance (PS2), Tomb Raider Underworld (multi)] */
|
||||
VGMSTREAM * init_vgmstream_mul(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset, coefs_offset = 0;
|
||||
int loop_flag, channel_count, sample_rate, num_samples, loop_start;
|
||||
int big_endian;
|
||||
mul_codec codec = NONE;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
||||
|
||||
/* checks */
|
||||
/* .mul: found in the exe, used by the bigfile extractor (Gibbed.TombRaider)
|
||||
* (some files have companion .mus/sam files but seem to be sequences/control stuff)
|
||||
* .(extensionless): filenames as found in the bigfile
|
||||
* .emff: fake extension ('Eidos Music File Format') */
|
||||
if (!check_extensions(streamFile, "mul,,emff"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x10,streamFile) != 0 ||
|
||||
read_32bitBE(0x14,streamFile) != 0 ||
|
||||
read_32bitBE(0x18,streamFile) != 0 ||
|
||||
read_32bitBE(0x1c,streamFile) != 0)
|
||||
goto fail;
|
||||
|
||||
big_endian = guess_endianness32bit(0x00, streamFile);
|
||||
read_32bit = big_endian ? read_32bitBE : read_32bitLE;
|
||||
|
||||
sample_rate = read_32bit(0x00,streamFile);
|
||||
loop_start = read_32bit(0x04,streamFile);
|
||||
num_samples = read_32bit(0x08,streamFile);
|
||||
channel_count = read_32bit(0x0C,streamFile);
|
||||
if (sample_rate < 8000 || sample_rate > 48000 || channel_count > 8)
|
||||
goto fail;
|
||||
/* 0x20: flag when file has non-audio blocks (ignored by the layout) */
|
||||
/* 0x24: same? */
|
||||
/* 0x28: loop offset within audio data (not file offset) */
|
||||
/* 0x2c: some value related to loop? */
|
||||
/* 0x34: id? */
|
||||
/* 0x38+: channel config until ~0x100? (multiple 0x3F800000 depending on the number of channels) */
|
||||
|
||||
/* test known versions (later versions start from 0x24 instead of 0x20) */
|
||||
if (!(read_32bit(0x38,streamFile) == 0x3F800000 ||
|
||||
read_32bit(0x3c,streamFile) == 0x3F800000)) /* Tomb Raider Underworld */
|
||||
goto fail;
|
||||
|
||||
loop_flag = (loop_start >= 0); /* 0xFFFFFFFF when not looping */
|
||||
start_offset = 0x800;
|
||||
|
||||
/* format is pretty limited so we need to guess codec */
|
||||
if (big_endian) {
|
||||
/* test DSP (GC/Wii): check known coef locations */
|
||||
if (read_32bitBE(0xC8,streamFile) != 0) { /* Tomb Raider Legend (GC) */
|
||||
codec = DSP;
|
||||
coefs_offset = 0xC8;
|
||||
}
|
||||
else if (read_32bitBE(0xCC,streamFile) != 0) { /* Tomb Raider Anniversary (Wii) */
|
||||
codec = DSP;
|
||||
coefs_offset = 0xCC;
|
||||
}
|
||||
else if (read_32bitBE(0x2D0,streamFile) != 0) { /* Tomb Raider Underworld (Wii) */
|
||||
codec = DSP;
|
||||
coefs_offset = 0x2D0;
|
||||
}
|
||||
|
||||
// todo test XMA1 (X360): mono streams, each block has 1 sub-blocks of 0x800 packet per channel
|
||||
|
||||
// todo test ? (PS3)
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
off_t offset = start_offset;
|
||||
size_t file_size = get_streamfile_size(streamFile);
|
||||
size_t frame_size;
|
||||
|
||||
/* check first audio frame */
|
||||
while (offset < file_size) {
|
||||
uint32_t block_type = read_32bit(offset+0x00, streamFile);
|
||||
uint32_t block_size = read_32bit(offset+0x04, streamFile);
|
||||
uint32_t data_size = read_32bit(offset+0x10, streamFile);
|
||||
|
||||
if (block_type != 0x00) {
|
||||
offset += 0x10 + block_size;
|
||||
continue; /* not audio */
|
||||
}
|
||||
|
||||
/* test PS-ADPCM (PS2/PSP): flag is always 2 in .mul */
|
||||
frame_size = 0x10;
|
||||
for (i = 0; i < data_size / frame_size; i++) {
|
||||
if (read_8bit(offset + 0x20 + frame_size*i + 0x01, streamFile) != 0x02)
|
||||
break;
|
||||
}
|
||||
if (i == data_size / frame_size) {
|
||||
codec = PSX;
|
||||
break;
|
||||
}
|
||||
|
||||
/* test XBOX-IMA (PC/Xbox): reserved frame header value is always 0 */
|
||||
frame_size = 0x24;
|
||||
for (i = 0; i < data_size / frame_size; i++) {
|
||||
if (read_8bit(offset + 0x20 + frame_size*i + 0x03, streamFile) != 0x00)
|
||||
break;
|
||||
}
|
||||
if (i == data_size / frame_size) {
|
||||
codec = XBOX;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (codec == NONE) {
|
||||
VGM_LOG("MUL: unknown codec\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_MUL;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = num_samples;
|
||||
vgmstream->codec_endian = big_endian;
|
||||
|
||||
switch(codec) {
|
||||
case PSX:
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_mul;
|
||||
break;
|
||||
|
||||
case DSP:
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_blocked_mul;
|
||||
|
||||
dsp_read_coefs_be(vgmstream,streamFile,coefs_offset+0x00,0x2e);
|
||||
dsp_read_hist_be (vgmstream,streamFile,coefs_offset+0x24,0x2e);
|
||||
break;
|
||||
|
||||
case XBOX:
|
||||
vgmstream->coding_type = coding_XBOX_IMA_int;
|
||||
vgmstream->layout_type = layout_blocked_mul;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -13,7 +13,7 @@ static uint32_t find_key(uint32_t firstword) {
|
||||
|
||||
/* RSD - RedSpark (MadWorld)
|
||||
RS3D - RedSpark (Mario & Luigi: Dream Team I fi*/
|
||||
VGMSTREAM * init_vgmstream_RedSpark(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * init_vgmstream_redspark(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
@ -105,7 +105,7 @@ VGMSTREAM * init_vgmstream_RedSpark(STREAMFILE *streamFile) {
|
||||
} else {
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
vgmstream->meta_type = meta_RedSpark;
|
||||
vgmstream->meta_type = meta_REDSPARK;
|
||||
|
||||
|
||||
{
|
||||
|
@ -1,75 +1,52 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* VS (from Men in Black) */
|
||||
/* .VS - from Melbourne House games [Men in Black II (PS2), Grand Prix Challenge (PS2) */
|
||||
VGMSTREAM * init_vgmstream_vs(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int i;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("vs",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0xC8000000) /* "0xC8000000" */
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "vs"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0xC8000000)
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
start_offset = 0x08;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x08;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->interleave_block_size=0x10;
|
||||
vgmstream->meta_type = meta_VS;
|
||||
vgmstream->sample_rate = read_32bitLE(0x04,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_vs;
|
||||
|
||||
#if 0
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x0c,streamFile)-start_offset);
|
||||
}
|
||||
#endif
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
|
||||
vgmstream->layout_type = layout_blocked_vs;
|
||||
vgmstream->meta_type = meta_VS;
|
||||
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
/* calc num_samples */
|
||||
{
|
||||
vgmstream->next_block_offset = start_offset;
|
||||
do {
|
||||
block_update(vgmstream->next_block_offset,vgmstream);
|
||||
vgmstream->num_samples += ps_bytes_to_samples(vgmstream->current_block_size, 1);
|
||||
}
|
||||
while (vgmstream->next_block_offset < get_streamfile_size(streamFile));
|
||||
block_update(start_offset, vgmstream);
|
||||
|
||||
}
|
||||
|
||||
/* Calc num_samples */
|
||||
block_update_vs(start_offset,vgmstream);
|
||||
vgmstream->num_samples=0;
|
||||
|
||||
do {
|
||||
vgmstream->num_samples += vgmstream->current_block_size*28/16;
|
||||
block_update_vs(vgmstream->next_block_offset,vgmstream);
|
||||
} while (vgmstream->next_block_offset<get_streamfile_size(streamFile));
|
||||
|
||||
block_update_vs(start_offset,vgmstream);
|
||||
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* VS - VagStream from Square games [Final Fantasy X (PS2) voices, Unlimited Saga (PS2) voices] */
|
||||
VGMSTREAM * init_vgmstream_vs_ffx(STREAMFILE *streamFile) {
|
||||
/* VS - VagStream from Square games [Final Fantasy X (PS2) voices, Unlimited Saga (PS2) voices, All Star Pro-Wrestling 2/3 (PS2) music] */
|
||||
VGMSTREAM * init_vgmstream_vs_square(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
int channel_count, loop_flag, pitch;
|
||||
int channel_count, loop_flag, pitch, flags;
|
||||
off_t start_offset;
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ VGMSTREAM * init_vgmstream_vs_ffx(STREAMFILE *streamFile) {
|
||||
if (read_32bitBE(0x00,streamFile) != 0x56530000) /* "VS\0\0" */
|
||||
goto fail;
|
||||
|
||||
/* 0x04: null (flags? used in SVS) */
|
||||
flags = read_32bitLE(0x04,streamFile);
|
||||
/* 0x08: block number */
|
||||
/* 0x0c: blocks left in the subfile */
|
||||
pitch = read_32bitLE(0x10,streamFile); /* usually 0x1000 = 48000 */
|
||||
@ -25,8 +25,13 @@ VGMSTREAM * init_vgmstream_vs_ffx(STREAMFILE *streamFile) {
|
||||
/* 0x18: null */
|
||||
/* 0x1c: null */
|
||||
|
||||
if (flags != 0x00 && flags != 0x01) {
|
||||
VGM_LOG("VS: unknown flags\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 1;
|
||||
channel_count = (flags & 1) ? 2 : 1;
|
||||
start_offset = 0x00;
|
||||
|
||||
|
||||
@ -34,10 +39,10 @@ VGMSTREAM * init_vgmstream_vs_ffx(STREAMFILE *streamFile) {
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_VS_FFX;
|
||||
vgmstream->meta_type = meta_VS_SQUARE;
|
||||
vgmstream->sample_rate = round10((48000 * pitch) / 4096); /* needed for rare files */
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_vs_ffx;
|
||||
vgmstream->layout_type = layout_blocked_vs_square;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
@ -3,7 +3,7 @@
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .vs/STRx - from The Bouncer (PS2) */
|
||||
VGMSTREAM * init_vgmstream_ps2_strlr(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * init_vgmstream_vs_str(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
int channel_count, loop_flag;
|
||||
off_t start_offset;
|
||||
@ -29,10 +29,10 @@ VGMSTREAM * init_vgmstream_ps2_strlr(STREAMFILE *streamFile) {
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_PS2_STRLR;
|
||||
vgmstream->meta_type = meta_VS_STR;
|
||||
vgmstream->sample_rate = 44100;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_ps2_strlr;
|
||||
vgmstream->layout_type = layout_blocked_vs_str;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
@ -108,9 +108,11 @@ VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
||||
name_size = 0;
|
||||
switch(sample_rate) {
|
||||
case 0x0800: sample_rate = 22050; break;
|
||||
case 0x0687: sample_rate = 18000; break;
|
||||
case 0x05ce: sample_rate = 16000; break;
|
||||
case 0x0400: sample_rate = 11025; break;
|
||||
default:
|
||||
VGM_LOG("ZSND: unknown sample_rate\n");
|
||||
VGM_LOG("ZSND: unknown sample_rate %x at %x\n", sample_rate, (uint32_t)header2_offset);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
@ -192,8 +192,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_vgs,
|
||||
init_vgmstream_dc_dcsw_dcs,
|
||||
init_vgmstream_wii_smp,
|
||||
init_vgmstream_emff_ps2,
|
||||
init_vgmstream_emff_ngc,
|
||||
init_vgmstream_mul,
|
||||
init_vgmstream_thp,
|
||||
init_vgmstream_wii_sts,
|
||||
init_vgmstream_ps2_p2bt,
|
||||
@ -213,7 +212,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ps2_mcg,
|
||||
init_vgmstream_zsd,
|
||||
init_vgmstream_ps2_vgs,
|
||||
init_vgmstream_RedSpark,
|
||||
init_vgmstream_redspark,
|
||||
init_vgmstream_ivaud,
|
||||
init_vgmstream_wii_wsd,
|
||||
init_vgmstream_wii_ndp,
|
||||
@ -290,7 +289,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ps2_spm,
|
||||
init_vgmstream_x360_tra,
|
||||
init_vgmstream_ps2_iab,
|
||||
init_vgmstream_ps2_strlr,
|
||||
init_vgmstream_vs_str,
|
||||
init_vgmstream_lsf_n1nj4n,
|
||||
init_vgmstream_vawx,
|
||||
init_vgmstream_ps2_wmus,
|
||||
@ -445,7 +444,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ue4opus,
|
||||
init_vgmstream_xwma,
|
||||
init_vgmstream_xopus,
|
||||
init_vgmstream_vs_ffx,
|
||||
init_vgmstream_vs_square,
|
||||
init_vgmstream_msf_banpresto_wmsf,
|
||||
init_vgmstream_msf_banpresto_2msf,
|
||||
init_vgmstream_nwav,
|
||||
@ -458,6 +457,8 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_dsp_adpcmx,
|
||||
init_vgmstream_ogg_opus,
|
||||
init_vgmstream_nus3audio,
|
||||
init_vgmstream_imc,
|
||||
init_vgmstream_imc_container,
|
||||
|
||||
/* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */
|
||||
init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */
|
||||
@ -1006,8 +1007,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
case layout_blocked_matx:
|
||||
case layout_blocked_dec:
|
||||
case layout_blocked_vs:
|
||||
case layout_blocked_emff_ps2:
|
||||
case layout_blocked_emff_ngc:
|
||||
case layout_blocked_mul:
|
||||
case layout_blocked_gsb:
|
||||
case layout_blocked_xvas:
|
||||
case layout_blocked_thp:
|
||||
@ -1018,7 +1018,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
case layout_blocked_bdsp:
|
||||
case layout_blocked_tra:
|
||||
case layout_blocked_ps2_iab:
|
||||
case layout_blocked_ps2_strlr:
|
||||
case layout_blocked_vs_str:
|
||||
case layout_blocked_rws:
|
||||
case layout_blocked_hwas:
|
||||
case layout_blocked_ea_sns:
|
||||
@ -1031,7 +1031,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
case layout_blocked_sthd:
|
||||
case layout_blocked_h4m:
|
||||
case layout_blocked_xa_aiff:
|
||||
case layout_blocked_vs_ffx:
|
||||
case layout_blocked_vs_square:
|
||||
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
||||
break;
|
||||
case layout_aix:
|
||||
|
@ -229,8 +229,7 @@ typedef enum {
|
||||
layout_blocked_dec,
|
||||
layout_blocked_xvas,
|
||||
layout_blocked_vs,
|
||||
layout_blocked_emff_ps2,
|
||||
layout_blocked_emff_ngc,
|
||||
layout_blocked_mul,
|
||||
layout_blocked_gsb,
|
||||
layout_blocked_thp,
|
||||
layout_blocked_filp,
|
||||
@ -241,7 +240,7 @@ typedef enum {
|
||||
layout_blocked_ivaud, /* GTA IV .ivaud blocks */
|
||||
layout_blocked_tra, /* DefJam Rapstar .tra blocks */
|
||||
layout_blocked_ps2_iab,
|
||||
layout_blocked_ps2_strlr,
|
||||
layout_blocked_vs_str,
|
||||
layout_blocked_rws,
|
||||
layout_blocked_hwas,
|
||||
layout_blocked_ea_sns, /* newest Electronic Arts blocks, found in SNS/SNU/SPS/etc formats */
|
||||
@ -254,7 +253,7 @@ typedef enum {
|
||||
layout_blocked_sthd, /* Dream Factory STHD */
|
||||
layout_blocked_h4m, /* H4M video */
|
||||
layout_blocked_xa_aiff, /* XA in AIFF files [Crusader: No Remorse (SAT), Road Rash (3DO)] */
|
||||
layout_blocked_vs_ffx,
|
||||
layout_blocked_vs_square,
|
||||
|
||||
/* otherwise odd */
|
||||
layout_aix, /* CRI AIX's wheels within wheels */
|
||||
@ -441,8 +440,7 @@ typedef enum {
|
||||
meta_DC_DCSW_DCS, /* Evil Twin - Cypriens Chronicles (DC) */
|
||||
meta_WII_SMP, /* Mushroom Men - The Spore Wars */
|
||||
meta_WII_SNG, /* Excite Trucks */
|
||||
meta_EMFF_PS2, /* Eidos Music File Format for PS2*/
|
||||
meta_EMFF_NGC, /* Eidos Music File Format for NGC/WII */
|
||||
meta_MUL,
|
||||
meta_SAT_BAKA, /* Crypt Killer */
|
||||
meta_PS2_VSF, /* Musashi: Samurai Legend */
|
||||
meta_PS2_VSF_TTA, /* Tiny Toon Adventures: Defenders of the Universe */
|
||||
@ -502,8 +500,8 @@ typedef enum {
|
||||
meta_PS2_TK5, /* Tekken 5 Stream Files */
|
||||
meta_PS2_MCG, /* Gunvari MCG Files (was name .GCM on disk) */
|
||||
meta_ZSD, /* Dragon Booster ZSD */
|
||||
meta_RedSpark, /* "RedSpark" RSD (MadWorld) */
|
||||
meta_IVAUD, /* .ivaud GTA IV */
|
||||
meta_REDSPARK, /* "RedSpark" RSD (MadWorld) */
|
||||
meta_IVAUD, /* .ivaud GTA IV */
|
||||
meta_NDS_HWAS, /* Spider-Man 3, Tony Hawk's Downhill Jam, possibly more... */
|
||||
meta_NGC_LPS, /* Rave Master (Groove Adventure Rave)(GC) */
|
||||
meta_NAOMI_ADPCM, /* NAOMI/NAOMI2 ARcade games */
|
||||
@ -567,7 +565,7 @@ typedef enum {
|
||||
meta_X360_TRA, /* Def Jam Rapstar */
|
||||
meta_PS2_VGS, /* Princess Soft PS2 games */
|
||||
meta_PS2_IAB, /* Ueki no Housoku - Taosu ze Robert Juudan!! (PS2) */
|
||||
meta_PS2_STRLR, /* The Bouncer */
|
||||
meta_VS_STR, /* The Bouncer */
|
||||
meta_LSF_N1NJ4N, /* .lsf n1nj4n Fastlane Street Racing (iPhone) */
|
||||
meta_VAWX, /* feelplus: No More Heroes Heroes Paradise, Moon Diver */
|
||||
meta_PC_SNDS, /* Incredibles PC .snds */
|
||||
@ -702,14 +700,15 @@ typedef enum {
|
||||
meta_XWMA,
|
||||
meta_VA3, /* DDR Supernova 2 AC */
|
||||
meta_XOPUS,
|
||||
meta_VS_FFX,
|
||||
meta_VS_SQUARE,
|
||||
meta_NWAV,
|
||||
meta_XPCM,
|
||||
meta_MSF_TAMASOFT,
|
||||
meta_XPS_DAT,
|
||||
meta_ZSND,
|
||||
meta_DSP_ADPCMX,
|
||||
meta_OGG_OPUS
|
||||
meta_OGG_OPUS,
|
||||
meta_IMC,
|
||||
|
||||
} meta_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user