mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 07:44:43 +01:00
commit
fc5bb81ddc
16
BUILD.md
16
BUILD.md
@ -129,7 +129,9 @@ git clean -fd
|
|||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Structure
|
### Structure
|
||||||
vgmstream uses C89 when possible (so VS2010 can compile it), and C++ for the foobar2000 and Audacious plugins.
|
vgmstream uses C (C89 when possible), and C++ for the foobar2000 and Audacious plugins.
|
||||||
|
|
||||||
|
C is restricted to features VS2010 can understand. This mainly means means declaring variables at the start of a { .. } block (declare+initialize is fine, as long as it doesn't reference variables declared in that block) and avoiding C99 like variable-length arrays (but others like // comments are fine).
|
||||||
|
|
||||||
```
|
```
|
||||||
./ docs, scripts
|
./ docs, scripts
|
||||||
@ -162,11 +164,17 @@ Very simplified it goes like this:
|
|||||||
|
|
||||||
### Adding new formats
|
### Adding new formats
|
||||||
For new simple formats, assuming existing layout/coding:
|
For new simple formats, assuming existing layout/coding:
|
||||||
- *src/meta/(format-name).c*: create new format parser that reads all needed info from the stream header and inits VGMSTREAM
|
- *src/meta/(format-name).c*: create new init_vgmstream_(format-name) parser that reads all needed info from the stream header and inits VGMSTREAM
|
||||||
- *src/meta/meta.h*: register parser's init
|
- *src/meta/meta.h*: define parser's init
|
||||||
- *src/vgmstream.h*: register new meta
|
- *src/vgmstream.h*: define meta description in the meta_t list
|
||||||
- *src/vgmstream.c*: add parser init to the init list
|
- *src/vgmstream.c*: add parser init to the init list
|
||||||
- *src/formats.c*: add new extension to the format list, add meta description
|
- *src/formats.c*: add new extension to the format list, add meta description
|
||||||
- *fb2k/foo_filetypes.h*: add new extension to the file register list (optional)
|
- *fb2k/foo_filetypes.h*: add new extension to the file register list (optional)
|
||||||
- *src/libvgmstream.vcproj/vcxproj/filters*: add to compile new (format-name).c parser in VS
|
- *src/libvgmstream.vcproj/vcxproj/filters*: add to compile new (format-name).c parser in VS
|
||||||
- if the format needs an external library don't forget to mark optional parts with: *#ifdef VGM_USE_X ... #endif*
|
- if the format needs an external library don't forget to mark optional parts with: *#ifdef VGM_USE_X ... #endif*
|
||||||
|
|
||||||
|
A STREAMFILE is passed to init_vgmstream_(format-name) function, and I/O must be done using its functions and not STDIO/FILEs, as this lets plugins do their own I/O. This includes reading data from the header or opening other STREAMFILEs (if the header has companion files that need to be parsed).
|
||||||
|
|
||||||
|
When a parser is successful (allocates VGMSTREAM and sets values) it also needs to open and assign to the VGMSTREAM one or several STREAMFILEs (usually reopens the one passed, but could be any other file) to do I/O during decode. The STREAMFILE passed to the meta will be discarded and must not be reused.
|
||||||
|
|
||||||
|
If it supports subsongs it should read and handle the stream index (subsong number) in the passed STREAMFILE, and report the number of subsongs in the VGMSTREAM, to signal the plugins this feature. The index is 1-based (first subsong is 1, not 0).
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "../src/formats.h"
|
|
||||||
#include "../src/vgmstream.h"
|
#include "../src/vgmstream.h"
|
||||||
}
|
}
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
@ -95,8 +94,8 @@ bool VgmstreamPlugin::is_our_file(const char *filename, VFSFile &file) {
|
|||||||
else
|
else
|
||||||
ext = ext+1; /* skip the dot */
|
ext = ext+1; /* skip the dot */
|
||||||
|
|
||||||
const char ** ext_list = vgmstream_get_formats();
|
size_t ext_list_len = 0;
|
||||||
int ext_list_len = vgmstream_get_formats_length();
|
const char ** ext_list = vgmstream_get_formats(&ext_list_len);
|
||||||
|
|
||||||
for (int i=0; i < ext_list_len; i++) {
|
for (int i=0; i < ext_list_len; i++) {
|
||||||
if (!strcasecmp(ext, ext_list[i]))
|
if (!strcasecmp(ext, ext_list[i]))
|
||||||
|
@ -161,6 +161,7 @@ VGMSTREAM_DECLARE_FILE_TYPE("KOVS", kovs);
|
|||||||
VGMSTREAM_DECLARE_FILE_TYPE("KRAW", kraw);
|
VGMSTREAM_DECLARE_FILE_TYPE("KRAW", kraw);
|
||||||
|
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("LAAC", laac);
|
VGMSTREAM_DECLARE_FILE_TYPE("LAAC", laac);
|
||||||
|
VGMSTREAM_DECLARE_FILE_TYPE("LAC3", lac3);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("LEG", leg);
|
VGMSTREAM_DECLARE_FILE_TYPE("LEG", leg);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("LMP4", lmp4);
|
VGMSTREAM_DECLARE_FILE_TYPE("LMP4", lmp4);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("LOGG", logg);
|
VGMSTREAM_DECLARE_FILE_TYPE("LOGG", logg);
|
||||||
@ -282,8 +283,6 @@ VGMSTREAM_DECLARE_FILE_TYPE("SPS", sps);
|
|||||||
VGMSTREAM_DECLARE_FILE_TYPE("SPSD", spsd);
|
VGMSTREAM_DECLARE_FILE_TYPE("SPSD", spsd);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("SPW", spw);
|
VGMSTREAM_DECLARE_FILE_TYPE("SPW", spw);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("SS2", ss2);
|
VGMSTREAM_DECLARE_FILE_TYPE("SS2", ss2);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("SS3", ss3);
|
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("SS7", ss7);
|
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("SSM", ssm);
|
VGMSTREAM_DECLARE_FILE_TYPE("SSM", ssm);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("SSS", sss);
|
VGMSTREAM_DECLARE_FILE_TYPE("SSS", sss);
|
||||||
VGMSTREAM_DECLARE_FILE_TYPE("STER", ster);
|
VGMSTREAM_DECLARE_FILE_TYPE("STER", ster);
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include <shared.h>
|
#include <shared.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "../src/formats.h"
|
|
||||||
#include "../src/vgmstream.h"
|
#include "../src/vgmstream.h"
|
||||||
}
|
}
|
||||||
#include "foo_vgmstream.h"
|
#include "foo_vgmstream.h"
|
||||||
@ -184,19 +183,19 @@ void input_vgmstream::decode_initialize(t_uint32 p_subsong, unsigned p_flags, ab
|
|||||||
|
|
||||||
bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
|
bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
|
||||||
if (!decoding) return false;
|
if (!decoding) return false;
|
||||||
|
if (!vgmstream) return false;
|
||||||
|
|
||||||
int max_buffer_samples = sizeof(sample_buffer)/sizeof(sample_buffer[0])/vgmstream->channels;
|
int max_buffer_samples = sizeof(sample_buffer)/sizeof(sample_buffer[0])/vgmstream->channels;
|
||||||
int l = 0, samples_to_do = max_buffer_samples;
|
int samples_to_do = max_buffer_samples;
|
||||||
|
t_size bytes;
|
||||||
|
|
||||||
if(vgmstream) {
|
{
|
||||||
bool loop_okay = loop_forever && vgmstream->loop_flag && !ignore_loop && !force_ignore_loop;
|
bool loop_okay = loop_forever && vgmstream->loop_flag && !ignore_loop && !force_ignore_loop;
|
||||||
if (decode_pos_samples+max_buffer_samples>stream_length_samples && !loop_okay)
|
if (decode_pos_samples+max_buffer_samples>stream_length_samples && !loop_okay)
|
||||||
samples_to_do=stream_length_samples-decode_pos_samples;
|
samples_to_do=stream_length_samples-decode_pos_samples;
|
||||||
else
|
else
|
||||||
samples_to_do=max_buffer_samples;
|
samples_to_do=max_buffer_samples;
|
||||||
|
|
||||||
l = (samples_to_do*vgmstream->channels * sizeof(sample_buffer[0]));
|
|
||||||
|
|
||||||
if (samples_to_do /*< DECODE_SIZE*/ == 0) {
|
if (samples_to_do /*< DECODE_SIZE*/ == 0) {
|
||||||
decoding = false;
|
decoding = false;
|
||||||
return false;
|
return false;
|
||||||
@ -222,15 +221,14 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p_chunk.set_data_fixedpoint((char*)sample_buffer, l, vgmstream->sample_rate, vgmstream->channels, 16, audio_chunk::g_guess_channel_config(vgmstream->channels));
|
bytes = (samples_to_do*vgmstream->channels * sizeof(sample_buffer[0]));
|
||||||
|
p_chunk.set_data_fixedpoint((char*)sample_buffer, bytes, vgmstream->sample_rate, vgmstream->channels, 16, audio_chunk::g_guess_channel_config(vgmstream->channels));
|
||||||
|
|
||||||
decode_pos_samples+=samples_to_do;
|
decode_pos_samples+=samples_to_do;
|
||||||
decode_pos_ms=decode_pos_samples*1000LL/vgmstream->sample_rate;
|
decode_pos_ms=decode_pos_samples*1000LL/vgmstream->sample_rate;
|
||||||
|
|
||||||
return samples_to_do==max_buffer_samples;
|
return samples_to_do==max_buffer_samples;
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_vgmstream::decode_seek(double p_seconds,abort_callback & p_abort) {
|
void input_vgmstream::decode_seek(double p_seconds,abort_callback & p_abort) {
|
||||||
@ -295,11 +293,10 @@ void input_vgmstream::retag_commit(abort_callback & p_abort) { /*throw exception
|
|||||||
bool input_vgmstream::g_is_our_content_type(const char * p_content_type) {return false;}
|
bool input_vgmstream::g_is_our_content_type(const char * p_content_type) {return false;}
|
||||||
bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension) {
|
bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension) {
|
||||||
const char ** ext_list;
|
const char ** ext_list;
|
||||||
int ext_list_len;
|
size_t ext_list_len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ext_list = vgmstream_get_formats();
|
ext_list = vgmstream_get_formats(&ext_list_len);
|
||||||
ext_list_len = vgmstream_get_formats_length();
|
|
||||||
|
|
||||||
for (i=0; i < ext_list_len; i++) {
|
for (i=0; i < ext_list_len; i++) {
|
||||||
if (!stricmp_utf8(p_extension, ext_list[i]))
|
if (!stricmp_utf8(p_extension, ext_list[i]))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "formats.h"
|
#include "vgmstream.h"
|
||||||
|
|
||||||
//#define VGM_REGISTER_TYPE(extension) ...
|
//#define VGM_REGISTER_TYPE(extension) ...
|
||||||
//#define VGM_REGISTER_TYPE_COMMON(extension) ... /* for common extensions like aiff */
|
//#define VGM_REGISTER_TYPE_COMMON(extension) ... /* for common extensions like aiff */
|
||||||
@ -154,6 +154,7 @@ static const char* extension_list[] = {
|
|||||||
"kraw",
|
"kraw",
|
||||||
|
|
||||||
"laac", //fake extension, for AAC (tri-Ace/FFmpeg)
|
"laac", //fake extension, for AAC (tri-Ace/FFmpeg)
|
||||||
|
"lac3", //fake extension, for AC3
|
||||||
"leg",
|
"leg",
|
||||||
"lmp4", //fake extension, for MP4s
|
"lmp4", //fake extension, for MP4s
|
||||||
"logg", //fake extension, for OGGs
|
"logg", //fake extension, for OGGs
|
||||||
@ -276,8 +277,6 @@ static const char* extension_list[] = {
|
|||||||
"spsd",
|
"spsd",
|
||||||
"spw",
|
"spw",
|
||||||
"ss2",
|
"ss2",
|
||||||
"ss3",
|
|
||||||
"ss7",
|
|
||||||
"ssm",
|
"ssm",
|
||||||
"sss",
|
"sss",
|
||||||
"ster",
|
"ster",
|
||||||
@ -374,22 +373,11 @@ static const char* extension_list[] = {
|
|||||||
//, NULL //end mark
|
//, NULL //end mark
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
const char ** vgmstream_get_formats(size_t * size) {
|
||||||
* List of supported formats.
|
*size = sizeof(extension_list) / sizeof(char*);
|
||||||
*
|
|
||||||
* For plugins that need to know (test.exe doesn't use it)
|
|
||||||
*/
|
|
||||||
const char ** vgmstream_get_formats() {
|
|
||||||
return extension_list;
|
return extension_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of elements in the list.
|
|
||||||
*/
|
|
||||||
int vgmstream_get_formats_length() {
|
|
||||||
return sizeof(extension_list) / sizeof(char*);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* internal description info */
|
/* internal description info */
|
||||||
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* formats.h - utils to parse supported formats
|
|
||||||
*/
|
|
||||||
#ifndef _FORMATS_H_
|
|
||||||
#define _FORMATS_H_
|
|
||||||
|
|
||||||
#include "vgmstream.h"
|
|
||||||
|
|
||||||
/* rough number of chars counting all extensions (actually <1500 and extra space) */
|
|
||||||
#define VGM_EXTENSION_LIST_CHAR_SIZE 2000
|
|
||||||
|
|
||||||
const char ** vgmstream_get_formats();
|
|
||||||
int vgmstream_get_formats_length();
|
|
||||||
|
|
||||||
const char * get_vgmstream_coding_description(coding_t coding_type);
|
|
||||||
const char * get_vgmstream_layout_description(layout_t layout_type);
|
|
||||||
const char * get_vgmstream_meta_description(meta_t meta_type);
|
|
||||||
|
|
||||||
#endif /* _FORMATS_H_ */
|
|
@ -147,10 +147,6 @@
|
|||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
>
|
>
|
||||||
<File
|
|
||||||
RelativePath=".\formats.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\streamfile.h"
|
RelativePath=".\streamfile.h"
|
||||||
>
|
>
|
||||||
@ -662,6 +658,10 @@
|
|||||||
RelativePath=".\meta\pc_adp.c"
|
RelativePath=".\meta\pc_adp.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\meta\pc_adp_otns.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\pc_al2.c"
|
RelativePath=".\meta\pc_al2.c"
|
||||||
>
|
>
|
||||||
@ -1122,10 +1122,6 @@
|
|||||||
RelativePath=".\meta\sqex_scd.c"
|
RelativePath=".\meta\sqex_scd.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\meta\ss_stream.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\stm.c"
|
RelativePath=".\meta\stm.c"
|
||||||
>
|
>
|
||||||
|
@ -113,7 +113,6 @@
|
|||||||
<ClInclude Include="coding\vorbis_custom_data_fsb.h" />
|
<ClInclude Include="coding\vorbis_custom_data_fsb.h" />
|
||||||
<ClInclude Include="coding\vorbis_custom_data_wwise.h" />
|
<ClInclude Include="coding\vorbis_custom_data_wwise.h" />
|
||||||
<ClInclude Include="coding\vorbis_custom_decoder.h" />
|
<ClInclude Include="coding\vorbis_custom_decoder.h" />
|
||||||
<ClInclude Include="formats.h" />
|
|
||||||
<ClInclude Include="streamfile.h" />
|
<ClInclude Include="streamfile.h" />
|
||||||
<ClInclude Include="streamtypes.h" />
|
<ClInclude Include="streamtypes.h" />
|
||||||
<ClInclude Include="util.h" />
|
<ClInclude Include="util.h" />
|
||||||
@ -162,6 +161,7 @@
|
|||||||
<ClCompile Include="meta\nsw_opus.c" />
|
<ClCompile Include="meta\nsw_opus.c" />
|
||||||
<ClCompile Include="meta\nub_vag.c" />
|
<ClCompile Include="meta\nub_vag.c" />
|
||||||
<ClCompile Include="meta\pc_adp.c" />
|
<ClCompile Include="meta\pc_adp.c" />
|
||||||
|
<ClCompile Include="meta\pc_adp_otns.c" />
|
||||||
<ClCompile Include="meta\pc_ast.c" />
|
<ClCompile Include="meta\pc_ast.c" />
|
||||||
<ClCompile Include="meta\pc_snds.c" />
|
<ClCompile Include="meta\pc_snds.c" />
|
||||||
<ClCompile Include="meta\ps2_2pfs.c" />
|
<ClCompile Include="meta\ps2_2pfs.c" />
|
||||||
@ -388,7 +388,6 @@
|
|||||||
<ClCompile Include="meta\sfl.c" />
|
<ClCompile Include="meta\sfl.c" />
|
||||||
<ClCompile Include="meta\sli.c" />
|
<ClCompile Include="meta\sli.c" />
|
||||||
<ClCompile Include="meta\spt_spd.c" />
|
<ClCompile Include="meta\spt_spd.c" />
|
||||||
<ClCompile Include="meta\ss_stream.c" />
|
|
||||||
<ClCompile Include="meta\stm.c" />
|
<ClCompile Include="meta\stm.c" />
|
||||||
<ClCompile Include="meta\str_asr.c" />
|
<ClCompile Include="meta\str_asr.c" />
|
||||||
<ClCompile Include="meta\str_snds.c" />
|
<ClCompile Include="meta\str_snds.c" />
|
||||||
|
@ -47,9 +47,6 @@
|
|||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="formats.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="streamfile.h">
|
<ClInclude Include="streamfile.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -685,9 +682,6 @@
|
|||||||
<ClCompile Include="meta\spt_spd.c">
|
<ClCompile Include="meta\spt_spd.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\ss_stream.c">
|
|
||||||
<Filter>meta\Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="meta\stm.c">
|
<ClCompile Include="meta\stm.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -1081,6 +1075,9 @@
|
|||||||
<ClCompile Include="meta\pc_adp.c">
|
<ClCompile Include="meta\pc_adp.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="meta\pc_adp_otns.c">
|
||||||
|
<Filter>meta\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="meta\excitebots.c">
|
<ClCompile Include="meta\excitebots.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
290
src/meta/bcstm.c
290
src/meta/bcstm.c
@ -3,166 +3,166 @@
|
|||||||
|
|
||||||
/* BCSTM - Nintendo 3DS format */
|
/* BCSTM - Nintendo 3DS format */
|
||||||
VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
coding_t coding_type;
|
coding_t coding_type;
|
||||||
|
|
||||||
off_t info_offset = 0, seek_offset = 0, data_offset = 0;
|
off_t info_offset = 0, seek_offset = 0, data_offset = 0;
|
||||||
uint16_t temp_id;
|
uint16_t temp_id;
|
||||||
int codec_number;
|
int codec_number;
|
||||||
int channel_count, loop_flag;
|
int channel_count, loop_flag;
|
||||||
int i, ima = 0;
|
int i, ima = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int section_count;
|
int section_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
if ( !check_extensions(streamFile,"bcstm") )
|
if ( !check_extensions(streamFile,"bcstm") )
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if ((uint32_t)read_32bitBE(0, streamFile) != 0x4353544D) /* "CSTM" */
|
if ((uint32_t)read_32bitBE(0, streamFile) != 0x4353544D) /* "CSTM" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if ((uint16_t)read_16bitLE(4, streamFile) != 0xFEFF)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
section_count = read_16bitLE(0x10, streamFile);
|
||||||
|
for (i = 0; i < section_count; i++) {
|
||||||
|
temp_id = read_16bitLE(0x14 + i * 0xc, streamFile);
|
||||||
|
switch(temp_id) {
|
||||||
|
case 0x4000:
|
||||||
|
info_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t info_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4001:
|
||||||
|
seek_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t seek_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4002:
|
||||||
|
data_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t data_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4003:
|
||||||
|
/* off_t regn_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */
|
||||||
|
/* size_t regn_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4004:
|
||||||
|
/* off_t pdat_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */
|
||||||
|
/* size_t pdat_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((uint16_t)read_16bitLE(4, streamFile) != 0xFEFF)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
section_count = read_16bitLE(0x10, streamFile);
|
|
||||||
for (i = 0; i < section_count; i++) {
|
|
||||||
temp_id = read_16bitLE(0x14 + i * 0xc, streamFile);
|
|
||||||
switch(temp_id) {
|
|
||||||
case 0x4000:
|
|
||||||
info_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
|
||||||
/* size_t info_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
|
||||||
break;
|
|
||||||
case 0x4001:
|
|
||||||
seek_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
|
||||||
/* size_t seek_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
|
||||||
break;
|
|
||||||
case 0x4002:
|
|
||||||
data_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
|
||||||
/* size_t data_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
|
||||||
break;
|
|
||||||
case 0x4003:
|
|
||||||
/* off_t regn_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */
|
|
||||||
/* size_t regn_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
|
||||||
break;
|
|
||||||
case 0x4004:
|
|
||||||
/* off_t pdat_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */
|
|
||||||
/* size_t pdat_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info_offset == 0) goto fail;
|
if (info_offset == 0) goto fail;
|
||||||
if ((uint32_t)read_32bitBE(info_offset, streamFile) != 0x494E464F) /* "INFO" */
|
if ((uint32_t)read_32bitBE(info_offset, streamFile) != 0x494E464F) /* "INFO" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
||||||
/* check type details */
|
|
||||||
codec_number = read_8bit(info_offset + 0x20, streamFile);
|
|
||||||
loop_flag = read_8bit(info_offset + 0x21, streamFile);
|
|
||||||
channel_count = read_8bit(info_offset + 0x22, streamFile);
|
|
||||||
|
|
||||||
switch (codec_number) {
|
/* check type details */
|
||||||
case 0:
|
codec_number = read_8bit(info_offset + 0x20, streamFile);
|
||||||
coding_type = coding_PCM8;
|
loop_flag = read_8bit(info_offset + 0x21, streamFile);
|
||||||
break;
|
channel_count = read_8bit(info_offset + 0x22, streamFile);
|
||||||
case 1:
|
|
||||||
coding_type = coding_PCM16LE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (seek_offset == 0) goto fail;
|
|
||||||
if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */
|
|
||||||
ima = 1;
|
|
||||||
coding_type = coding_IMA_int;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
coding_type = coding_NGC_DSP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel_count < 1) goto fail;
|
switch (codec_number) {
|
||||||
|
case 0:
|
||||||
|
coding_type = coding_PCM8;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
coding_type = coding_PCM16LE;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (seek_offset == 0) goto fail;
|
||||||
|
if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */
|
||||||
|
ima = 1;
|
||||||
|
coding_type = coding_IMA_int;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
coding_type = coding_NGC_DSP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
if (channel_count < 1) goto fail;
|
||||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* build the VGMSTREAM */
|
||||||
vgmstream->num_samples = read_32bitLE(info_offset + 0x2c, streamFile);
|
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||||
vgmstream->sample_rate = read_32bitLE(info_offset + 0x24, streamFile);
|
if (!vgmstream) goto fail;
|
||||||
/* channels and loop flag are set by allocate_vgmstream */
|
|
||||||
if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
|
|
||||||
{
|
|
||||||
vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile);
|
|
||||||
if (vgmstream->loop_start_sample > 10000)
|
|
||||||
{
|
|
||||||
vgmstream->loop_start_sample -= 5000;
|
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples - 5000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile);
|
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_type;
|
/* fill in the vital statistics */
|
||||||
if (channel_count == 1)
|
vgmstream->num_samples = read_32bitLE(info_offset + 0x2c, streamFile);
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->sample_rate = read_32bitLE(info_offset + 0x24, streamFile);
|
||||||
else
|
/* channels and loop flag are set by allocate_vgmstream */
|
||||||
{
|
if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
|
||||||
if (ima)
|
{
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile);
|
||||||
else
|
if (vgmstream->loop_start_sample > 10000)
|
||||||
vgmstream->layout_type = layout_interleave_shortblock;
|
{
|
||||||
}
|
vgmstream->loop_start_sample -= 5000;
|
||||||
vgmstream->meta_type = meta_CSTM;
|
vgmstream->loop_end_sample = vgmstream->num_samples - 5000;
|
||||||
|
}
|
||||||
if (ima)
|
else
|
||||||
vgmstream->interleave_block_size = 0x200;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
else {
|
}
|
||||||
vgmstream->interleave_block_size = read_32bitLE(info_offset + 0x34, streamFile);
|
else
|
||||||
vgmstream->interleave_smallblock_size = read_32bitLE(info_offset + 0x44, streamFile);
|
{
|
||||||
}
|
vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile);
|
||||||
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
}
|
||||||
off_t coef_offset;
|
|
||||||
off_t tempoffset = info_offset;
|
vgmstream->coding_type = coding_type;
|
||||||
int foundcoef = 0;
|
if (channel_count == 1)
|
||||||
int i, j;
|
vgmstream->layout_type = layout_none;
|
||||||
int coef_spacing = 0x2E;
|
else
|
||||||
|
{
|
||||||
while (!(foundcoef))
|
if (ima)
|
||||||
{
|
vgmstream->layout_type = layout_interleave;
|
||||||
if ((uint32_t)read_32bitLE(tempoffset, streamFile) == 0x00004102)
|
else
|
||||||
{
|
vgmstream->layout_type = layout_interleave_shortblock;
|
||||||
coef_offset = read_32bitLE(tempoffset + 4, streamFile) + tempoffset + (channel_count * 8) - 4 - info_offset;
|
}
|
||||||
foundcoef++;
|
vgmstream->meta_type = meta_CSTM;
|
||||||
break;
|
|
||||||
}
|
if (ima)
|
||||||
tempoffset++;
|
vgmstream->interleave_block_size = 0x200;
|
||||||
}
|
else {
|
||||||
|
vgmstream->interleave_block_size = read_32bitLE(info_offset + 0x34, streamFile);
|
||||||
|
vgmstream->interleave_smallblock_size = read_32bitLE(info_offset + 0x44, streamFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||||
|
off_t coef_offset;
|
||||||
|
off_t tempoffset = info_offset;
|
||||||
|
int foundcoef = 0;
|
||||||
|
int i, j;
|
||||||
|
int coef_spacing = 0x2E;
|
||||||
|
|
||||||
|
while (!(foundcoef))
|
||||||
|
{
|
||||||
|
if ((uint32_t)read_32bitLE(tempoffset, streamFile) == 0x00004102)
|
||||||
|
{
|
||||||
|
coef_offset = read_32bitLE(tempoffset + 4, streamFile) + tempoffset + (channel_count * 8) - 4 - info_offset;
|
||||||
|
foundcoef++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tempoffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j<vgmstream->channels; j++) {
|
||||||
|
for (i = 0; i<16; i++) {
|
||||||
|
vgmstream->ch[j].adpcm_coef[i] = read_16bitLE(info_offset + coef_offset + j*coef_spacing + i * 2, streamFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ima) { // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
|
||||||
|
if (seek_offset == 0) goto fail;
|
||||||
|
start_offset = seek_offset;
|
||||||
|
} else {
|
||||||
|
if (data_offset == 0) goto fail;
|
||||||
|
start_offset = data_offset + 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j<vgmstream->channels; j++) {
|
|
||||||
for (i = 0; i<16; i++) {
|
|
||||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitLE(info_offset + coef_offset + j*coef_spacing + i * 2, streamFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ima) { // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
|
|
||||||
if (seek_offset == 0) goto fail;
|
|
||||||
start_offset = seek_offset;
|
|
||||||
} else {
|
|
||||||
if (data_offset == 0) goto fail;
|
|
||||||
start_offset = data_offset + 0x20;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading by each channel */
|
||||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
|
@ -254,7 +254,8 @@ VGMSTREAM * init_vgmstream_fsb_offset(STREAMFILE *streamFile, off_t offset) {
|
|||||||
|
|
||||||
/* sometimes there is garbage at the end or missing bytes due to improper demuxing */
|
/* sometimes there is garbage at the end or missing bytes due to improper demuxing */
|
||||||
VGM_ASSERT(fsbh.hdrsize + fsbh.shdrsize + fsbh.datasize != streamFile->get_size(streamFile) - offset,
|
VGM_ASSERT(fsbh.hdrsize + fsbh.shdrsize + fsbh.datasize != streamFile->get_size(streamFile) - offset,
|
||||||
"FSB wrong head/datasize found\n");
|
"FSB wrong head/datasize found (expected 0x%x vs 0x%lx)\n",
|
||||||
|
fsbh.hdrsize + fsbh.shdrsize + fsbh.datasize, streamFile->get_size(streamFile) - offset);
|
||||||
|
|
||||||
/* Loops unless disabled. FMOD default seems full loops (0/num_samples-1) without flags, for repeating tracks
|
/* Loops unless disabled. FMOD default seems full loops (0/num_samples-1) without flags, for repeating tracks
|
||||||
* that should loop and jingles/sfx that shouldn't. We'll try to disable looping is it looks jingly enough. */
|
* that should loop and jingles/sfx that shouldn't. We'll try to disable looping is it looks jingly enough. */
|
||||||
|
278
src/meta/genh.c
278
src/meta/genh.c
@ -3,6 +3,8 @@
|
|||||||
#include "../layout/layout.h"
|
#include "../layout/layout.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* known GENH types */
|
/* known GENH types */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PSX = 0, /* PSX ADPCM */
|
PSX = 0, /* PSX ADPCM */
|
||||||
@ -28,26 +30,45 @@ typedef enum {
|
|||||||
XMA1 = 20, /* raw XMA1 */
|
XMA1 = 20, /* raw XMA1 */
|
||||||
XMA2 = 21, /* raw XMA2 */
|
XMA2 = 21, /* raw XMA2 */
|
||||||
FFMPEG = 22, /* any headered FFmpeg format */
|
FFMPEG = 22, /* any headered FFmpeg format */
|
||||||
|
AC3 = 23, /* AC3/SPDIF */
|
||||||
} genh_type;
|
} genh_type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
genh_type codec;
|
||||||
|
int codec_mode;
|
||||||
|
size_t interleave;
|
||||||
|
|
||||||
|
int channels;
|
||||||
|
int32_t sample_rate;
|
||||||
|
|
||||||
|
size_t data_size;
|
||||||
|
off_t start_offset;
|
||||||
|
|
||||||
|
int32_t num_samples;
|
||||||
|
int32_t loop_start_sample;
|
||||||
|
int32_t loop_end_sample;
|
||||||
|
int skip_samples_mode;
|
||||||
|
int32_t skip_samples;
|
||||||
|
|
||||||
|
int loop_flag;
|
||||||
|
|
||||||
|
int32_t coef[2];
|
||||||
|
int32_t coef_splitted[2];
|
||||||
|
int32_t coef_type;
|
||||||
|
int32_t coef_interleave_type;
|
||||||
|
int coef_big_endian;
|
||||||
|
|
||||||
|
} genh_header;
|
||||||
|
|
||||||
|
static int parse_genh(STREAMFILE * streamFile, genh_header * genh);
|
||||||
|
|
||||||
/* GENH is an artificial "generic" header for headerless streams */
|
/* GENH is an artificial "generic" header for headerless streams */
|
||||||
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
genh_header genh = {0};
|
||||||
int channel_count, loop_flag, sample_rate, interleave;
|
coding_t coding;
|
||||||
int32_t num_samples = 0, loop_start, loop_end, skip_samples = 0;
|
|
||||||
int32_t start_offset, header_size;
|
|
||||||
off_t datasize = 0;
|
|
||||||
|
|
||||||
int32_t coef[2];
|
|
||||||
int32_t coef_splitted[2];
|
|
||||||
int32_t dsp_interleave_type;
|
|
||||||
int32_t coef_type;
|
|
||||||
int skip_samples_mode, atrac3_mode, xma_mode;
|
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
coding_t coding;
|
|
||||||
genh_type type;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
if (!check_extensions(streamFile,"genh")) goto fail;
|
if (!check_extensions(streamFile,"genh")) goto fail;
|
||||||
@ -55,12 +76,13 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
/* check header magic */
|
/* check header magic */
|
||||||
if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail;
|
if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail;
|
||||||
|
|
||||||
channel_count = read_32bitLE(0x4,streamFile);
|
/* process the header */
|
||||||
if (channel_count < 1) goto fail;
|
if (!parse_genh(streamFile, &genh))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
|
||||||
type = read_32bitLE(0x18,streamFile);
|
|
||||||
/* type to coding conversion */
|
/* type to coding conversion */
|
||||||
switch (type) {
|
switch (genh.codec) {
|
||||||
case PSX: coding = coding_PSX; break;
|
case PSX: coding = coding_PSX; break;
|
||||||
case XBOX: coding = coding_XBOX; break;
|
case XBOX: coding = coding_XBOX; break;
|
||||||
case NGC_DTK: coding = coding_NGC_DTK; break;
|
case NGC_DTK: coding = coding_NGC_DTK; break;
|
||||||
@ -86,68 +108,27 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
case ATRAC3PLUS:
|
case ATRAC3PLUS:
|
||||||
case XMA1:
|
case XMA1:
|
||||||
case XMA2:
|
case XMA2:
|
||||||
|
case AC3:
|
||||||
case FFMPEG: coding = coding_FFmpeg; break;
|
case FFMPEG: coding = coding_FFmpeg; break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
start_offset = read_32bitLE(0x1C,streamFile);
|
|
||||||
header_size = read_32bitLE(0x20,streamFile);
|
|
||||||
|
|
||||||
/* HACK to support old genh */
|
|
||||||
if (header_size == 0) {
|
|
||||||
start_offset = 0x800;
|
|
||||||
header_size = 0x800;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for audio data start past header end */
|
|
||||||
if (header_size > start_offset) goto fail;
|
|
||||||
|
|
||||||
interleave = read_32bitLE(0x8,streamFile);
|
|
||||||
sample_rate = read_32bitLE(0xc,streamFile);
|
|
||||||
loop_start = read_32bitLE(0x10,streamFile);
|
|
||||||
loop_end = read_32bitLE(0x14,streamFile);
|
|
||||||
|
|
||||||
coef[0] = read_32bitLE(0x24,streamFile);
|
|
||||||
coef[1] = read_32bitLE(0x28,streamFile);
|
|
||||||
dsp_interleave_type = read_32bitLE(0x2C,streamFile);
|
|
||||||
|
|
||||||
/* DSP coefficient variants */
|
|
||||||
/* bit 0 - split coefs (2 arrays) */
|
|
||||||
/* bit 1 - little endian coefs */
|
|
||||||
coef_type = read_32bitLE(0x30,streamFile);
|
|
||||||
/* when using split coefficients, 2nd array is at: */
|
|
||||||
coef_splitted[0] = read_32bitLE(0x34,streamFile);
|
|
||||||
coef_splitted[1] = read_32bitLE(0x38,streamFile);
|
|
||||||
|
|
||||||
/* other fields */
|
|
||||||
num_samples = read_32bitLE(0x40,streamFile);
|
|
||||||
skip_samples = read_32bitLE(0x44,streamFile); /* for FFmpeg based codecs */
|
|
||||||
skip_samples_mode = read_8bit(0x48,streamFile); /* 0=autodetect, 1=force manual value @ 0x44 */
|
|
||||||
atrac3_mode = read_8bit(0x49,streamFile); /* 0=autodetect, 1=force joint stereo, 2=force full stereo */
|
|
||||||
xma_mode = read_8bit(0x4a,streamFile); /* 0=default (4ch = 2ch + 2ch), 1=single (4ch = 1ch + 1ch + 1ch + 1ch) */
|
|
||||||
datasize = read_32bitLE(0x50,streamFile);
|
|
||||||
if (!datasize)
|
|
||||||
datasize = get_streamfile_size(streamFile)-start_offset;
|
|
||||||
|
|
||||||
num_samples = num_samples > 0 ? num_samples : loop_end;
|
|
||||||
loop_flag = loop_start != -1;
|
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(genh.channels,genh.loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
vgmstream->sample_rate = sample_rate;
|
vgmstream->sample_rate = genh.sample_rate;
|
||||||
vgmstream->num_samples = num_samples;
|
vgmstream->num_samples = genh.num_samples;
|
||||||
vgmstream->loop_start_sample = loop_start;
|
vgmstream->loop_start_sample = genh.loop_start_sample;
|
||||||
vgmstream->loop_end_sample = loop_end;
|
vgmstream->loop_end_sample = genh.loop_end_sample;
|
||||||
|
|
||||||
/* codec specific */
|
/* codec specific */
|
||||||
switch (coding) {
|
switch (coding) {
|
||||||
case coding_PCM8_U_int:
|
case coding_PCM8_U_int:
|
||||||
vgmstream->layout_type=layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_PCM16LE:
|
case coding_PCM16LE:
|
||||||
case coding_PCM16BE:
|
case coding_PCM16BE:
|
||||||
@ -160,14 +141,14 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
case coding_IMA:
|
case coding_IMA:
|
||||||
case coding_AICA:
|
case coding_AICA:
|
||||||
case coding_APPLE_IMA4:
|
case coding_APPLE_IMA4:
|
||||||
vgmstream->interleave_block_size = interleave;
|
vgmstream->interleave_block_size = genh.interleave;
|
||||||
if (channel_count > 1)
|
if (vgmstream->channels > 1)
|
||||||
{
|
{
|
||||||
if (coding == coding_SDX2) {
|
if (coding == coding_SDX2) {
|
||||||
coding = coding_SDX2_int;
|
coding = coding_SDX2_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vgmstream->interleave_block_size==0xffffffff) {
|
if (vgmstream->interleave_block_size==0xffffffff) {// || vgmstream->interleave_block_size == 0) {
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -179,7 +160,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* to avoid endless loops */
|
/* to avoid endless loops */
|
||||||
if (!interleave && (
|
if (!genh.interleave && (
|
||||||
coding == coding_PSX ||
|
coding == coding_PSX ||
|
||||||
coding == coding_PSX_badflags ||
|
coding == coding_PSX_badflags ||
|
||||||
coding == coding_IMA_int ||
|
coding == coding_IMA_int ||
|
||||||
@ -194,64 +175,61 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
/* setup adpcm */
|
/* setup adpcm */
|
||||||
if (coding == coding_AICA) {
|
if (coding == coding_AICA) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<channel_count;i++) {
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
vgmstream->ch[i].adpcm_step_index = 0x7f;
|
vgmstream->ch[i].adpcm_step_index = 0x7f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case coding_MS_IMA:
|
case coding_MS_IMA:
|
||||||
if (!interleave) goto fail; /* creates garbage */
|
if (!genh.interleave) goto fail; /* creates garbage */
|
||||||
|
|
||||||
vgmstream->interleave_block_size = interleave;
|
vgmstream->interleave_block_size = genh.interleave;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_MSADPCM:
|
case coding_MSADPCM:
|
||||||
if (channel_count > 2) goto fail;
|
if (vgmstream->channels > 2) goto fail;
|
||||||
if (!interleave) goto fail; /* creates garbage */
|
if (!genh.interleave) goto fail; /* creates garbage */
|
||||||
|
|
||||||
vgmstream->interleave_block_size = interleave;
|
vgmstream->interleave_block_size = genh.interleave;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_XBOX:
|
case coding_XBOX:
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_NGC_DTK:
|
case coding_NGC_DTK:
|
||||||
if (channel_count != 2) goto fail;
|
if (vgmstream->channels != 2) goto fail;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_NGC_DSP:
|
case coding_NGC_DSP:
|
||||||
if (dsp_interleave_type == 0) {
|
if (genh.coef_interleave_type == 0) {
|
||||||
if (!interleave) goto fail;
|
if (!genh.interleave) goto fail;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = interleave;
|
vgmstream->interleave_block_size = genh.interleave;
|
||||||
} else if (dsp_interleave_type == 1) {
|
} else if (genh.coef_interleave_type == 1) {
|
||||||
if (!interleave) goto fail;
|
if (!genh.interleave) goto fail;
|
||||||
vgmstream->layout_type = layout_interleave_byte;
|
vgmstream->layout_type = layout_interleave_byte;
|
||||||
vgmstream->interleave_block_size = interleave;
|
vgmstream->interleave_block_size = genh.interleave;
|
||||||
} else if (dsp_interleave_type == 2) {
|
} else if (genh.coef_interleave_type == 2) {
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
}
|
}// else {
|
||||||
|
// goto fail;
|
||||||
|
//}
|
||||||
|
|
||||||
/* get coefs */
|
/* get coefs */
|
||||||
for (i=0;i<channel_count;i++) {
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
int16_t (*read_16bit)(off_t , STREAMFILE*);
|
int16_t (*read_16bit)(off_t , STREAMFILE*) = genh.coef_big_endian ? read_16bitBE : read_16bitLE;
|
||||||
/* bit 1 - little endian coefs */
|
|
||||||
if ((coef_type & 2) == 0) {
|
|
||||||
read_16bit = read_16bitBE;
|
|
||||||
} else {
|
|
||||||
read_16bit = read_16bitLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bit 0 - split coefs (2 arrays) */
|
/* normal/split coefs */
|
||||||
if ((coef_type & 1) == 0) {
|
if ((genh.coef_type & 1) == 0) { /* bit 0 - split coefs (2 arrays) */
|
||||||
for (j=0;j<16;j++) {
|
for (j=0;j<16;j++) {
|
||||||
vgmstream->ch[i].adpcm_coef[j] = read_16bit(coef[i]+j*2,streamFile);
|
vgmstream->ch[i].adpcm_coef[j] = read_16bit(genh.coef[i]+j*2,streamFile);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
for (j=0;j<8;j++) {
|
for (j=0;j<8;j++) {
|
||||||
vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(coef[i]+j*2,streamFile);
|
vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(genh.coef[i]+j*2,streamFile);
|
||||||
vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(coef_splitted[i]+j*2,streamFile);
|
vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(genh.coef_splitted[i]+j*2,streamFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,7 +238,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
#ifdef VGM_USE_MPEG
|
#ifdef VGM_USE_MPEG
|
||||||
case coding_MPEG_layer3:
|
case coding_MPEG_layer3:
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->codec_data = init_mpeg_codec_data(streamFile, start_offset, &coding, vgmstream->channels);
|
vgmstream->codec_data = init_mpeg_codec_data(streamFile, genh.start_offset, &coding, vgmstream->channels);
|
||||||
if (!vgmstream->codec_data) goto fail;
|
if (!vgmstream->codec_data) goto fail;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -269,50 +247,53 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
case coding_FFmpeg: {
|
case coding_FFmpeg: {
|
||||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
|
||||||
if (type == FFMPEG) {
|
if (genh.codec == FFMPEG || genh.codec == AC3) {
|
||||||
/* default FFmpeg */
|
/* default FFmpeg */
|
||||||
ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,datasize);
|
ffmpeg_data = init_ffmpeg_offset(streamFile, genh.start_offset,genh.data_size);
|
||||||
if ( !ffmpeg_data ) goto fail;
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
|
||||||
|
//if (vgmstream->num_samples == 0)
|
||||||
|
// vgmstream->num_samples = ffmpeg_data->totalSamples; /* sometimes works */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* fake header FFmpeg */
|
/* fake header FFmpeg */
|
||||||
uint8_t buf[200];
|
uint8_t buf[200];
|
||||||
int32_t bytes;
|
int32_t bytes;
|
||||||
|
|
||||||
if (type == ATRAC3) {
|
if (genh.codec == ATRAC3) {
|
||||||
int block_size = interleave;
|
int block_size = genh.interleave;
|
||||||
int joint_stereo;
|
int joint_stereo;
|
||||||
switch(atrac3_mode) {
|
switch(genh.codec_mode) {
|
||||||
case 0: joint_stereo = vgmstream->channels > 1 && interleave/vgmstream->channels==0x60 ? 1 : 0; break; /* autodetect */
|
case 0: joint_stereo = vgmstream->channels > 1 && genh.interleave/vgmstream->channels==0x60 ? 1 : 0; break; /* autodetect */
|
||||||
case 1: joint_stereo = 1; break; /* force joint stereo */
|
case 1: joint_stereo = 1; break; /* force joint stereo */
|
||||||
case 2: joint_stereo = 0; break; /* force stereo */
|
case 2: joint_stereo = 0; break; /* force stereo */
|
||||||
default: goto fail;
|
default: goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = ffmpeg_make_riff_atrac3(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, skip_samples);
|
bytes = ffmpeg_make_riff_atrac3(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, genh.skip_samples);
|
||||||
}
|
}
|
||||||
else if (type == ATRAC3PLUS) {
|
else if (genh.codec == ATRAC3PLUS) {
|
||||||
int block_size = interleave;
|
int block_size = genh.interleave;
|
||||||
|
|
||||||
bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, skip_samples);
|
bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, genh.skip_samples);
|
||||||
}
|
}
|
||||||
else if (type == XMA1) {
|
else if (genh.codec == XMA1) {
|
||||||
int xma_stream_mode = xma_mode == 1 ? 1 : 0;
|
int xma_stream_mode = genh.codec_mode == 1 ? 1 : 0;
|
||||||
|
|
||||||
bytes = ffmpeg_make_riff_xma1(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode);
|
bytes = ffmpeg_make_riff_xma1(buf, 100, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode);
|
||||||
}
|
}
|
||||||
else if (type == XMA2) {
|
else if (genh.codec == XMA2) {
|
||||||
int block_size = interleave ? interleave : 2048;
|
int block_size = genh.interleave ? genh.interleave : 2048;
|
||||||
int block_count = datasize / block_size;
|
int block_count = genh.data_size / block_size;
|
||||||
|
|
||||||
bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (bytes <= 0) goto fail;
|
if (bytes <= 0) goto fail;
|
||||||
|
|
||||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size);
|
||||||
if ( !ffmpeg_data ) goto fail;
|
if ( !ffmpeg_data ) goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,8 +301,8 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
/* force encoder delay */
|
/* force encoder delay */
|
||||||
if (skip_samples_mode && skip_samples >= 0) {
|
if (genh.skip_samples_mode && genh.skip_samples >= 0) {
|
||||||
ffmpeg_set_skip_samples(ffmpeg_data, skip_samples);
|
ffmpeg_set_skip_samples(ffmpeg_data, genh.skip_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -335,7 +316,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
vgmstream->meta_type = meta_GENH;
|
vgmstream->meta_type = meta_GENH;
|
||||||
|
|
||||||
|
|
||||||
if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) )
|
if ( !vgmstream_open_stream(vgmstream,streamFile,genh.start_offset) )
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
@ -344,3 +325,60 @@ fail:
|
|||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int parse_genh(STREAMFILE * streamFile, genh_header * genh) {
|
||||||
|
size_t header_size;
|
||||||
|
|
||||||
|
genh->channels = read_32bitLE(0x4,streamFile);
|
||||||
|
|
||||||
|
genh->interleave = read_32bitLE(0x8,streamFile);
|
||||||
|
genh->sample_rate = read_32bitLE(0xc,streamFile);
|
||||||
|
genh->loop_start_sample = read_32bitLE(0x10,streamFile);
|
||||||
|
genh->loop_end_sample = read_32bitLE(0x14,streamFile);
|
||||||
|
|
||||||
|
genh->codec = read_32bitLE(0x18,streamFile);
|
||||||
|
genh->start_offset = read_32bitLE(0x1C,streamFile);
|
||||||
|
header_size = read_32bitLE(0x20,streamFile);
|
||||||
|
/* HACK to support old genh */
|
||||||
|
if (header_size == 0) {
|
||||||
|
genh->start_offset = 0x800;
|
||||||
|
header_size = 0x800;
|
||||||
|
}
|
||||||
|
/* check for audio data start past header end */
|
||||||
|
if (header_size > genh->start_offset) goto fail;
|
||||||
|
|
||||||
|
genh->coef[0] = read_32bitLE(0x24,streamFile);
|
||||||
|
genh->coef[1] = read_32bitLE(0x28,streamFile);
|
||||||
|
genh->coef_interleave_type = read_32bitLE(0x2C,streamFile);
|
||||||
|
|
||||||
|
/* DSP coefficient variants */
|
||||||
|
/* bit 0 - split coefs (2 arrays) */
|
||||||
|
/* bit 1 - little endian coefs */
|
||||||
|
genh->coef_type = read_32bitLE(0x30,streamFile);
|
||||||
|
genh->coef_big_endian = ((genh->coef_type & 2) == 0);
|
||||||
|
|
||||||
|
/* when using split coefficients, 2nd array is at: */
|
||||||
|
genh->coef_splitted[0] = read_32bitLE(0x34,streamFile);
|
||||||
|
genh->coef_splitted[1] = read_32bitLE(0x38,streamFile);
|
||||||
|
|
||||||
|
/* other fields */
|
||||||
|
genh->num_samples = read_32bitLE(0x40,streamFile);
|
||||||
|
genh->skip_samples = read_32bitLE(0x44,streamFile); /* for FFmpeg based codecs */
|
||||||
|
genh->skip_samples_mode = read_8bit(0x48,streamFile); /* 0=autodetect, 1=force manual value @ 0x44 */
|
||||||
|
if (genh->codec == ATRAC3 || genh->codec == ATRAC3PLUS)
|
||||||
|
genh->codec_mode = read_8bit(0x49,streamFile); /* 0=autodetect, 1=force joint stereo, 2=force full stereo */
|
||||||
|
if (genh->codec == XMA1 || genh->codec == XMA2)
|
||||||
|
genh->codec_mode = read_8bit(0x4a,streamFile); /* 0=default (4ch = 2ch + 2ch), 1=single (4ch = 1ch + 1ch + 1ch + 1ch) */
|
||||||
|
genh->data_size = read_32bitLE(0x50,streamFile);
|
||||||
|
if (genh->data_size == 0)
|
||||||
|
genh->data_size = get_streamfile_size(streamFile) - genh->start_offset;
|
||||||
|
|
||||||
|
genh->num_samples = genh->num_samples > 0 ? genh->num_samples : genh->loop_end_sample;
|
||||||
|
genh->loop_flag = genh->loop_start_sample != -1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -276,8 +276,6 @@ VGMSTREAM * init_vgmstream_ps2_omu(STREAMFILE *streamFile);
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ps2_xa2(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_ps2_xa2(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE * streamFile);
|
|
||||||
|
|
||||||
//VGMSTREAM * init_vgmstream_idsp(STREAMFILE * streamFile);
|
//VGMSTREAM * init_vgmstream_idsp(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_idsp2(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_idsp2(STREAMFILE * streamFile);
|
||||||
@ -581,6 +579,7 @@ VGMSTREAM * init_vgmstream_hyperscan_kvag(STREAMFILE* streamFile);
|
|||||||
VGMSTREAM * init_vgmstream_ios_psnd(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_ios_psnd(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_eb_sfx(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_eb_sfx(STREAMFILE* streamFile);
|
||||||
|
@ -19,11 +19,11 @@ VGMSTREAM * init_vgmstream_nds_strm(STREAMFILE *streamFile) {
|
|||||||
if (strcasecmp("strm",filename_extension(filename))) goto fail;
|
if (strcasecmp("strm",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if ((uint32_t)read_32bitBE(0x00,streamFile)!=0x5354524D) /* STRM */
|
if ((uint32_t)read_32bitBE(0x00,streamFile)!=0x5354524D) /* STRM */
|
||||||
|
goto fail;
|
||||||
|
if ((uint32_t)read_32bitBE(0x04,streamFile)!=0xFFFE0001 && /* Old Header Check */
|
||||||
|
((uint32_t)read_32bitBE(0x04,streamFile)!=0xFEFF0001)) /* Some newer games have a new flag */
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((uint32_t)read_32bitBE(0x04,streamFile)!=0xFFFE0001 && /* Old Header Check */
|
|
||||||
((uint32_t)read_32bitBE(0x04,streamFile)!=0xFEFF0001)) /* Some newer games have a new flag */
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
/* .dsp found in:
|
/* .dsp found in:
|
||||||
Hikaru No Go 3 (NGC)
|
Hikaru No Go 3 (NGC)
|
||||||
Yu-Gi-Oh! The Falsebound Kingdom (NGC)
|
Yu-Gi-Oh! The Falsebound Kingdom (NGC)
|
||||||
|
|
||||||
2010-01-31 - added loop stuff and some header checks...
|
2010-01-31 - added loop stuff and some header checks...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -24,29 +24,29 @@ VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) {
|
|||||||
if ((read_32bitBE(0x0,streamFile)+0xE0) != (get_streamfile_size(streamFile)))
|
if ((read_32bitBE(0x0,streamFile)+0xE0) != (get_streamfile_size(streamFile)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (uint16_t)(read_16bitBE(0x2C,streamFile) != 0x0);
|
loop_flag = (uint16_t)(read_16bitBE(0x2C,streamFile) != 0x0);
|
||||||
channel_count = 1;
|
channel_count = 1;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0xE0;
|
start_offset = 0xE0;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
|
||||||
vgmstream->coding_type = coding_NGC_DSP;
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
vgmstream->num_samples = read_32bitBE(0x20,streamFile);
|
vgmstream->num_samples = read_32bitBE(0x20,streamFile);
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->meta_type = meta_DSP_YGO;
|
vgmstream->meta_type = meta_DSP_YGO;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile)*14/16);
|
vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile)*14/16);
|
||||||
vgmstream->loop_end_sample = (read_32bitBE(0x34,streamFile)*14/16);
|
vgmstream->loop_end_sample = (read_32bitBE(0x34,streamFile)*14/16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read coef stuff
|
// read coef stuff
|
||||||
{
|
{
|
||||||
for (i=0;i<16;i++) {
|
for (i=0;i<16;i++) {
|
||||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile);
|
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,63 +8,63 @@
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
STREAMFILE * streamFileDSP = NULL;
|
STREAMFILE * streamFileDSP = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
char filenameDSP[PATH_LIMIT];
|
char filenameDSP[PATH_LIMIT];
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("sck",filename_extension(filename))) goto fail;
|
if (strcasecmp("sck",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
|
|
||||||
strcpy(filenameDSP,filename);
|
strcpy(filenameDSP,filename);
|
||||||
strcpy(filenameDSP+strlen(filenameDSP)-3,"dsp");
|
strcpy(filenameDSP+strlen(filenameDSP)-3,"dsp");
|
||||||
|
|
||||||
|
streamFileDSP = streamFile->open(streamFile,filenameDSP,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
|
||||||
streamFileDSP = streamFile->open(streamFile,filenameDSP,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
if (read_32bitBE(0x5C,streamFile) != 0x60A94000)
|
if (read_32bitBE(0x5C,streamFile) != 0x60A94000)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!streamFile) goto fail;
|
if (!streamFile) goto fail;
|
||||||
|
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x18,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x18,streamFile);
|
||||||
vgmstream->num_samples=read_32bitBE(0x14,streamFile)/8/channel_count*14;
|
vgmstream->num_samples=read_32bitBE(0x14,streamFile)/8/channel_count*14;
|
||||||
vgmstream->coding_type = coding_NGC_DSP;
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
|
|
||||||
if(loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = 0;
|
|
||||||
vgmstream->loop_end_sample = read_32bitBE(0x10,streamFile)/8/channel_count*14;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel_count == 1) {
|
if(loop_flag) {
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->loop_start_sample = 0;
|
||||||
} else if (channel_count == 2) {
|
vgmstream->loop_end_sample = read_32bitBE(0x10,streamFile)/8/channel_count*14;
|
||||||
vgmstream->layout_type = layout_interleave;
|
}
|
||||||
vgmstream->interleave_block_size=read_32bitBE(0xC,streamFile);
|
|
||||||
}
|
if (channel_count == 1) {
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
} else if (channel_count == 2) {
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size=read_32bitBE(0xC,streamFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vgmstream->meta_type = meta_NGC_SCK_DSP;
|
vgmstream->meta_type = meta_NGC_SCK_DSP;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
for (i=0;i<channel_count;i++) {
|
for (i=0;i<channel_count;i++) {
|
||||||
/* Not sure, i'll put a fake value here for now */
|
/* Not sure, i'll put a fake value here for now */
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFileDSP,filenameDSP,0x8000);
|
vgmstream->ch[i].streamfile = streamFile->open(streamFileDSP,filenameDSP,0x8000);
|
||||||
vgmstream->ch[i].offset = 0;
|
vgmstream->ch[i].offset = 0;
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<16;i++) {
|
for (i=0;i<16;i++) {
|
||||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x2C+i*2,streamFile);
|
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x2C+i*2,streamFile);
|
||||||
@ -87,7 +87,7 @@ VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
close_streamfile(streamFileDSP); streamFileDSP=NULL;
|
close_streamfile(streamFileDSP); streamFileDSP=NULL;
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
/* clean up anything we may have opened */
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* ADP - from Balls of Steel */
|
/* ADP - from Balls of Steel */
|
||||||
VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE *streamFile) {
|
||||||
@ -48,45 +47,3 @@ fail:
|
|||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ADP - from Omikron: The Nomad Soul (PC/DC) */
|
|
||||||
VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE *streamFile) {
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
off_t start_offset, datasize;
|
|
||||||
int loop_flag = 0, channel_count, stereo_flag;
|
|
||||||
|
|
||||||
if (!check_extensions(streamFile,"adp")) goto fail;
|
|
||||||
|
|
||||||
/* no ID, only a basic 0x10 header with filesize and nulls; do some extra checks */
|
|
||||||
datasize = read_32bitLE(0x00,streamFile) & 0x00FFFFFF; /*24 bit*/
|
|
||||||
if (datasize + 0x10 != streamFile->get_size(streamFile)
|
|
||||||
|| read_32bitLE(0x04,streamFile) != 0
|
|
||||||
|| read_32bitLE(0x08,streamFile) != 0
|
|
||||||
|| read_32bitLE(0x0c,streamFile) != 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
stereo_flag = read_8bit(0x03, streamFile);
|
|
||||||
if (stereo_flag > 1 || stereo_flag < 0) goto fail;
|
|
||||||
channel_count = stereo_flag ? 2 : 1;
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
start_offset = 0x10;
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
vgmstream->sample_rate = 22050;
|
|
||||||
vgmstream->num_samples = channel_count== 1 ? datasize*2 : datasize;
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_OTNS_IMA;
|
|
||||||
vgmstream->layout_type = layout_none;
|
|
||||||
vgmstream->meta_type = meta_OTNS_ADP;
|
|
||||||
|
|
||||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
|
||||||
goto fail;
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
43
src/meta/pc_adp_otns.c
Normal file
43
src/meta/pc_adp_otns.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
/* ADP - from Omikron: The Nomad Soul (PC/DC) */
|
||||||
|
VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset, datasize;
|
||||||
|
int loop_flag = 0, channel_count, stereo_flag;
|
||||||
|
|
||||||
|
if (!check_extensions(streamFile,"adp")) goto fail;
|
||||||
|
|
||||||
|
/* no ID, only a basic 0x10 header with filesize and nulls; do some extra checks */
|
||||||
|
datasize = read_32bitLE(0x00,streamFile) & 0x00FFFFFF; /*24 bit*/
|
||||||
|
if (datasize + 0x10 != streamFile->get_size(streamFile)
|
||||||
|
|| read_32bitLE(0x04,streamFile) != 0
|
||||||
|
|| read_32bitLE(0x08,streamFile) != 0
|
||||||
|
|| read_32bitLE(0x0c,streamFile) != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
stereo_flag = read_8bit(0x03, streamFile);
|
||||||
|
if (stereo_flag > 1 || stereo_flag < 0) goto fail;
|
||||||
|
channel_count = stereo_flag ? 2 : 1;
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
start_offset = 0x10;
|
||||||
|
vgmstream->channels = channel_count;
|
||||||
|
vgmstream->sample_rate = 22050;
|
||||||
|
vgmstream->num_samples = channel_count== 1 ? datasize*2 : datasize;
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_OTNS_IMA;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
vgmstream->meta_type = meta_OTNS_ADP;
|
||||||
|
|
||||||
|
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||||
|
goto fail;
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -4,41 +4,41 @@
|
|||||||
/* PCM (from Lunar: Eternal Blue (Sega CD) */
|
/* PCM (from Lunar: Eternal Blue (Sega CD) */
|
||||||
VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x0,streamFile) != 0x00020000)
|
if (read_32bitBE(0x0,streamFile) != 0x00020000)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x02,streamFile)!=0);
|
loop_flag = (read_32bitLE(0x02,streamFile)!=0);
|
||||||
channel_count = 1;
|
channel_count = 1;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* build the VGMSTREAM */
|
||||||
start_offset = 0x200;
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
vgmstream->channels = channel_count;
|
if (!vgmstream) goto fail;
|
||||||
vgmstream->sample_rate = 32000;
|
|
||||||
vgmstream->coding_type = coding_PCM8_SB_int;
|
/* fill in the vital statistics */
|
||||||
vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2;
|
start_offset = 0x200;
|
||||||
if(loop_flag) {
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*0x400*2;
|
vgmstream->sample_rate = 32000;
|
||||||
vgmstream->loop_end_sample = read_32bitBE(0x06,streamFile)*2;
|
vgmstream->coding_type = coding_PCM8_SB_int;
|
||||||
}
|
vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2;
|
||||||
vgmstream->layout_type = layout_interleave;
|
if(loop_flag) {
|
||||||
vgmstream->interleave_block_size = 0x1;
|
vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*0x400*2;
|
||||||
vgmstream->meta_type = meta_PCM_SCD;
|
vgmstream->loop_end_sample = read_32bitBE(0x06,streamFile)*2;
|
||||||
|
}
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = 0x1;
|
||||||
|
vgmstream->meta_type = meta_PCM_SCD;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
@ -54,7 +54,7 @@ VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
/* clean up anything we may have opened */
|
||||||
fail:
|
fail:
|
||||||
@ -64,41 +64,41 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
/* PCM - Custom header from Konami, which contains only loop infos...
|
/* PCM - Custom header from Konami, which contains only loop infos...
|
||||||
found in: Ephemeral Fantasia [Reiselied]
|
found in: Ephemeral Fantasia [Reiselied]
|
||||||
Yu-Gi-Oh! The Duelists of the Roses [Yu-Gi-Oh! Shin Duel Monsters II]
|
Yu-Gi-Oh! The Duelists of the Roses [Yu-Gi-Oh! Shin Duel Monsters II]
|
||||||
*/
|
*/
|
||||||
VGMSTREAM * init_vgmstream_pcm_ps2(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_pcm_ps2(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
// if ((read_32bitLE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile)))
|
// if ((read_32bitLE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile)))
|
||||||
// goto fail;
|
// goto fail;
|
||||||
if ((read_32bitLE(0x00,streamFile)) != (read_32bitLE(0x04,streamFile)*4))
|
if ((read_32bitLE(0x00,streamFile)) != (read_32bitLE(0x04,streamFile)*4))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x08,streamFile) != 0x0);
|
loop_flag = (read_32bitLE(0x08,streamFile) != 0x0);
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x800;
|
start_offset = 0x800;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = 24000;
|
vgmstream->sample_rate = 24000;
|
||||||
vgmstream->coding_type = coding_PCM16LE;
|
vgmstream->coding_type = coding_PCM16LE;
|
||||||
vgmstream->num_samples = read_32bitLE(0x0,streamFile)/2/channel_count;
|
vgmstream->num_samples = read_32bitLE(0x0,streamFile)/2/channel_count;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile);
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile);
|
vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
@ -9,17 +9,17 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
int loop_flag=0;
|
int loop_flag=0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
off_t check_offset;
|
off_t check_offset;
|
||||||
int32_t streamSize;
|
int32_t streamSize;
|
||||||
|
|
||||||
uint8_t testBuffer[0x10];
|
uint8_t testBuffer[0x10];
|
||||||
uint8_t isPCM = 0;
|
uint8_t isPCM = 0;
|
||||||
|
|
||||||
off_t readOffset = 0;
|
off_t readOffset = 0;
|
||||||
off_t loopEnd = 0;
|
off_t loopEnd = 0;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -35,27 +35,27 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check if file is not corrupt */
|
/* check if file is not corrupt */
|
||||||
/* seems the Gran Turismo 4 ADS files are considered corrupt,*/
|
/* seems the Gran Turismo 4 ADS files are considered corrupt,*/
|
||||||
/* so I changed it to adapt the stream size if that's the case */
|
/* so I changed it to adapt the stream size if that's the case */
|
||||||
/* instead of failing playing them at all*/
|
/* instead of failing playing them at all*/
|
||||||
streamSize = read_32bitLE(0x24,streamFile);
|
streamSize = read_32bitLE(0x24,streamFile);
|
||||||
|
|
||||||
if (get_streamfile_size(streamFile) < (size_t)(streamSize + 0x28))
|
if (get_streamfile_size(streamFile) < (size_t)(streamSize + 0x28))
|
||||||
{
|
{
|
||||||
streamSize = get_streamfile_size(streamFile) - 0x28;
|
streamSize = get_streamfile_size(streamFile) - 0x28;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check loop */
|
/* check loop */
|
||||||
if ((read_32bitLE(0x1C,streamFile) == 0xFFFFFFFF) ||
|
if ((read_32bitLE(0x1C,streamFile) == 0xFFFFFFFF) ||
|
||||||
((read_32bitLE(0x18,streamFile) == 0) && (read_32bitLE(0x1C,streamFile) == 0)))
|
((read_32bitLE(0x18,streamFile) == 0) && (read_32bitLE(0x1C,streamFile) == 0)))
|
||||||
{
|
{
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loop_flag = 1;
|
loop_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_count=read_32bitLE(0x10,streamFile);
|
channel_count=read_32bitLE(0x10,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
@ -70,9 +70,9 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) {
|
|||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((streamSize-0x40)/16*28)/vgmstream->channels;
|
vgmstream->num_samples = ((streamSize-0x40)/16*28)/vgmstream->channels;
|
||||||
|
|
||||||
/* SS2 container with RAW Interleaved PCM */
|
/* SS2 container with RAW Interleaved PCM */
|
||||||
if (read_32bitLE(0x08,streamFile)!=0x10)
|
if (read_32bitLE(0x08,streamFile)!=0x10)
|
||||||
{
|
{
|
||||||
|
|
||||||
vgmstream->coding_type=coding_PCM16LE;
|
vgmstream->coding_type=coding_PCM16LE;
|
||||||
vgmstream->num_samples = streamSize/2/vgmstream->channels;
|
vgmstream->num_samples = streamSize/2/vgmstream->channels;
|
||||||
@ -84,100 +84,100 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
/* Get loop point values */
|
/* Get loop point values */
|
||||||
if(vgmstream->loop_flag) {
|
if(vgmstream->loop_flag) {
|
||||||
if((read_32bitLE(0x1C,streamFile)*0x10*vgmstream->channels+0x800)==get_streamfile_size(streamFile))
|
if((read_32bitLE(0x1C,streamFile)*0x10*vgmstream->channels+0x800)==get_streamfile_size(streamFile))
|
||||||
{
|
{
|
||||||
// Search for Loop Value
|
// Search for Loop Value
|
||||||
readOffset=(off_t)get_streamfile_size(streamFile)-(4*vgmstream->interleave_block_size);
|
readOffset=(off_t)get_streamfile_size(streamFile)-(4*vgmstream->interleave_block_size);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile);
|
readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile);
|
||||||
|
|
||||||
// Loop End ...
|
|
||||||
if(testBuffer[0x01]==0x01) {
|
|
||||||
if(loopEnd==0) loopEnd = readOffset-0x10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (streamFile->get_offset(streamFile)<(int32_t)get_streamfile_size(streamFile));
|
// Loop End ...
|
||||||
|
if(testBuffer[0x01]==0x01) {
|
||||||
|
if(loopEnd==0) loopEnd = readOffset-0x10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
vgmstream->loop_start_sample = 0;
|
} while (streamFile->get_offset(streamFile)<(int32_t)get_streamfile_size(streamFile));
|
||||||
vgmstream->loop_end_sample = (loopEnd/(vgmstream->interleave_block_size)*vgmstream->interleave_block_size)/16*28;
|
|
||||||
vgmstream->loop_end_sample += (loopEnd%vgmstream->interleave_block_size)/16*28;
|
|
||||||
vgmstream->loop_end_sample /=vgmstream->channels;
|
|
||||||
|
|
||||||
} else {
|
vgmstream->loop_start_sample = 0;
|
||||||
if(read_32bitLE(0x1C,streamFile)<=vgmstream->num_samples) {
|
vgmstream->loop_end_sample = (loopEnd/(vgmstream->interleave_block_size)*vgmstream->interleave_block_size)/16*28;
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x18,streamFile);
|
vgmstream->loop_end_sample += (loopEnd%vgmstream->interleave_block_size)/16*28;
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x1C,streamFile);
|
vgmstream->loop_end_sample /=vgmstream->channels;
|
||||||
} else {
|
|
||||||
vgmstream->loop_start_sample = (read_32bitLE(0x18,streamFile)*0x10)/16*28/vgmstream->channels;;
|
} else {
|
||||||
vgmstream->loop_end_sample = (read_32bitLE(0x1C,streamFile)*0x10)/16*28/vgmstream->channels;
|
if(read_32bitLE(0x1C,streamFile)<=vgmstream->num_samples) {
|
||||||
}
|
vgmstream->loop_start_sample = read_32bitLE(0x18,streamFile);
|
||||||
}
|
vgmstream->loop_end_sample = read_32bitLE(0x1C,streamFile);
|
||||||
|
} else {
|
||||||
|
vgmstream->loop_start_sample = (read_32bitLE(0x18,streamFile)*0x10)/16*28/vgmstream->channels;;
|
||||||
|
vgmstream->loop_end_sample = (read_32bitLE(0x1C,streamFile)*0x10)/16*28/vgmstream->channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't know why, but it does happen, in ps2 too :( */
|
/* don't know why, but it does happen, in ps2 too :( */
|
||||||
if (vgmstream->loop_end_sample > vgmstream->num_samples)
|
if (vgmstream->loop_end_sample > vgmstream->num_samples)
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
{
|
{
|
||||||
start_offset=0x28;
|
start_offset=0x28;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((streamSize * 2) == (get_streamfile_size(streamFile) - 0x18))
|
|
||||||
{
|
|
||||||
// True Fortune PS2
|
|
||||||
streamSize = (read_32bitLE(0x24,streamFile) * 2) - 0x10;
|
|
||||||
vgmstream->num_samples = streamSize / 16 * 28 / vgmstream->channels;
|
|
||||||
}
|
|
||||||
else if(get_streamfile_size(streamFile) - read_32bitLE(0x24,streamFile) >= 0x800)
|
|
||||||
{
|
|
||||||
// Hack for files with start_offset = 0x800
|
|
||||||
start_offset=0x800;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((vgmstream->coding_type == coding_PSX) && (start_offset==0x28))
|
if ((streamSize * 2) == (get_streamfile_size(streamFile) - 0x18))
|
||||||
{
|
{
|
||||||
start_offset=0x800;
|
// True Fortune PS2
|
||||||
|
streamSize = (read_32bitLE(0x24,streamFile) * 2) - 0x10;
|
||||||
for(i=0;i<0x1f6;i+=4)
|
vgmstream->num_samples = streamSize / 16 * 28 / vgmstream->channels;
|
||||||
{
|
}
|
||||||
if(read_32bitLE(0x28+(i*4),streamFile)!=0)
|
else if(get_streamfile_size(streamFile) - read_32bitLE(0x24,streamFile) >= 0x800)
|
||||||
{
|
{
|
||||||
start_offset=0x28;
|
// Hack for files with start_offset = 0x800
|
||||||
break;
|
start_offset=0x800;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we got a real pcm (ex: Clock Tower 3)
|
if((vgmstream->coding_type == coding_PSX) && (start_offset==0x28))
|
||||||
if(vgmstream->coding_type==coding_PCM16LE)
|
{
|
||||||
{
|
start_offset=0x800;
|
||||||
check_offset=start_offset;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(read_8bit(check_offset+1,streamFile)>7)
|
|
||||||
{
|
|
||||||
isPCM=1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
check_offset+=0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (check_offset<get_streamfile_size(streamFile));
|
|
||||||
|
|
||||||
if(!isPCM)
|
for(i=0;i<0x1f6;i+=4)
|
||||||
{
|
{
|
||||||
vgmstream->num_samples=(get_streamfile_size(streamFile)-start_offset)/16*28/vgmstream->channels;
|
if(read_32bitLE(0x28+(i*4),streamFile)!=0)
|
||||||
vgmstream->coding_type=coding_PSX;
|
{
|
||||||
}
|
start_offset=0x28;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* expect pcm format allways start @ 0x800, don't know if it's true :P */
|
// check if we got a real pcm (ex: Clock Tower 3)
|
||||||
/*if(vgmstream->coding_type == coding_PCM16LE)
|
if(vgmstream->coding_type==coding_PCM16LE)
|
||||||
start_offset=0x800;*/
|
{
|
||||||
|
check_offset=start_offset;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(read_8bit(check_offset+1,streamFile)>7)
|
||||||
|
{
|
||||||
|
isPCM=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
check_offset+=0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (check_offset<get_streamfile_size(streamFile));
|
||||||
|
|
||||||
|
if(!isPCM)
|
||||||
|
{
|
||||||
|
vgmstream->num_samples=(get_streamfile_size(streamFile)-start_offset)/16*28/vgmstream->channels;
|
||||||
|
vgmstream->coding_type=coding_PSX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expect pcm format allways start @ 0x800, don't know if it's true :P */
|
||||||
|
/*if(vgmstream->coding_type == coding_PCM16LE)
|
||||||
|
start_offset=0x800;*/
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading by each channel */
|
||||||
{
|
{
|
||||||
|
@ -8,8 +8,8 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -18,23 +18,23 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) {
|
|||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x0,streamFile) != 0x46494C70) /* "FILp" */
|
if (read_32bitBE(0x0,streamFile) != 0x46494C70) /* "FILp" */
|
||||||
goto fail;
|
goto fail;
|
||||||
if (read_32bitBE(0x100,streamFile) != 0x56414770) /* "VAGp" */
|
if (read_32bitBE(0x100,streamFile) != 0x56414770) /* "VAGp" */
|
||||||
goto fail;
|
goto fail;
|
||||||
if (read_32bitBE(0x130,streamFile) != 0x56414770) /* "VAGp" */
|
if (read_32bitBE(0x130,streamFile) != 0x56414770) /* "VAGp" */
|
||||||
|
goto fail;
|
||||||
|
if (get_streamfile_size(streamFile) != read_32bitLE(0xC,streamFile))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (get_streamfile_size(streamFile) != read_32bitLE(0xC,streamFile))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x34,streamFile) == 0);
|
loop_flag = (read_32bitLE(0x34,streamFile) == 0);
|
||||||
channel_count = read_32bitLE(0x4,streamFile);
|
channel_count = read_32bitLE(0x4,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x0;
|
start_offset = 0x0;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitLE(0x110,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x110,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->layout_type = layout_filp_blocked;
|
vgmstream->layout_type = layout_filp_blocked;
|
||||||
@ -47,9 +47,9 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) {
|
|||||||
if (!file) goto fail;
|
if (!file) goto fail;
|
||||||
for (i=0;i<channel_count;i++) {
|
for (i=0;i<channel_count;i++) {
|
||||||
vgmstream->ch[i].streamfile = file;
|
vgmstream->ch[i].streamfile = file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filp_block_update(start_offset,vgmstream);
|
filp_block_update(start_offset,vgmstream);
|
||||||
vgmstream->num_samples = read_32bitLE(0x10C,streamFile)/16*28;
|
vgmstream->num_samples = read_32bitLE(0x10C,streamFile)/16*28;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
@ -57,7 +57,7 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) {
|
|||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
/* clean up anything we may have opened */
|
||||||
|
@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_gcm(STREAMFILE *streamFile) {
|
|||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -17,19 +17,19 @@ VGMSTREAM * init_vgmstream_ps2_gcm(STREAMFILE *streamFile) {
|
|||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x4D434700) /* "MCG" */
|
if (read_32bitBE(0x00,streamFile) != 0x4D434700) /* "MCG" */
|
||||||
goto fail;
|
goto fail;
|
||||||
if (read_32bitBE(0x20,streamFile) != 0x56414770) /* "VAGp" */
|
if (read_32bitBE(0x20,streamFile) != 0x56414770) /* "VAGp" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
channel_count= 2;
|
channel_count= 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x80;
|
start_offset = 0x80;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x30,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x30,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = read_32bitLE(0x10,streamFile)*28/32;
|
vgmstream->num_samples = read_32bitLE(0x10,streamFile)*28/32;
|
||||||
|
@ -8,14 +8,14 @@ VGMSTREAM * init_vgmstream_ps2_hsf(STREAMFILE *streamFile)
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
size_t fileLength;
|
size_t fileLength;
|
||||||
size_t frequencyFlag;
|
size_t frequencyFlag;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
off_t readOffset = 0;
|
off_t readOffset = 0;
|
||||||
uint8_t testBuffer[0x10];
|
uint8_t testBuffer[0x10];
|
||||||
off_t loopEndOffset;
|
off_t loopEndOffset;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
@ -26,56 +26,56 @@ VGMSTREAM * init_vgmstream_ps2_hsf(STREAMFILE *streamFile)
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x48534600) // "HSF"
|
if (read_32bitBE(0x00,streamFile) != 0x48534600) // "HSF"
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
fileLength = get_streamfile_size(streamFile);
|
fileLength = get_streamfile_size(streamFile);
|
||||||
frequencyFlag = read_32bitLE(0x08, streamFile);
|
frequencyFlag = read_32bitLE(0x08, streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x10;
|
start_offset = 0x10;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
|
|
||||||
if (frequencyFlag == 0x0EB3)
|
if (frequencyFlag == 0x0EB3)
|
||||||
{
|
{
|
||||||
vgmstream->sample_rate = 44100;
|
vgmstream->sample_rate = 44100;
|
||||||
}
|
}
|
||||||
else if (frequencyFlag == 0x1000)
|
else if (frequencyFlag == 0x1000)
|
||||||
{
|
{
|
||||||
vgmstream->sample_rate = 48000;
|
vgmstream->sample_rate = 48000;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((fileLength - 0x10) / 16 * 28) / vgmstream->channels;
|
vgmstream->num_samples = ((fileLength - 0x10) / 16 * 28) / vgmstream->channels;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x0C, streamFile);
|
vgmstream->interleave_block_size = read_32bitLE(0x0C, streamFile);
|
||||||
vgmstream->meta_type = meta_PS2_HSF;
|
vgmstream->meta_type = meta_PS2_HSF;
|
||||||
|
|
||||||
if (vgmstream->loop_flag)
|
if (vgmstream->loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = 0;
|
vgmstream->loop_start_sample = 0;
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
readOffset = fileLength - 0x10;
|
readOffset = fileLength - 0x10;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
readOffset -=(off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
readOffset -=(off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
||||||
|
|
||||||
if (testBuffer[1] == 0x07)
|
if (testBuffer[1] == 0x07)
|
||||||
{
|
{
|
||||||
loopEndOffset = readOffset + 0x10;
|
loopEndOffset = readOffset + 0x10;
|
||||||
vgmstream->loop_end_sample = ((loopEndOffset - 0x10) / 16 * 28) / vgmstream->channels;
|
vgmstream->loop_end_sample = ((loopEndOffset - 0x10) / 16 * 28) / vgmstream->channels;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (readOffset > 0);
|
} while (readOffset > 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_ps2_ild(STREAMFILE *streamFile) {
|
|||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
int loop_flag=0;
|
int loop_flag=0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -19,33 +19,33 @@ VGMSTREAM * init_vgmstream_ps2_ild(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x494C4400)
|
if (read_32bitBE(0x00,streamFile) != 0x494C4400)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check loop */
|
/* check loop */
|
||||||
loop_flag = (read_32bitLE(0x2C,streamFile)!=0);
|
loop_flag = (read_32bitLE(0x2C,streamFile)!=0);
|
||||||
channel_count=read_32bitLE(0x04,streamFile);
|
channel_count=read_32bitLE(0x04,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->channels = read_32bitLE(0x04,streamFile);
|
vgmstream->channels = read_32bitLE(0x04,streamFile);
|
||||||
vgmstream->sample_rate = read_32bitLE(0x28,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x28,streamFile);
|
||||||
|
|
||||||
/* Check for Compression Scheme */
|
/* Check for Compression Scheme */
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = read_32bitLE(0x0C,streamFile)/16*28/vgmstream->channels;
|
vgmstream->num_samples = read_32bitLE(0x0C,streamFile)/16*28/vgmstream->channels;
|
||||||
|
|
||||||
/* Get loop point values */
|
/* Get loop point values */
|
||||||
if(vgmstream->loop_flag) {
|
if(vgmstream->loop_flag) {
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x2C,streamFile)/16*28;
|
vgmstream->loop_start_sample = read_32bitLE(0x2C,streamFile)/16*28;
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x30,streamFile)/16*28;
|
vgmstream->loop_end_sample = read_32bitLE(0x30,streamFile)/16*28;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile)/2;
|
vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile)/2;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->meta_type = meta_PS2_ILD;
|
vgmstream->meta_type = meta_PS2_ILD;
|
||||||
|
|
||||||
start_offset = (off_t)read_32bitLE(0x08,streamFile);
|
start_offset = (off_t)read_32bitLE(0x08,streamFile);
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading by each channel */
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_ps2_mcg(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -16,31 +16,31 @@ VGMSTREAM * init_vgmstream_ps2_mcg(STREAMFILE *streamFile) {
|
|||||||
/* check header */
|
/* check header */
|
||||||
if (!((read_32bitBE(0x00,streamFile) == 0x4D434700) &&
|
if (!((read_32bitBE(0x00,streamFile) == 0x4D434700) &&
|
||||||
(read_32bitBE(0x20,streamFile) == 0x56414770) &&
|
(read_32bitBE(0x20,streamFile) == 0x56414770) &&
|
||||||
(read_32bitBE(0x50,streamFile) == 0x56414770)))
|
(read_32bitBE(0x50,streamFile) == 0x56414770)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x34,streamFile)!=0);
|
loop_flag = (read_32bitLE(0x34,streamFile)!=0);
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x80;
|
start_offset = 0x80;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x30,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x30,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = read_32bitBE(0x2C,streamFile)/16*14*channel_count;
|
vgmstream->num_samples = read_32bitBE(0x2C,streamFile)/16*14*channel_count;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile);
|
vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile);
|
||||||
vgmstream->meta_type = meta_PS2_MCG;
|
vgmstream->meta_type = meta_PS2_MCG;
|
||||||
|
|
||||||
if (vgmstream->loop_flag)
|
if (vgmstream->loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x34,streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(0x34,streamFile);
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
|
@ -6,9 +6,9 @@ VGMSTREAM * init_vgmstream_ps2_mihb(STREAMFILE *streamFile) {
|
|||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int mib_blocks;
|
int mib_blocks;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -17,18 +17,18 @@ VGMSTREAM * init_vgmstream_ps2_mihb(STREAMFILE *streamFile) {
|
|||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x40000000)
|
if (read_32bitBE(0x00,streamFile) != 0x40000000)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
mib_blocks = read_32bitLE(0x14,streamFile);
|
mib_blocks = read_32bitLE(0x14,streamFile);
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
channel_count = read_32bitLE(0x08,streamFile);
|
channel_count = read_32bitLE(0x08,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x40;
|
start_offset = 0x40;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitLE(0x0C,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x0C,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((read_32bitLE(0x10,streamFile))*mib_blocks)*28/16;
|
vgmstream->num_samples = ((read_32bitLE(0x10,streamFile))*mib_blocks)*28/16;
|
||||||
|
@ -14,20 +14,20 @@ VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x4E505346) /* "NPSF" */
|
if (read_32bitBE(0x00,streamFile) != 0x4E505346) /* "NPSF" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x14,streamFile) != 0xFFFFFFFF);
|
loop_flag = (read_32bitLE(0x14,streamFile) != 0xFFFFFFFF);
|
||||||
channel_count = read_32bitLE(0x0C,streamFile);
|
channel_count = read_32bitLE(0x0C,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
vgmstream->channels = read_32bitLE(0x0C,streamFile);
|
vgmstream->channels = read_32bitLE(0x0C,streamFile);
|
||||||
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
|
||||||
vgmstream->num_samples = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1); /* single channel data */
|
vgmstream->num_samples = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1); /* single channel data */
|
||||||
if(vgmstream->loop_flag) {
|
if(vgmstream->loop_flag) {
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile);
|
||||||
vgmstream->loop_end_sample = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1);
|
vgmstream->loop_end_sample = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
@ -186,30 +186,30 @@ VGMSTREAM * init_vgmstream_ps2_rxw(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
/* check RXWS/FORM Header */
|
/* check RXWS/FORM Header */
|
||||||
if (!((read_32bitBE(0x00,streamFile) == 0x52585753) &&
|
if (!((read_32bitBE(0x00,streamFile) == 0x52585753) &&
|
||||||
(read_32bitBE(0x10,streamFile) == 0x464F524D)))
|
(read_32bitBE(0x10,streamFile) == 0x464F524D)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x3C,streamFile)!=0xFFFFFFFF);
|
loop_flag = (read_32bitLE(0x3C,streamFile)!=0xFFFFFFFF);
|
||||||
channel_count=2; /* Always stereo files */
|
channel_count=2; /* Always stereo files */
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0x2E,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x2E,streamFile);
|
||||||
vgmstream->num_samples = (read_32bitLE(0x38,streamFile)*28/16)/2;
|
vgmstream->num_samples = (read_32bitLE(0x38,streamFile)*28/16)/2;
|
||||||
|
|
||||||
/* Get loop point values */
|
/* Get loop point values */
|
||||||
if(vgmstream->loop_flag) {
|
if(vgmstream->loop_flag) {
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x3C,streamFile)/16*14;
|
vgmstream->loop_start_sample = read_32bitLE(0x3C,streamFile)/16*14;
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x38,streamFile)/16*14;
|
vgmstream->loop_end_sample = read_32bitLE(0x38,streamFile)/16*14;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x1c,streamFile)+0x10;
|
vgmstream->interleave_block_size = read_32bitLE(0x1c,streamFile)+0x10;
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->meta_type = meta_PS2_RXWS;
|
vgmstream->meta_type = meta_PS2_RXWS;
|
||||||
start_offset = 0x40;
|
start_offset = 0x40;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
|
@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_tk5(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -18,28 +18,28 @@ VGMSTREAM * init_vgmstream_ps2_tk5(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x544B3553)
|
if (read_32bitBE(0x00,streamFile) != 0x544B3553)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x0C,streamFile)!=0);
|
loop_flag = (read_32bitLE(0x0C,streamFile)!=0);
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x800;
|
start_offset = 0x800;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = 48000;
|
vgmstream->sample_rate = 48000;
|
||||||
vgmstream->coding_type = coding_PSX_badflags;
|
vgmstream->coding_type = coding_PSX_badflags;
|
||||||
vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x800))/16*28/2;
|
vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x800))/16*28/2;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x10;
|
vgmstream->interleave_block_size = 0x10;
|
||||||
vgmstream->meta_type = meta_PS2_TK5;
|
vgmstream->meta_type = meta_PS2_TK5;
|
||||||
|
|
||||||
if (vgmstream->loop_flag)
|
if (vgmstream->loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28;
|
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28;
|
||||||
vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28);
|
vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
@ -71,7 +71,7 @@ VGMSTREAM * init_vgmstream_ps2_tk1(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -81,28 +81,28 @@ VGMSTREAM * init_vgmstream_ps2_tk1(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x544B3553)
|
if (read_32bitBE(0x00,streamFile) != 0x544B3553)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x0C,streamFile)!=0);
|
loop_flag = (read_32bitLE(0x0C,streamFile)!=0);
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x800;
|
start_offset = 0x800;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = 44100;
|
vgmstream->sample_rate = 44100;
|
||||||
vgmstream->coding_type = coding_PSX_badflags;
|
vgmstream->coding_type = coding_PSX_badflags;
|
||||||
vgmstream->num_samples = read_32bitLE(0x08,streamFile)/16*28;
|
vgmstream->num_samples = read_32bitLE(0x08,streamFile)/16*28;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x10;
|
vgmstream->interleave_block_size = 0x10;
|
||||||
vgmstream->meta_type = meta_PS2_TK1;
|
vgmstream->meta_type = meta_PS2_TK1;
|
||||||
|
|
||||||
if (vgmstream->loop_flag)
|
if (vgmstream->loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28;
|
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28;
|
||||||
vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28);
|
vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
|
@ -79,13 +79,16 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
/* channels are usually at 0x1e, but not in Ukiyo no Roushi which has some kind
|
/* channels are usually at 0x1e, but not in Ukiyo no Roushi which has some kind
|
||||||
* of loop-like values instead (who designs this crap?) */
|
* of loop-like values instead (who designs this crap?) */
|
||||||
if (read_32bitBE(0x18,streamFile) != 0 || read_32bitBE(0x1c,streamFile) > 0x20) {
|
if (read_32bitBE(0x18,streamFile) == 0
|
||||||
channel_count = 1;
|
&& (read_32bitBE(0x1c,streamFile) & 0xFFFF00FF) == 0
|
||||||
} else {
|
&& read_8bit(0x1e,streamFile) < 16) {
|
||||||
channel_count = read_8bit(0x1e,streamFile);
|
channel_count = read_8bit(0x1e,streamFile);
|
||||||
if (channel_count == 0)
|
if (channel_count == 0)
|
||||||
channel_count = 1; /* ex. early Vita vag (Lumines) */
|
channel_count = 1; /* ex. early Vita vag (Lumines) */
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
channel_count = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd);
|
loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd);
|
||||||
|
@ -9,15 +9,15 @@ VGMSTREAM * init_vgmstream_ps2_vgs(STREAMFILE *streamFile) {
|
|||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
size_t fileLength;
|
size_t fileLength;
|
||||||
off_t readOffset = 0;
|
off_t readOffset = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
off_t loop_start_offset = 0;
|
off_t loop_start_offset = 0;
|
||||||
off_t loop_end_offset = 0;
|
off_t loop_end_offset = 0;
|
||||||
|
|
||||||
uint8_t testBuffer[0x10];
|
uint8_t testBuffer[0x10];
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -27,71 +27,71 @@ VGMSTREAM * init_vgmstream_ps2_vgs(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x56475300)
|
if (read_32bitBE(0x00,streamFile) != 0x56475300)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
// get file length
|
// get file length
|
||||||
fileLength = get_streamfile_size(streamFile);
|
fileLength = get_streamfile_size(streamFile);
|
||||||
|
|
||||||
// Find loop start
|
// Find loop start
|
||||||
do {
|
do {
|
||||||
readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
||||||
|
|
||||||
// Loop Start ...
|
|
||||||
if(testBuffer[0x01] == 0x06)
|
|
||||||
{
|
|
||||||
loop_start_offset = readOffset - 0x10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (streamFile->get_offset(streamFile)<((int32_t)fileLength));
|
// Loop Start ...
|
||||||
|
if(testBuffer[0x01] == 0x06)
|
||||||
|
{
|
||||||
|
loop_start_offset = readOffset - 0x10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// start at last line of file and move up
|
} while (streamFile->get_offset(streamFile)<((int32_t)fileLength));
|
||||||
readOffset = (int32_t)fileLength - 0x10;
|
|
||||||
|
|
||||||
// Find loop end
|
|
||||||
do {
|
|
||||||
readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
|
||||||
|
|
||||||
// Loop End ...
|
|
||||||
if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77))
|
|
||||||
{
|
|
||||||
loop_end_offset = readOffset + 0x20;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (readOffset > 0);
|
|
||||||
|
|
||||||
// setup loops
|
// start at last line of file and move up
|
||||||
if (loop_start_offset > 0)
|
readOffset = (int32_t)fileLength - 0x10;
|
||||||
{
|
|
||||||
loop_flag = 1;
|
// Find loop end
|
||||||
|
do {
|
||||||
// if we have a start loop, use EOF if end loop is not found
|
readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
||||||
if (loop_end_offset == 0)
|
|
||||||
{
|
// Loop End ...
|
||||||
loop_end_offset = (int32_t)fileLength - 0x10;
|
if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77))
|
||||||
}
|
{
|
||||||
}
|
loop_end_offset = readOffset + 0x20;
|
||||||
else
|
break;
|
||||||
{
|
}
|
||||||
loop_flag = 0;
|
} while (readOffset > 0);
|
||||||
}
|
|
||||||
|
// setup loops
|
||||||
|
if (loop_start_offset > 0)
|
||||||
|
{
|
||||||
|
loop_flag = 1;
|
||||||
|
|
||||||
|
// if we have a start loop, use EOF if end loop is not found
|
||||||
|
if (loop_end_offset == 0)
|
||||||
|
{
|
||||||
|
loop_end_offset = (int32_t)fileLength - 0x10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loop_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = 0x30;
|
start_offset = 0x30;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x30)/16/channel_count*28);
|
vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x30)/16/channel_count*28);
|
||||||
|
|
||||||
if (loop_flag)
|
if (loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28;
|
vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28;
|
||||||
vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28;
|
vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile)*0x1000;
|
vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile)*0x1000;
|
||||||
|
@ -7,9 +7,9 @@ VGMSTREAM * init_vgmstream_ps2_vms(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int header_size;
|
int header_size;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -19,27 +19,27 @@ VGMSTREAM * init_vgmstream_ps2_vms(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x564D5320)
|
if (read_32bitBE(0x00,streamFile) != 0x564D5320)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = 1;
|
loop_flag = 1;
|
||||||
channel_count = read_8bit(0x08,streamFile);
|
channel_count = read_8bit(0x08,streamFile);
|
||||||
header_size = read_32bitLE(0x1C, streamFile);
|
header_size = read_32bitLE(0x1C, streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = header_size;
|
start_offset = header_size;
|
||||||
|
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitLE(0x14,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x14,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((get_streamfile_size(streamFile) - header_size)/16/ channel_count * 28);
|
vgmstream->num_samples = ((get_streamfile_size(streamFile) - header_size)/16/ channel_count * 28);
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x10,streamFile);
|
vgmstream->interleave_block_size = read_32bitLE(0x10,streamFile);
|
||||||
vgmstream->meta_type = meta_PS2_VMS;
|
vgmstream->meta_type = meta_PS2_VMS;
|
||||||
vgmstream->loop_start_sample = 0;
|
vgmstream->loop_start_sample = 0;
|
||||||
vgmstream->loop_end_sample = (get_streamfile_size(streamFile))/16/ channel_count * 28;
|
vgmstream->loop_end_sample = (get_streamfile_size(streamFile))/16/ channel_count * 28;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_vpk(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
int loop_flag=0;
|
int loop_flag=0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -20,33 +20,33 @@ VGMSTREAM * init_vgmstream_ps2_vpk(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x204B5056)
|
if (read_32bitBE(0x00,streamFile) != 0x204B5056)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check loop */
|
/* check loop */
|
||||||
loop_flag = (read_32bitLE(0x7FC,streamFile)!=0);
|
loop_flag = (read_32bitLE(0x7FC,streamFile)!=0);
|
||||||
channel_count=read_32bitLE(0x14,streamFile);
|
channel_count=read_32bitLE(0x14,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->channels = read_32bitLE(0x14,streamFile);
|
vgmstream->channels = read_32bitLE(0x14,streamFile);
|
||||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||||
|
|
||||||
/* Check for Compression Scheme */
|
/* Check for Compression Scheme */
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16*28;
|
vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16*28;
|
||||||
|
|
||||||
/* Get loop point values */
|
/* Get loop point values */
|
||||||
if(vgmstream->loop_flag) {
|
if(vgmstream->loop_flag) {
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x7FC,streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(0x7FC,streamFile);
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile)/2;
|
vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile)/2;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->meta_type = meta_PS2_VPK;
|
vgmstream->meta_type = meta_PS2_VPK;
|
||||||
|
|
||||||
start_offset = (off_t)read_32bitLE(0x08,streamFile);
|
start_offset = (off_t)read_32bitLE(0x08,streamFile);
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading by each channel */
|
||||||
{
|
{
|
||||||
|
@ -2,19 +2,19 @@
|
|||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
/* IVAG
|
/* IVAG
|
||||||
- The Idolm@ster: Gravure For You! Vol. 3 (PS3)
|
- The Idolm@ster: Gravure For You! Vol. 3 (PS3)
|
||||||
|
|
||||||
Appears to be two VAGp streams interleaved.
|
Appears to be two VAGp streams interleaved.
|
||||||
*/
|
*/
|
||||||
VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile)
|
VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile)
|
||||||
{
|
{
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -24,34 +24,34 @@ VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile)
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x49564147) // "IVAG"
|
if (read_32bitBE(0x00,streamFile) != 0x49564147) // "IVAG"
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
// channel count
|
// channel count
|
||||||
channel_count = read_32bitBE(0x08, streamFile);
|
channel_count = read_32bitBE(0x08, streamFile);
|
||||||
|
|
||||||
// header size
|
// header size
|
||||||
start_offset = 0x40 + (0x40 * channel_count);
|
start_offset = 0x40 + (0x40 * channel_count);
|
||||||
|
|
||||||
// loop flag
|
// loop flag
|
||||||
if ((read_32bitBE(0x14, streamFile) != 0 ||
|
if ((read_32bitBE(0x14, streamFile) != 0 ||
|
||||||
(read_32bitBE(0x18, streamFile) != 0)))
|
(read_32bitBE(0x18, streamFile) != 0)))
|
||||||
{
|
{
|
||||||
loop_flag = 1;
|
loop_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x0C,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x0C,streamFile);
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = read_32bitBE(0x10,streamFile);
|
vgmstream->num_samples = read_32bitBE(0x10,streamFile);
|
||||||
|
|
||||||
if (loop_flag)
|
if (loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
|
vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
|
||||||
vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile);
|
vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = read_32bitBE(0x1C,streamFile);
|
vgmstream->interleave_block_size = read_32bitBE(0x1C,streamFile);
|
||||||
@ -64,15 +64,15 @@ VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile)
|
|||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
if (!file) goto fail;
|
if (!file) goto fail;
|
||||||
|
|
||||||
for (i=0;i<channel_count;i++)
|
for (i=0;i<channel_count;i++)
|
||||||
{
|
{
|
||||||
vgmstream->ch[i].streamfile = file;
|
vgmstream->ch[i].streamfile = file;
|
||||||
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
vgmstream->ch[i].channel_start_offset=
|
||||||
vgmstream->ch[i].offset=start_offset + (vgmstream->interleave_block_size * i);
|
vgmstream->ch[i].offset=start_offset + (vgmstream->interleave_block_size * i);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
@ -7,15 +7,15 @@ VGMSTREAM * init_vgmstream_ps3_klbs(STREAMFILE *streamFile)
|
|||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
size_t fileLength;
|
size_t fileLength;
|
||||||
off_t readOffset = 0;
|
off_t readOffset = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
off_t loop_start_offset = 0;
|
off_t loop_start_offset = 0;
|
||||||
off_t loop_end_offset = 0;
|
off_t loop_end_offset = 0;
|
||||||
|
|
||||||
uint8_t testBuffer[0x10];
|
uint8_t testBuffer[0x10];
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -25,77 +25,77 @@ VGMSTREAM * init_vgmstream_ps3_klbs(STREAMFILE *streamFile)
|
|||||||
if (read_32bitBE(0x20,streamFile) != 0x6B6C4253)
|
if (read_32bitBE(0x20,streamFile) != 0x6B6C4253)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
// get file length
|
// get file length
|
||||||
fileLength = get_streamfile_size(streamFile);
|
fileLength = get_streamfile_size(streamFile);
|
||||||
|
|
||||||
// Find loop start
|
// Find loop start
|
||||||
start_offset = read_32bitBE(0x10,streamFile);
|
start_offset = read_32bitBE(0x10,streamFile);
|
||||||
readOffset = start_offset;
|
readOffset = start_offset;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
||||||
|
|
||||||
// Loop Start ...
|
|
||||||
if(testBuffer[0x01] == 0x06)
|
|
||||||
{
|
|
||||||
loop_start_offset = readOffset - 0x10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (streamFile->get_offset(streamFile)<((int32_t)fileLength));
|
// Loop Start ...
|
||||||
|
if(testBuffer[0x01] == 0x06)
|
||||||
|
{
|
||||||
|
loop_start_offset = readOffset - 0x10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// start at last line of file and move up
|
} while (streamFile->get_offset(streamFile)<((int32_t)fileLength));
|
||||||
readOffset = (int32_t)fileLength - 0x10;
|
|
||||||
|
|
||||||
// Find loop end
|
|
||||||
do {
|
|
||||||
readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
|
||||||
|
|
||||||
// Loop End ...
|
|
||||||
if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77))
|
|
||||||
{
|
|
||||||
loop_end_offset = readOffset + 0x20;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (readOffset > 0);
|
|
||||||
|
|
||||||
// setup loops
|
// start at last line of file and move up
|
||||||
if (loop_start_offset > 0)
|
readOffset = (int32_t)fileLength - 0x10;
|
||||||
{
|
|
||||||
loop_flag = 1;
|
// Find loop end
|
||||||
|
do {
|
||||||
// if we have a start loop, use EOF if end loop is not found
|
readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile);
|
||||||
if (loop_end_offset == 0)
|
|
||||||
{
|
// Loop End ...
|
||||||
loop_end_offset = (int32_t)fileLength - 0x10;
|
if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77))
|
||||||
}
|
{
|
||||||
}
|
loop_end_offset = readOffset + 0x20;
|
||||||
else
|
break;
|
||||||
{
|
}
|
||||||
loop_flag = 0;
|
} while (readOffset > 0);
|
||||||
}
|
|
||||||
|
// setup loops
|
||||||
|
if (loop_start_offset > 0)
|
||||||
|
{
|
||||||
|
loop_flag = 1;
|
||||||
|
|
||||||
|
// if we have a start loop, use EOF if end loop is not found
|
||||||
|
if (loop_end_offset == 0)
|
||||||
|
{
|
||||||
|
loop_end_offset = (int32_t)fileLength - 0x10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loop_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = read_32bitBE(0x90, streamFile);
|
vgmstream->interleave_block_size = read_32bitBE(0x90, streamFile);
|
||||||
vgmstream->meta_type = meta_PS3_KLBS;
|
vgmstream->meta_type = meta_PS3_KLBS;
|
||||||
|
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = 48000;
|
vgmstream->sample_rate = 48000;
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((vgmstream->interleave_block_size * channel_count)/16/channel_count*28);
|
vgmstream->num_samples = ((vgmstream->interleave_block_size * channel_count)/16/channel_count*28);
|
||||||
|
|
||||||
if (loop_flag)
|
if (loop_flag)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28;
|
vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28;
|
||||||
vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28;
|
vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_psx_fag(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -15,27 +15,27 @@ VGMSTREAM * init_vgmstream_psx_fag(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
|
|
||||||
/* Look if there's more than 1 one file... */
|
/* Look if there's more than 1 one file... */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x01000000)
|
if (read_32bitBE(0x00,streamFile) != 0x01000000)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = read_32bitLE(0x04,streamFile);
|
start_offset = read_32bitLE(0x04,streamFile);
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = 24000;
|
vgmstream->sample_rate = 24000;
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = (read_32bitLE(0x08,streamFile))/channel_count/32*28;
|
vgmstream->num_samples = (read_32bitLE(0x08,streamFile))/channel_count/32*28;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = 0;
|
vgmstream->loop_start_sample = 0;
|
||||||
vgmstream->loop_end_sample = (read_32bitLE(0x08,streamFile))/channel_count/32*28;
|
vgmstream->loop_end_sample = (read_32bitLE(0x08,streamFile))/channel_count/32*28;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x8000;
|
vgmstream->interleave_block_size = 0x8000;
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
#include "meta.h"
|
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* SS_STREAM
|
|
||||||
|
|
||||||
SS_STREAM is format used by various UBI Soft Games
|
|
||||||
|
|
||||||
2008-11-15 - Fastelbja : First version ...
|
|
||||||
|
|
||||||
|
|
||||||
Some infos, sorry for messing up the meta (regards, manako)
|
|
||||||
|
|
||||||
Splinter Cell - *.SS0; PC (except Music_*.SS0)
|
|
||||||
Splinter Cell: Pandora Tomorrow - *.SS0, *.LS0; PC
|
|
||||||
Splinter Cell: Chaos Theory - *.SS0, *.LS0; PC
|
|
||||||
Splinter Cell: Double Agent - *.SS0, *.LS0; PC
|
|
||||||
|
|
||||||
UbiSoft Old Simple Stream (version 3)
|
|
||||||
UbiSoft Simple Stream (version 5)
|
|
||||||
UbiSoft Old Interleaved Stream (version 2)
|
|
||||||
UbiSoft Interleaved Stream (version 8 )
|
|
||||||
|
|
||||||
Note: if the version number is 3, then all values in this file are big-endian. If the version is 5, then all values are little-endian.
|
|
||||||
|
|
||||||
Header:
|
|
||||||
byte {1} - Version number (3 or 5)
|
|
||||||
byte {3} - Unknown
|
|
||||||
byte {4} - Unknown
|
|
||||||
uint32 {4} - Unknown
|
|
||||||
uint16 {2} - Unknown
|
|
||||||
uint16 {2} - Number of extra uncompressed samples before the data (always 10)
|
|
||||||
int16 {2} - First left sample for decompression
|
|
||||||
byte {1} - First left index for decompression
|
|
||||||
byte {1} - Unknown
|
|
||||||
int16 {2} - First right sample for decompression
|
|
||||||
byte {1} - First right index for decompression
|
|
||||||
byte {1} - Unknown
|
|
||||||
byte {4} - Unknown
|
|
||||||
|
|
||||||
Extra Uncompressed Samples:
|
|
||||||
if the sound is mono:
|
|
||||||
int16 {Number of extra uncompressed samples * 2} - Uncompressed samples
|
|
||||||
|
|
||||||
if the sound is stereo:
|
|
||||||
int16 {Number of extra uncompressed samples * 4} - Uncompressed samples
|
|
||||||
|
|
||||||
Data:
|
|
||||||
byte {?} - Compressed data
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
And here is the format of the old interleaved streams:
|
|
||||||
|
|
||||||
Code:
|
|
||||||
Little-endian
|
|
||||||
|
|
||||||
uint32 {4} - Signature (2)
|
|
||||||
uint32 {4} - Number of Layers (always 3)
|
|
||||||
uint32 {4} - Total File Size
|
|
||||||
uint32 {4} - Unknown (always 20)
|
|
||||||
uint32 {4} - Unknown (always 1104)
|
|
||||||
uint32 {4} - Average Block Size (always 361)
|
|
||||||
|
|
||||||
For Each Block: {
|
|
||||||
uint32 {4} - Block Index (begins at 1)
|
|
||||||
uint32 {4} - Unknown (always 20)
|
|
||||||
|
|
||||||
For Each Layer (Chunk): {
|
|
||||||
uint32 {4} - Layer Chunk Size
|
|
||||||
}
|
|
||||||
|
|
||||||
For Each Layer (Chunk): {
|
|
||||||
uint32 {Layer Chunk Size} - Chunk of an Encapsulated UbiSoft Old Simple Stream
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
And the new interleaved streams:
|
|
||||||
|
|
||||||
Code:
|
|
||||||
Little-endian
|
|
||||||
|
|
||||||
uint16 {2} - Signature (8)
|
|
||||||
uint16 {2} - Unknown
|
|
||||||
uint32 {4} - Unknown
|
|
||||||
uint32 {4} - Number of Layers
|
|
||||||
uint32 {4} - Number of Blocks
|
|
||||||
uint32 {4} - Number of Bytes after This to the Headers
|
|
||||||
uint32 {4} - The Sum of (Number of Layers * 4) Plus the Header Lengths
|
|
||||||
uint32 {4} - Average Sum of Chunk Data Lengths
|
|
||||||
|
|
||||||
For Each Layer: {
|
|
||||||
uint32 {4} - Layer Header Size
|
|
||||||
}
|
|
||||||
|
|
||||||
For Each Layer: {
|
|
||||||
uint32 {Layer Header Size} - Header of an Encapsulated Stream (PCM, UbiSoft Simple Stream, Ogg Vorbis)
|
|
||||||
}
|
|
||||||
|
|
||||||
For Each Block: {
|
|
||||||
uint32 {4} - Signature (3)
|
|
||||||
uint32 {4} - Number of bytes from the start of this block to the next block, 0 if no more blocks
|
|
||||||
|
|
||||||
For Each Layer (Chunk): {
|
|
||||||
uint32 {4} - Layer Chunk Size
|
|
||||||
}
|
|
||||||
|
|
||||||
For Each Layer (Chunk): {
|
|
||||||
uint32 {Layer Chunk Size} - Chunk of an Encapsulated Stream (PCM, UbiSoft Simple Stream, Ogg Vorbis)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE *streamFile) {
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
int loop_flag=0;
|
|
||||||
int channels;
|
|
||||||
int channel_count;
|
|
||||||
off_t start_offset;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("ss3",filename_extension(filename)) &&
|
|
||||||
strcasecmp("ss7",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
loop_flag = 0;
|
|
||||||
//freq_flag = read_8bit(0x08,streamFile);
|
|
||||||
|
|
||||||
if (read_8bit(0x0C,streamFile) == 0) {
|
|
||||||
channels = 1;
|
|
||||||
} else {
|
|
||||||
channels = read_8bit(0x0C,streamFile)*2;
|
|
||||||
}
|
|
||||||
|
|
||||||
channel_count = channels;
|
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
vgmstream->sample_rate = 48000;
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!strcasecmp("ss3",filename_extension(filename))) {
|
|
||||||
vgmstream->sample_rate = 32000;
|
|
||||||
} else if (!strcasecmp("ss7",filename_extension(filename))) {
|
|
||||||
vgmstream->sample_rate = 48000;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
start_offset = (read_8bit(0x07,streamFile)+5);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (channel_count == 1){
|
|
||||||
start_offset = 0x3C;
|
|
||||||
} else if (channel_count == 2) {
|
|
||||||
start_offset = 0x44;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(channel_count==1)
|
|
||||||
vgmstream->coding_type = coding_IMA;
|
|
||||||
else
|
|
||||||
vgmstream->coding_type = coding_EACS_IMA;
|
|
||||||
|
|
||||||
vgmstream->num_samples = (int32_t)((get_streamfile_size(streamFile)-start_offset)* 2 / vgmstream->channels);
|
|
||||||
vgmstream->layout_type = layout_none;
|
|
||||||
|
|
||||||
vgmstream->meta_type = meta_XBOX_WAVM;
|
|
||||||
vgmstream->get_high_nibble=0;
|
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
|
||||||
{
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
|
|
||||||
if (channel_count == 1){
|
|
||||||
vgmstream->ch[i].offset = start_offset;
|
|
||||||
} else if (channel_count == 2) {
|
|
||||||
vgmstream->ch[i].offset = start_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
vgmstream->ch[i].adpcm_history1_32=(int32_t)read_16bitLE(0x10+i*4,streamFile);
|
|
||||||
vgmstream->ch[i].adpcm_step_index =(int)read_8bit(0x12+i*4,streamFile);
|
|
||||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -8,93 +8,93 @@ VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile) {
|
|||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag, channel_count;
|
int loop_flag, channel_count;
|
||||||
size_t sampleRate, numSamples, startSample, dataSize, blockSize, blockCount; // A mess
|
size_t sampleRate, numSamples, startSample, dataSize, blockSize, blockCount; // A mess
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
/* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */
|
/* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */
|
||||||
if ( !check_extensions(streamFile,"aac,laac,ace"))
|
if ( !check_extensions(streamFile,"aac,laac,ace"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x41414320) /* "AAC " */
|
if (read_32bitBE(0x00,streamFile) != 0x41414320) /* "AAC " */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Ok, let's check what's behind door number 1 */
|
/* Ok, let's check what's behind door number 1 */
|
||||||
if (read_32bitBE(0x1000, streamFile) == 0x41534320) /* "ASC " */
|
if (read_32bitBE(0x1000, streamFile) == 0x41534320) /* "ASC " */
|
||||||
{
|
{
|
||||||
loop_flag = read_32bitBE(0x1118, streamFile);
|
loop_flag = read_32bitBE(0x1118, streamFile);
|
||||||
|
|
||||||
/*Funky Channel Count Checking */
|
/*Funky Channel Count Checking */
|
||||||
if (read_32bitBE(0x1184, streamFile) == 0x7374726D)
|
if (read_32bitBE(0x1184, streamFile) == 0x7374726D)
|
||||||
channel_count = 6;
|
channel_count = 6;
|
||||||
else if (read_32bitBE(0x1154, streamFile) == 0x7374726D)
|
else if (read_32bitBE(0x1154, streamFile) == 0x7374726D)
|
||||||
channel_count = 4;
|
channel_count = 4;
|
||||||
else
|
else
|
||||||
channel_count = read_8bit(0x1134, streamFile);
|
channel_count = read_8bit(0x1134, streamFile);
|
||||||
|
|
||||||
sampleRate = read_32bitBE(0x10F4, streamFile);
|
sampleRate = read_32bitBE(0x10F4, streamFile);
|
||||||
numSamples = read_32bitBE(0x10FC, streamFile);
|
numSamples = read_32bitBE(0x10FC, streamFile);
|
||||||
startSample = read_32bitBE(0x10F8, streamFile);
|
startSample = read_32bitBE(0x10F8, streamFile);
|
||||||
dataSize = read_32bitBE(0x10F0, streamFile);
|
dataSize = read_32bitBE(0x10F0, streamFile);
|
||||||
blockSize = read_32bitBE(0x1100, streamFile);
|
blockSize = read_32bitBE(0x1100, streamFile);
|
||||||
blockCount = read_32bitBE(0x110C, streamFile);
|
blockCount = read_32bitBE(0x110C, streamFile);
|
||||||
}
|
}
|
||||||
else if (read_32bitBE(0x1000, streamFile) == 0x57415645) /* "WAVE" */
|
else if (read_32bitBE(0x1000, streamFile) == 0x57415645) /* "WAVE" */
|
||||||
{
|
{
|
||||||
loop_flag = read_32bitBE(0x1048, streamFile);
|
loop_flag = read_32bitBE(0x1048, streamFile);
|
||||||
|
|
||||||
/*Funky Channel Count Checking */
|
/*Funky Channel Count Checking */
|
||||||
if (read_32bitBE(0x10B0, streamFile) == 0x7374726D)
|
if (read_32bitBE(0x10B0, streamFile) == 0x7374726D)
|
||||||
channel_count = 6;
|
channel_count = 6;
|
||||||
else if (read_32bitBE(0x1080, streamFile) == 0x7374726D)
|
else if (read_32bitBE(0x1080, streamFile) == 0x7374726D)
|
||||||
channel_count = 4;
|
channel_count = 4;
|
||||||
else
|
else
|
||||||
channel_count = read_8bit(0x1060, streamFile);
|
channel_count = read_8bit(0x1060, streamFile);
|
||||||
|
|
||||||
sampleRate = read_32bitBE(0x1024, streamFile);
|
sampleRate = read_32bitBE(0x1024, streamFile);
|
||||||
numSamples = read_32bitBE(0x102C, streamFile);
|
numSamples = read_32bitBE(0x102C, streamFile);
|
||||||
startSample = read_32bitBE(0x1028, streamFile);
|
startSample = read_32bitBE(0x1028, streamFile);
|
||||||
dataSize = read_32bitBE(0x1020, streamFile);
|
dataSize = read_32bitBE(0x1020, streamFile);
|
||||||
blockSize = read_32bitBE(0x1030, streamFile);
|
blockSize = read_32bitBE(0x1030, streamFile);
|
||||||
blockCount = read_32bitBE(0x103C, streamFile);
|
blockCount = read_32bitBE(0x103C, streamFile);
|
||||||
}
|
}
|
||||||
else if (read_32bitBE(0x1000, streamFile) == 0x00000000) /* some like to be special */
|
else if (read_32bitBE(0x1000, streamFile) == 0x00000000) /* some like to be special */
|
||||||
{
|
{
|
||||||
loop_flag = read_32bitBE(0x6048, streamFile);
|
loop_flag = read_32bitBE(0x6048, streamFile);
|
||||||
|
|
||||||
/*Funky Channel Count Checking */
|
/*Funky Channel Count Checking */
|
||||||
if (read_32bitBE(0x60B0, streamFile) == 0x7374726D)
|
if (read_32bitBE(0x60B0, streamFile) == 0x7374726D)
|
||||||
channel_count = 6;
|
channel_count = 6;
|
||||||
else if (read_32bitBE(0x6080, streamFile) == 0x7374726D)
|
else if (read_32bitBE(0x6080, streamFile) == 0x7374726D)
|
||||||
channel_count = 4;
|
channel_count = 4;
|
||||||
else
|
else
|
||||||
channel_count = read_8bit(0x6060, streamFile);
|
channel_count = read_8bit(0x6060, streamFile);
|
||||||
|
|
||||||
sampleRate = read_32bitBE(0x6024, streamFile);
|
sampleRate = read_32bitBE(0x6024, streamFile);
|
||||||
numSamples = read_32bitBE(0x602C, streamFile);
|
numSamples = read_32bitBE(0x602C, streamFile);
|
||||||
startSample = read_32bitBE(0x6028, streamFile);
|
startSample = read_32bitBE(0x6028, streamFile);
|
||||||
dataSize = read_32bitBE(0x6020, streamFile);
|
dataSize = read_32bitBE(0x6020, streamFile);
|
||||||
blockSize = read_32bitBE(0x6030, streamFile);
|
blockSize = read_32bitBE(0x6030, streamFile);
|
||||||
blockCount = read_32bitBE(0x603C, streamFile);
|
blockCount = read_32bitBE(0x603C, streamFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto fail; //cuz I don't know if there are other variants
|
goto fail; //cuz I don't know if there are other variants
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
if (read_32bitBE(0x1000, streamFile) == 0x00000000)
|
if (read_32bitBE(0x1000, streamFile) == 0x00000000)
|
||||||
start_offset = 0x7000;
|
start_offset = 0x7000;
|
||||||
else
|
else
|
||||||
start_offset = 0x2000;
|
start_offset = 0x2000;
|
||||||
|
|
||||||
vgmstream->sample_rate = sampleRate;
|
vgmstream->sample_rate = sampleRate;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->num_samples = numSamples;
|
vgmstream->num_samples = numSamples;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = startSample;
|
vgmstream->loop_start_sample = startSample;
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
vgmstream->meta_type = meta_TA_AAC_X360;
|
vgmstream->meta_type = meta_TA_AAC_X360;
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
@ -103,9 +103,9 @@ VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile) {
|
|||||||
uint8_t buf[100];
|
uint8_t buf[100];
|
||||||
size_t bytes, datasize, block_size, block_count;
|
size_t bytes, datasize, block_size, block_count;
|
||||||
|
|
||||||
block_count = blockCount;
|
block_count = blockCount;
|
||||||
block_size = blockSize;
|
block_size = blockSize;
|
||||||
datasize = dataSize;
|
datasize = dataSize;
|
||||||
|
|
||||||
bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||||
if (bytes <= 0) goto fail;
|
if (bytes <= 0) goto fail;
|
||||||
@ -132,79 +132,79 @@ fail:
|
|||||||
|
|
||||||
/* PlayStation 3 Variants (Star Ocean International, Resonance of Fate) */
|
/* PlayStation 3 Variants (Star Ocean International, Resonance of Fate) */
|
||||||
VGMSTREAM * init_vgmstream_ta_aac_ps3(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ta_aac_ps3(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag, channel_count;
|
int loop_flag, channel_count;
|
||||||
uint32_t data_size, loop_start, loop_end, codec_id;
|
uint32_t data_size, loop_start, loop_end, codec_id;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
/* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */
|
/* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */
|
||||||
if (!check_extensions(streamFile, "aac,laac,ace"))
|
if (!check_extensions(streamFile, "aac,laac,ace"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (read_32bitBE(0x00, streamFile) != 0x41414320) /* "AAC " */
|
if (read_32bitBE(0x00, streamFile) != 0x41414320) /* "AAC " */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Haven't Found a codec flag yet. Let's just use this for now */
|
/* Haven't Found a codec flag yet. Let's just use this for now */
|
||||||
if (read_32bitBE(0x10000, streamFile) != 0x41534320) /* "ASC " */
|
if (read_32bitBE(0x10000, streamFile) != 0x41534320) /* "ASC " */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (read_32bitBE(0x10104, streamFile) != 0xFFFFFFFF)
|
if (read_32bitBE(0x10104, streamFile) != 0xFFFFFFFF)
|
||||||
loop_flag = 1;
|
loop_flag = 1;
|
||||||
else
|
else
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
|
|
||||||
channel_count = read_32bitBE(0x100F4, streamFile);
|
channel_count = read_32bitBE(0x100F4, streamFile);
|
||||||
codec_id = read_32bitBE(0x100F0, streamFile);
|
codec_id = read_32bitBE(0x100F0, streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* Useless header, let's play the guessing game */
|
/* Useless header, let's play the guessing game */
|
||||||
start_offset = 0x10110;
|
start_offset = 0x10110;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x100FC, streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x100FC, streamFile);
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->meta_type = meta_TA_AAC_PS3;
|
vgmstream->meta_type = meta_TA_AAC_PS3;
|
||||||
data_size = read_32bitBE(0x100F8, streamFile);
|
data_size = read_32bitBE(0x100F8, streamFile);
|
||||||
loop_start = read_32bitBE(0x10104, streamFile);
|
loop_start = read_32bitBE(0x10104, streamFile);
|
||||||
loop_end = read_32bitBE(0x10108, streamFile);
|
loop_end = read_32bitBE(0x10108, streamFile);
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
{
|
{
|
||||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
uint8_t buf[100];
|
uint8_t buf[100];
|
||||||
int32_t bytes, samples_size = 1024, block_size, encoder_delay, joint_stereo, max_samples;
|
int32_t bytes, samples_size = 1024, block_size, encoder_delay, joint_stereo, max_samples;
|
||||||
block_size = (codec_id == 4 ? 0x60 : (codec_id == 5 ? 0x98 : 0xC0)) * vgmstream->channels;
|
block_size = (codec_id == 4 ? 0x60 : (codec_id == 5 ? 0x98 : 0xC0)) * vgmstream->channels;
|
||||||
max_samples = (data_size / block_size) * samples_size;
|
max_samples = (data_size / block_size) * samples_size;
|
||||||
encoder_delay = 0x0;
|
encoder_delay = 0x0;
|
||||||
joint_stereo = 0;
|
joint_stereo = 0;
|
||||||
|
|
||||||
/* make a fake riff so FFmpeg can parse the ATRAC3 */
|
/* make a fake riff so FFmpeg can parse the ATRAC3 */
|
||||||
bytes = ffmpeg_make_riff_atrac3(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
|
bytes = ffmpeg_make_riff_atrac3(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
|
||||||
if (bytes <= 0) goto fail;
|
if (bytes <= 0) goto fail;
|
||||||
|
|
||||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size);
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size);
|
||||||
if (!ffmpeg_data) goto fail;
|
if (!ffmpeg_data) goto fail;
|
||||||
vgmstream->codec_data = ffmpeg_data;
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
vgmstream->coding_type = coding_FFmpeg;
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->num_samples = max_samples;
|
vgmstream->num_samples = max_samples;
|
||||||
|
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = (loop_start / block_size) * samples_size;
|
vgmstream->loop_start_sample = (loop_start / block_size) * samples_size;
|
||||||
vgmstream->loop_end_sample = (loop_end / block_size) * samples_size;
|
vgmstream->loop_end_sample = (loop_end / block_size) * samples_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||||
goto fail;
|
goto fail;
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
102
src/meta/thp.c
102
src/meta/thp.c
@ -7,74 +7,74 @@
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
off_t start_offset;
|
||||||
|
|
||||||
char filename[PATH_LIMIT];
|
uint32_t maxAudioSize=0;
|
||||||
off_t start_offset;
|
|
||||||
|
|
||||||
uint32_t maxAudioSize=0;
|
|
||||||
|
|
||||||
uint32_t numComponents;
|
uint32_t numComponents;
|
||||||
off_t componentTypeOffset;
|
off_t componentTypeOffset;
|
||||||
off_t componentDataOffset;
|
off_t componentDataOffset;
|
||||||
|
|
||||||
char thpVersion;
|
|
||||||
|
|
||||||
int loop_flag;
|
char thpVersion;
|
||||||
int channel_count=-1;
|
|
||||||
int i;
|
int loop_flag;
|
||||||
|
int channel_count=-1;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("thp",filename_extension(filename)) &&
|
if (strcasecmp("thp",filename_extension(filename)) &&
|
||||||
strcasecmp("dsp",filename_extension(filename))) goto fail;
|
strcasecmp("dsp",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x54485000)
|
if (read_32bitBE(0x00,streamFile) != 0x54485000)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
maxAudioSize = read_32bitBE(0x0C,streamFile);
|
maxAudioSize = read_32bitBE(0x0C,streamFile);
|
||||||
thpVersion = read_8bit(0x06,streamFile);
|
thpVersion = read_8bit(0x06,streamFile);
|
||||||
|
|
||||||
if(maxAudioSize==0) // no sound
|
if(maxAudioSize==0) // no sound
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = 0; // allways unloop
|
loop_flag = 0; // allways unloop
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
if(thpVersion==0x10) {
|
if(thpVersion==0x10) {
|
||||||
start_offset = read_32bitBE(0x24,streamFile);
|
start_offset = read_32bitBE(0x24,streamFile);
|
||||||
/* No idea what's up with this */
|
/* No idea what's up with this */
|
||||||
if (start_offset == 0)
|
if (start_offset == 0)
|
||||||
start_offset = read_32bitBE(0x28,streamFile);
|
start_offset = read_32bitBE(0x28,streamFile);
|
||||||
} else
|
} else
|
||||||
start_offset = read_32bitBE(0x28,streamFile);
|
start_offset = read_32bitBE(0x28,streamFile);
|
||||||
|
|
||||||
// Get info from the first block
|
// Get info from the first block
|
||||||
componentTypeOffset = read_32bitBE(0x20,streamFile);
|
componentTypeOffset = read_32bitBE(0x20,streamFile);
|
||||||
numComponents = read_32bitBE(componentTypeOffset ,streamFile);
|
numComponents = read_32bitBE(componentTypeOffset ,streamFile);
|
||||||
componentDataOffset=componentTypeOffset+0x14;
|
componentDataOffset=componentTypeOffset+0x14;
|
||||||
componentTypeOffset+=4;
|
componentTypeOffset+=4;
|
||||||
|
|
||||||
for(i=0;i<numComponents;i++) {
|
for(i=0;i<numComponents;i++) {
|
||||||
if(read_8bit(componentTypeOffset+i,streamFile)==1) {
|
if(read_8bit(componentTypeOffset+i,streamFile)==1) {
|
||||||
channel_count=read_32bitBE(componentDataOffset,streamFile);
|
channel_count=read_32bitBE(componentDataOffset,streamFile);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
vgmstream->channels=channel_count;
|
vgmstream->channels=channel_count;
|
||||||
vgmstream->sample_rate=read_32bitBE(componentDataOffset+4,streamFile);
|
vgmstream->sample_rate=read_32bitBE(componentDataOffset+4,streamFile);
|
||||||
vgmstream->num_samples=read_32bitBE(componentDataOffset+8,streamFile);
|
vgmstream->num_samples=read_32bitBE(componentDataOffset+8,streamFile);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if(thpVersion==0x10)
|
if(thpVersion==0x10)
|
||||||
componentDataOffset+=0x0c;
|
componentDataOffset+=0x0c;
|
||||||
else
|
else
|
||||||
componentDataOffset+=0x08;
|
componentDataOffset+=0x08;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
@ -87,10 +87,10 @@ VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->thpNextFrameSize=read_32bitBE(0x18,streamFile);
|
vgmstream->thpNextFrameSize=read_32bitBE(0x18,streamFile);
|
||||||
thp_block_update(start_offset,vgmstream);
|
thp_block_update(start_offset,vgmstream);
|
||||||
|
|
||||||
vgmstream->coding_type = coding_NGC_DSP;
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
vgmstream->layout_type = layout_thp_blocked;
|
vgmstream->layout_type = layout_thp_blocked;
|
||||||
vgmstream->meta_type = meta_THP;
|
vgmstream->meta_type = meta_THP;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_tun(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -17,8 +17,8 @@ VGMSTREAM * init_vgmstream_tun(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x414C5020) /* "ALP " */
|
if (read_32bitBE(0x00,streamFile) != 0x414C5020) /* "ALP " */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
@ -30,11 +30,12 @@ typedef enum {
|
|||||||
XMA1 = 20, /* raw XMA1 */
|
XMA1 = 20, /* raw XMA1 */
|
||||||
XMA2 = 21, /* raw XMA2 */
|
XMA2 = 21, /* raw XMA2 */
|
||||||
FFMPEG = 22, /* any headered FFmpeg format */
|
FFMPEG = 22, /* any headered FFmpeg format */
|
||||||
|
AC3 = 23, /* AC3/SPDIF */
|
||||||
} txth_type;
|
} txth_type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
txth_type codec;
|
txth_type codec;
|
||||||
txth_type codec_mode;
|
uint32_t codec_mode;
|
||||||
uint32_t interleave;
|
uint32_t interleave;
|
||||||
|
|
||||||
uint32_t id_value;
|
uint32_t id_value;
|
||||||
@ -60,11 +61,12 @@ typedef struct {
|
|||||||
|
|
||||||
uint32_t coef_offset;
|
uint32_t coef_offset;
|
||||||
uint32_t coef_spacing;
|
uint32_t coef_spacing;
|
||||||
uint32_t coef_mode;
|
|
||||||
uint32_t coef_big_endian;
|
uint32_t coef_big_endian;
|
||||||
|
uint32_t coef_mode;
|
||||||
|
|
||||||
} txth_header;
|
} txth_header;
|
||||||
|
|
||||||
|
static STREAMFILE * open_txth(STREAMFILE * streamFile);
|
||||||
static int parse_txth(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth);
|
static int parse_txth(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth);
|
||||||
static int parse_keyval(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth, const char * key, const char * val);
|
static int parse_keyval(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth, const char * key, const char * val);
|
||||||
static int parse_num(STREAMFILE * streamFile, const char * val, uint32_t * out_value);
|
static int parse_num(STREAMFILE * streamFile, const char * val, uint32_t * out_value);
|
||||||
@ -76,44 +78,16 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes);
|
|||||||
VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
STREAMFILE * streamText = NULL;
|
STREAMFILE * streamText = NULL;
|
||||||
txth_header txth;
|
txth_header txth = {0};
|
||||||
coding_t coding;
|
coding_t coding;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
/* no need for ID or ext checks -- if a .TXTH exists all is good
|
/* no need for ID or ext checks -- if a .TXTH exists all is good
|
||||||
* (player still needs to accept the ext, so at worst rename to .vgmstream) */
|
* (player still needs to accept the ext, so at worst rename to .vgmstream) */
|
||||||
{
|
streamText = open_txth(streamFile);
|
||||||
char filename[PATH_LIMIT];
|
if (!streamText) goto fail;
|
||||||
char fileext[PATH_LIMIT];
|
|
||||||
|
|
||||||
/* try "(path/)(name.ext).txth" */
|
|
||||||
if (!get_streamfile_name(streamFile,filename,PATH_LIMIT)) goto fail;
|
|
||||||
strcat(filename, ".txth");
|
|
||||||
streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (streamText) goto found;
|
|
||||||
|
|
||||||
/* try "(path/)(.ext).txth" */
|
|
||||||
if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail;
|
|
||||||
if (!get_streamfile_ext(streamFile,fileext,PATH_LIMIT)) goto fail;
|
|
||||||
strcat(filename,".");
|
|
||||||
strcat(filename, fileext);
|
|
||||||
strcat(filename, ".txth");
|
|
||||||
streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (streamText) goto found;
|
|
||||||
|
|
||||||
/* try "(path/).txth" */
|
|
||||||
if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail;
|
|
||||||
strcat(filename, ".txth");
|
|
||||||
streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (streamText) goto found;
|
|
||||||
|
|
||||||
/* not found */
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
found:
|
|
||||||
|
|
||||||
/* process the text file */
|
/* process the text file */
|
||||||
memset(&txth,0,sizeof(txth_header));
|
|
||||||
if (!parse_txth(streamFile, streamText, &txth))
|
if (!parse_txth(streamFile, streamText, &txth))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -145,6 +119,7 @@ found:
|
|||||||
case ATRAC3PLUS:
|
case ATRAC3PLUS:
|
||||||
case XMA1:
|
case XMA1:
|
||||||
case XMA2:
|
case XMA2:
|
||||||
|
case AC3:
|
||||||
case FFMPEG: coding = coding_FFmpeg; break;
|
case FFMPEG: coding = coding_FFmpeg; break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@ -261,7 +236,8 @@ found:
|
|||||||
for (j=0;j<16;j++) {
|
for (j=0;j<16;j++) {
|
||||||
vgmstream->ch[i].adpcm_coef[j] = read_16bit(txth.coef_offset + i*txth.coef_spacing + j*2,streamFile);
|
vgmstream->ch[i].adpcm_coef[j] = read_16bit(txth.coef_offset + i*txth.coef_spacing + j*2,streamFile);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
goto fail; //IDK what is this
|
goto fail; //IDK what is this
|
||||||
/*
|
/*
|
||||||
for (j=0;j<8;j++) {
|
for (j=0;j<8;j++) {
|
||||||
@ -285,7 +261,7 @@ found:
|
|||||||
case coding_FFmpeg: {
|
case coding_FFmpeg: {
|
||||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
|
||||||
if (txth.codec == FFMPEG) {
|
if (txth.codec == FFMPEG || txth.codec == AC3) {
|
||||||
/* default FFmpeg */
|
/* default FFmpeg */
|
||||||
ffmpeg_data = init_ffmpeg_offset(streamFile, txth.start_offset,txth.data_size);
|
ffmpeg_data = init_ffmpeg_offset(streamFile, txth.start_offset,txth.data_size);
|
||||||
if ( !ffmpeg_data ) goto fail;
|
if ( !ffmpeg_data ) goto fail;
|
||||||
@ -390,6 +366,38 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static STREAMFILE * open_txth(STREAMFILE * streamFile) {
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
char fileext[PATH_LIMIT];
|
||||||
|
STREAMFILE * streamText;
|
||||||
|
|
||||||
|
/* try "(path/)(name.ext).txth" */
|
||||||
|
if (!get_streamfile_name(streamFile,filename,PATH_LIMIT)) goto fail;
|
||||||
|
strcat(filename, ".txth");
|
||||||
|
streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
if (streamText) return streamText;
|
||||||
|
|
||||||
|
/* try "(path/)(.ext).txth" */
|
||||||
|
if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail;
|
||||||
|
if (!get_streamfile_ext(streamFile,fileext,PATH_LIMIT)) goto fail;
|
||||||
|
strcat(filename,".");
|
||||||
|
strcat(filename, fileext);
|
||||||
|
strcat(filename, ".txth");
|
||||||
|
streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
if (streamText) return streamText;
|
||||||
|
|
||||||
|
/* try "(path/).txth" */
|
||||||
|
if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail;
|
||||||
|
strcat(filename, ".txth");
|
||||||
|
streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
if (streamText) return streamText;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* not found */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Simple text parser of "key = value" lines.
|
/* Simple text parser of "key = value" lines.
|
||||||
* The code is meh and error handling not exactly the best. */
|
* The code is meh and error handling not exactly the best. */
|
||||||
static int parse_txth(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth) {
|
static int parse_txth(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth) {
|
||||||
@ -472,6 +480,7 @@ static int parse_keyval(STREAMFILE * streamFile, STREAMFILE * streamText, txth_h
|
|||||||
else if (0==strcmp(val,"XMA1")) txth->codec = XMA1;
|
else if (0==strcmp(val,"XMA1")) txth->codec = XMA1;
|
||||||
else if (0==strcmp(val,"XMA2")) txth->codec = XMA2;
|
else if (0==strcmp(val,"XMA2")) txth->codec = XMA2;
|
||||||
else if (0==strcmp(val,"FFMPEG")) txth->codec = FFMPEG;
|
else if (0==strcmp(val,"FFMPEG")) txth->codec = FFMPEG;
|
||||||
|
else if (0==strcmp(val,"AC3")) txth->codec = AC3;
|
||||||
else goto fail;
|
else goto fail;
|
||||||
}
|
}
|
||||||
else if (0==strcmp(key,"codec_mode")) {
|
else if (0==strcmp(key,"codec_mode")) {
|
||||||
@ -663,6 +672,10 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) {
|
|||||||
case XMA2:
|
case XMA2:
|
||||||
return bytes; /* preserve */
|
return bytes; /* preserve */
|
||||||
|
|
||||||
|
case AC3:
|
||||||
|
if (!txth->interleave) return 0;
|
||||||
|
return bytes / txth->interleave * 256 * txth->channels;
|
||||||
|
|
||||||
/* untested */
|
/* untested */
|
||||||
case IMA:
|
case IMA:
|
||||||
case DVI_IMA:
|
case DVI_IMA:
|
||||||
|
@ -34,6 +34,8 @@ typedef struct {
|
|||||||
size_t stream_id_offset;
|
size_t stream_id_offset;
|
||||||
int has_short_channels;
|
int has_short_channels;
|
||||||
int has_internal_names;
|
int has_internal_names;
|
||||||
|
int has_extra_name_flag;
|
||||||
|
int has_rotating_ids;
|
||||||
|
|
||||||
/* derived */
|
/* derived */
|
||||||
size_t main_size;
|
size_t main_size;
|
||||||
@ -73,8 +75,6 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
|||||||
/* check extension (number represents the platform, see later) */
|
/* check extension (number represents the platform, see later) */
|
||||||
if ( !check_extensions(streamFile,"sb0,sb1,sb2,sb3,sb4,sb5,sb6,sb7") )
|
if ( !check_extensions(streamFile,"sb0,sb1,sb2,sb3,sb4,sb5,sb6,sb7") )
|
||||||
goto fail;
|
goto fail;
|
||||||
//memset(&sb,0,sizeof(ubi_sb_header)); //todo test for VC2010's init = {0} above (should be C89 but...)
|
|
||||||
if (sb.flag1 != 0 || sb.codec!=0 || sb.stream_samples != 0) { VGM_LOG("UBI SB: not init ok\n"); goto fail; }
|
|
||||||
|
|
||||||
|
|
||||||
/* .sb0 (sound bank) is a small multisong format (loaded in memory?) that contains SFX data
|
/* .sb0 (sound bank) is a small multisong format (loaded in memory?) that contains SFX data
|
||||||
@ -119,7 +119,7 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
|||||||
start_offset = sb.main_size + sb.section1_size + sb.section2_size + sb.extra_size + sb.section3_size;
|
start_offset = sb.main_size + sb.section1_size + sb.section2_size + sb.extra_size + sb.section3_size;
|
||||||
start_offset += sb.stream_offset;
|
start_offset += sb.stream_offset;
|
||||||
}
|
}
|
||||||
;VGM_LOG("so=%lx, main=%x, s1=%x, s2=%x, ex=%x, s3=%x, so=%lx\n", start_offset, sb.main_size, sb.section1_size, sb.section2_size, sb.extra_size, sb.section3_size, sb.stream_offset);
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(sb.channels,loop_flag);
|
vgmstream = allocate_vgmstream(sb.channels,loop_flag);
|
||||||
@ -131,7 +131,7 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
|
|
||||||
switch(sb.codec) {
|
switch(sb.codec) {
|
||||||
case UBI_ADPCM: { //todo move to its own decoder
|
case UBI_ADPCM: {
|
||||||
vgmstream->coding_type = coding_UBI_IMA;
|
vgmstream->coding_type = coding_UBI_IMA;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->num_samples = ubi_ima_bytes_to_samples(sb.stream_size, sb.channels, streamData, start_offset);
|
vgmstream->num_samples = ubi_ima_bytes_to_samples(sb.stream_size, sb.channels, streamData, start_offset);
|
||||||
@ -139,11 +139,10 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case RAW_PCM:
|
case RAW_PCM:
|
||||||
vgmstream->coding_type = coding_PCM16LE;
|
vgmstream->coding_type = coding_PCM16LE; /* always LE even on Wii */
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x02;
|
vgmstream->interleave_block_size = 0x02;
|
||||||
vgmstream->num_samples = pcm_bytes_to_samples(sb.stream_size, sb.channels, 16);
|
vgmstream->num_samples = pcm_bytes_to_samples(sb.stream_size, sb.channels, 16);
|
||||||
if (sb.channels > 1) { VGM_LOG("UBI SB: >1 channel\n"); goto fail; } //todo
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RAW_PSX:
|
case RAW_PSX:
|
||||||
@ -183,7 +182,8 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
|||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = sb.stream_size / sb.channels;
|
vgmstream->interleave_block_size = sb.stream_size / sb.channels;
|
||||||
vgmstream->num_samples = ps_bytes_to_samples(sb.stream_size, sb.channels) ;
|
vgmstream->num_samples = ps_bytes_to_samples(sb.stream_size, sb.channels);
|
||||||
|
|
||||||
if (sb.channels > 1) { VGM_LOG("UBI SB: >1 channel\n"); goto fail; } //todo
|
if (sb.channels > 1) { VGM_LOG("UBI SB: >1 channel\n"); goto fail; } //todo
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ fail:
|
|||||||
static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
||||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||||
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
||||||
int i, ok;
|
int i, ok, current_type = -1, current_id = -1;
|
||||||
int target_stream = streamFile->stream_index;
|
int target_stream = streamFile->stream_index;
|
||||||
|
|
||||||
if (target_stream == 0) target_stream = 1;
|
if (target_stream == 0) target_stream = 1;
|
||||||
@ -284,7 +284,7 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
sb->section1_num = read_32bit(0x04, streamFile); /* group headers? */
|
sb->section1_num = read_32bit(0x04, streamFile); /* group headers? */
|
||||||
sb->section2_num = read_32bit(0x08, streamFile); /* streams headers (internal or external) */
|
sb->section2_num = read_32bit(0x08, streamFile); /* streams headers (internal or external) */
|
||||||
sb->section3_num = read_32bit(0x0c, streamFile); /* internal streams table */
|
sb->section3_num = read_32bit(0x0c, streamFile); /* internal streams table */
|
||||||
sb->extra_size = read_32bit(0x10, streamFile); /* extra table, unknown except with DSP = coefs */
|
sb->extra_size = read_32bit(0x10, streamFile); /* extra table, unknown (config for non-audio types) except with DSP = coefs */
|
||||||
sb->flag1 = read_32bit(0x14, streamFile); /* unknown, usually -1 but can be others (0/1/2/etc) */
|
sb->flag1 = read_32bit(0x14, streamFile); /* unknown, usually -1 but can be others (0/1/2/etc) */
|
||||||
sb->flag2 = read_32bit(0x18, streamFile); /* unknown, usually -1 but can be others */
|
sb->flag2 = read_32bit(0x18, streamFile); /* unknown, usually -1 but can be others */
|
||||||
|
|
||||||
@ -307,11 +307,39 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
if (read_32bit(offset + 0x04, streamFile) != 0x01)
|
if (read_32bit(offset + 0x04, streamFile) != 0x01)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* weird case when there is no internal substream ID and just seem to rotate every time type changes, joy */
|
||||||
|
if (sb->has_rotating_ids) { /* assumes certain configs can't happen in this case */
|
||||||
|
int current_is_external = 0;
|
||||||
|
int type = read_32bit(offset + sb->stream_type_offset, streamFile);
|
||||||
|
|
||||||
|
if (current_type == -1)
|
||||||
|
current_type = type;
|
||||||
|
if (current_id == -1) /* use first ID in section3 */
|
||||||
|
current_id = read_32bit(sb->main_size + sb->section1_size + sb->section2_size + sb->extra_size + 0x00, streamFile);
|
||||||
|
|
||||||
|
if (sb->external_flag_offset) {
|
||||||
|
current_is_external = read_32bit(offset + sb->external_flag_offset, streamFile);
|
||||||
|
} else if (sb->has_extra_name_flag && read_32bit(offset + sb->extra_name_offset, streamFile) != 0xFFFFFFFF) {
|
||||||
|
current_is_external = 1; /* -1 in extra_name means internal */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!current_is_external) {
|
||||||
|
if (current_type != type) {
|
||||||
|
current_type = type;
|
||||||
|
current_id++; /* rotate */
|
||||||
|
if (current_id >= sb->section3_num)
|
||||||
|
current_id = 0; /* reset */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* update streams (total_stream also doubles as current) */
|
/* update streams (total_stream also doubles as current) */
|
||||||
sb->total_streams++;
|
sb->total_streams++;
|
||||||
if (sb->total_streams != target_stream)
|
if (sb->total_streams != target_stream)
|
||||||
continue;
|
continue;
|
||||||
;VGM_LOG("target at offset=%lx (size=%x)\n", offset, sb->section2_entry_size);
|
//;VGM_LOG("target at offset=%lx (size=%x)\n", offset, sb->section2_entry_size);
|
||||||
|
|
||||||
sb->header_id = read_32bit(offset + 0x00, streamFile); /* 16b+16b group+sound id */
|
sb->header_id = read_32bit(offset + 0x00, streamFile); /* 16b+16b group+sound id */
|
||||||
sb->header_type = read_32bit(offset + 0x04, streamFile);
|
sb->header_type = read_32bit(offset + 0x04, streamFile);
|
||||||
@ -327,8 +355,11 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
if (sb->num_samples_offset)
|
if (sb->num_samples_offset)
|
||||||
sb->stream_samples = read_32bit(offset + sb->num_samples_offset, streamFile);
|
sb->stream_samples = read_32bit(offset + sb->num_samples_offset, streamFile);
|
||||||
|
|
||||||
if (sb->stream_id_offset)
|
if (sb-> has_rotating_ids) {
|
||||||
|
sb->stream_id = current_id;
|
||||||
|
} else if (sb->stream_id_offset) {
|
||||||
sb->stream_id = read_32bit(offset + sb->stream_id_offset, streamFile);
|
sb->stream_id = read_32bit(offset + sb->stream_id_offset, streamFile);
|
||||||
|
}
|
||||||
|
|
||||||
/* external stream name can be found in the header (first versions) or the extra table (later versions) */
|
/* external stream name can be found in the header (first versions) or the extra table (later versions) */
|
||||||
if (sb->stream_name_offset) {
|
if (sb->stream_name_offset) {
|
||||||
@ -341,6 +372,8 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
/* not always set and must be derived */
|
/* not always set and must be derived */
|
||||||
if (sb->external_flag_offset) {
|
if (sb->external_flag_offset) {
|
||||||
sb->is_external = read_32bit(offset + sb->external_flag_offset, streamFile);
|
sb->is_external = read_32bit(offset + sb->external_flag_offset, streamFile);
|
||||||
|
} else if (sb->has_extra_name_flag && read_32bit(offset + sb->extra_name_offset, streamFile) != 0xFFFFFFFF) {
|
||||||
|
sb->is_external = 1; /* -1 in extra_name means internal */
|
||||||
} else if (sb->section3_num == 0) {
|
} else if (sb->section3_num == 0) {
|
||||||
sb->is_external = 1;
|
sb->is_external = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -361,7 +394,7 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sb->stream_id_offset && sb->section3_num > 1) {
|
if (!(sb->stream_id_offset || sb->has_rotating_ids) && sb->section3_num > 1) {
|
||||||
VGM_LOG("UBI SB: unexpected number of internal streams %i\n", sb->section3_num);
|
VGM_LOG("UBI SB: unexpected number of internal streams %i\n", sb->section3_num);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -392,6 +425,10 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x01: /* PCM (Wii, rarely used) */
|
||||||
|
sb->codec = RAW_PCM;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x03: /* Ubi ADPCM (main external stream codec, has subtypes) */
|
case 0x03: /* Ubi ADPCM (main external stream codec, has subtypes) */
|
||||||
sb->codec = UBI_ADPCM;
|
sb->codec = UBI_ADPCM;
|
||||||
break;
|
break;
|
||||||
@ -404,7 +441,6 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
sb->codec = FMT_AT3;
|
sb->codec = FMT_AT3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: /* PCM? (Wii, rarely used) */
|
|
||||||
default:
|
default:
|
||||||
VGM_LOG("UBI SB: unknown stream_type %x\n", sb->stream_type);
|
VGM_LOG("UBI SB: unknown stream_type %x\n", sb->stream_type);
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -413,12 +449,11 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
|||||||
/* uncommon but possible */
|
/* uncommon but possible */
|
||||||
//VGM_ASSERT(sb->is_external && sb->section3_num != 0, "UBI SS: mixed external and internal streams\n");
|
//VGM_ASSERT(sb->is_external && sb->section3_num != 0, "UBI SS: mixed external and internal streams\n");
|
||||||
|
|
||||||
/* seems can be safely ignored */
|
/* seems that can be safely ignored */
|
||||||
//VGM_ASSERT(sb->is_external && sb->stream_id_offset && sb->stream_id > 0, "UBI SB: unexpected external stream with stream id\n");
|
//VGM_ASSERT(sb->is_external && sb->stream_id_offset && sb->stream_id > 0, "UBI SB: unexpected external stream with stream id\n");
|
||||||
|
|
||||||
//todo fix, wrong
|
|
||||||
/* section 3: substreams within the file, adjust stream offset (rarely used but table is always present) */
|
/* section 3: substreams within the file, adjust stream offset (rarely used but table is always present) */
|
||||||
if (!sb->is_external && sb->stream_id_offset && sb->section3_num > 1) {
|
if (!sb->is_external && (sb->stream_id_offset || sb->has_rotating_ids) && sb->section3_num > 1) {
|
||||||
for (i = 0; i < sb->section3_num; i++) {
|
for (i = 0; i < sb->section3_num; i++) {
|
||||||
off_t offset = sb->main_size + sb->section1_size + sb->section2_size + sb->extra_size + sb->section3_entry_size * i;
|
off_t offset = sb->main_size + sb->section1_size + sb->section2_size + sb->extra_size + sb->section3_entry_size * i;
|
||||||
|
|
||||||
@ -620,13 +655,14 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile)
|
|||||||
sb->section2_entry_size = 0x78;
|
sb->section2_entry_size = 0x78;
|
||||||
|
|
||||||
sb->external_flag_offset = 0x2c;
|
sb->external_flag_offset = 0x2c;
|
||||||
sb->stream_id_offset = 0x34;//todo test
|
sb->stream_id_offset = 0x34;
|
||||||
sb->num_samples_offset = 0x40;
|
sb->num_samples_offset = 0x40;
|
||||||
sb->sample_rate_offset = 0x54;
|
sb->sample_rate_offset = 0x54;
|
||||||
sb->channels_offset = 0x5c;
|
sb->channels_offset = 0x5c;
|
||||||
sb->stream_type_offset = 0x60;
|
sb->stream_type_offset = 0x60;
|
||||||
sb->extra_name_offset = 0x64;
|
sb->extra_name_offset = 0x64;
|
||||||
|
|
||||||
|
sb->has_extra_name_flag = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,13 +671,14 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile)
|
|||||||
sb->section1_entry_size = 0x48;
|
sb->section1_entry_size = 0x48;
|
||||||
sb->section2_entry_size = 0x5c;
|
sb->section2_entry_size = 0x5c;
|
||||||
|
|
||||||
sb->external_flag_offset = 0; /* no apparent flag */
|
sb->external_flag_offset = 0;
|
||||||
sb->channels_offset = 0x2c;
|
sb->channels_offset = 0x2c;
|
||||||
sb->sample_rate_offset = 0x30;
|
sb->sample_rate_offset = 0x30;
|
||||||
sb->num_samples_offset = 0x3c;
|
sb->num_samples_offset = 0x3c;
|
||||||
sb->extra_name_offset = 0x4c;
|
sb->extra_name_offset = 0x4c;
|
||||||
sb->stream_type_offset = 0x50;
|
sb->stream_type_offset = 0x50;
|
||||||
|
|
||||||
|
sb->has_extra_name_flag = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,15 +687,16 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile)
|
|||||||
sb->section1_entry_size = 0x48;
|
sb->section1_entry_size = 0x48;
|
||||||
sb->section2_entry_size = 0x58;
|
sb->section2_entry_size = 0x58;
|
||||||
|
|
||||||
sb->external_flag_offset = 0; /* no apparent flag */
|
sb->external_flag_offset = 0;
|
||||||
sb->num_samples_offset = 0x28;
|
sb->num_samples_offset = 0x28;
|
||||||
sb->stream_id_offset = 0x34;//todo test
|
sb->stream_id_offset = 0;
|
||||||
sb->sample_rate_offset = 0x3c;
|
sb->sample_rate_offset = 0x3c;
|
||||||
sb->channels_offset = 0x44;
|
sb->channels_offset = 0x44;
|
||||||
sb->stream_type_offset = 0x48;
|
sb->stream_type_offset = 0x48;
|
||||||
sb->extra_name_offset = 0x4c;
|
sb->extra_name_offset = 0x4c;
|
||||||
|
|
||||||
sb->has_internal_names = 1;
|
sb->has_extra_name_flag = 1;
|
||||||
|
sb->has_rotating_ids = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,18 +715,34 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Red Steel (2006)(Wii) */
|
||||||
|
if (sb->version == 0x00180006 && is_sb7) { /* same as 0x00150000 */
|
||||||
|
sb->section1_entry_size = 0x68;
|
||||||
|
sb->section2_entry_size = 0x6c;
|
||||||
|
|
||||||
|
sb->external_flag_offset = 0x28; /* maybe 0x2c */
|
||||||
|
sb->num_samples_offset = 0x3c;
|
||||||
|
sb->sample_rate_offset = 0x50;
|
||||||
|
sb->channels_offset = 0x58;
|
||||||
|
sb->stream_type_offset = 0x5c;
|
||||||
|
sb->extra_name_offset = 0x60;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prince of Persia: Rival Swords (2007)(PSP) */
|
/* Prince of Persia: Rival Swords (2007)(PSP) */
|
||||||
if (sb->version == 0x00180005 && is_sb5) {
|
if (sb->version == 0x00180005 && is_sb5) {
|
||||||
sb->section1_entry_size = 0x48;
|
sb->section1_entry_size = 0x48;
|
||||||
sb->section2_entry_size = 0x54;
|
sb->section2_entry_size = 0x54;
|
||||||
|
|
||||||
sb->external_flag_offset = 0; /* no apparent flag */
|
sb->external_flag_offset = 0;
|
||||||
sb->channels_offset = 0x28;
|
sb->channels_offset = 0x28;
|
||||||
sb->sample_rate_offset = 0x2c;
|
sb->sample_rate_offset = 0x2c;
|
||||||
//sb->num_samples_offset = 0x34 or 0x3c /* varies */
|
//sb->num_samples_offset = 0x34 or 0x3c /* varies */
|
||||||
sb->extra_name_offset = 0x44;
|
sb->extra_name_offset = 0x44;
|
||||||
sb->stream_type_offset = 0x48;
|
sb->stream_type_offset = 0x48;
|
||||||
|
|
||||||
|
sb->has_extra_name_flag = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,7 +753,7 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile)
|
|||||||
|
|
||||||
sb->external_flag_offset = 0x28; /* maybe 0x2c */
|
sb->external_flag_offset = 0x28; /* maybe 0x2c */
|
||||||
sb->channels_offset = 0x3c;
|
sb->channels_offset = 0x3c;
|
||||||
sb->sample_rate_offset = 0x44;
|
sb->sample_rate_offset = 0x40;
|
||||||
sb->num_samples_offset = 0x48;
|
sb->num_samples_offset = 0x48;
|
||||||
sb->extra_name_offset = 0x58;
|
sb->extra_name_offset = 0x58;
|
||||||
sb->stream_type_offset = 0x5c;
|
sb->stream_type_offset = 0x5c;
|
||||||
|
@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_wpd(STREAMFILE *streamFile) {
|
|||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -17,8 +17,8 @@ VGMSTREAM * init_vgmstream_wpd(STREAMFILE *streamFile) {
|
|||||||
if (read_32bitBE(0x00,streamFile) != 0x20445057) /* " DPW" */
|
if (read_32bitBE(0x00,streamFile) != 0x20445057) /* " DPW" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
channel_count = read_32bitLE(0x4,streamFile);
|
channel_count = read_32bitLE(0x4,streamFile);
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
@ -128,8 +128,8 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* other Wwise specific: */
|
/* other Wwise specific: */
|
||||||
//"JUNK": optional padding so that raw data starts in an offset multiple of 0x10 (0-size JUNK exists too)
|
//"JUNK": optional padding for usually aligment (0-size JUNK exists too)
|
||||||
//"akd ": unknown (IMA/PCM; "audiokinetic data"?)
|
//"akd ": seem to store extra info for Wwise editor (wave peaks/loudness/HDR envelope?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* format to codec */
|
/* format to codec */
|
||||||
@ -158,7 +158,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
|||||||
ww.codec = DSP;
|
ww.codec = DSP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some Wwise files (ex. Oddworld PSV, Bayonetta 2 WiiU sfx) are truncated mirrors of another file.
|
/* Some Wwise files (ex. Oddworld PSV, Bayonetta 2 WiiU, often in BGM.bnk) are truncated mirrors of another file.
|
||||||
* They come in RAM banks, probably to play the beginning while the rest of the real stream loads.
|
* They come in RAM banks, probably to play the beginning while the rest of the real stream loads.
|
||||||
* We'll add basic support to avoid complaints of this or that .wem not playing */
|
* We'll add basic support to avoid complaints of this or that .wem not playing */
|
||||||
if (ww.data_size > ww.file_size) {
|
if (ww.data_size > ww.file_size) {
|
||||||
@ -560,50 +560,50 @@ fail:
|
|||||||
0x00 (4): num_samples
|
0x00 (4): num_samples
|
||||||
0x04 (4): skip samples?
|
0x04 (4): skip samples?
|
||||||
0x08 (4): ? (small if loop, 0 otherwise)
|
0x08 (4): ? (small if loop, 0 otherwise)
|
||||||
0x0c (4): loop offset after seek table+setup (offset after setup if file doesn't loop)
|
0x0c (4): data start offset after seek table+setup, or loop start when "smpl" is present
|
||||||
0x10 (4): ? (small, 0..~0x400)
|
0x10 (4): ? (small, 0..~0x400)
|
||||||
0x14 (4): approximate data size without seek table? (almost setup+packets)
|
0x14 (4): approximate data size without seek table? (almost setup+packets)
|
||||||
0x18 (4): setup_offset within data (0 = no seek table)
|
0x18 (4): setup_offset within data (0 = no seek table)
|
||||||
0x1c (4): audio_offset within data
|
0x1c (4): audio_offset within data
|
||||||
0x20 (4): biggest packet size (not including header)?
|
0x20 (2): biggest packet size (not including header)?
|
||||||
0x24 (4): ? (mid, 0~0x5000)
|
0x22 (2): ? (small, N..~0x100) uLastGranuleExtra?
|
||||||
0x28 (4): ? (mid, 0~0x5000)
|
0x24 (4): ? (mid, 0~0x5000) dwDecodeAllocSize?
|
||||||
0x2c (4): parent bank/event id? (shared by several .wem a game, but not all need to share it)
|
0x28 (4): ? (mid, 0~0x5000) dwDecodeX64AllocSize?
|
||||||
|
0x2c (4): parent bank/event id? uHashCodebook? (shared by several .wem a game, but not all need to share it)
|
||||||
0x30 (1): blocksize_1_exp (small)
|
0x30 (1): blocksize_1_exp (small)
|
||||||
0x31 (1): blocksize_0_exp (large)
|
0x31 (1): blocksize_0_exp (large)
|
||||||
0x32 (2): empty
|
0x32 (2): empty
|
||||||
|
|
||||||
"vorb" size 0x28 / 0x2a
|
"vorb" size 0x28 / 0x2a
|
||||||
0x00 (4): num_samples
|
0x00 (4): num_samples
|
||||||
0x04 (4): loop offset after seek table+setup (offset after setup if file doesn't loop)
|
0x04 (4): data start offset after seek table+setup, or loop start when "smpl" is present
|
||||||
0x08 (4): data size without seek table (setup+packets)
|
0x08 (4): data end offset after seek table (setup+packets), or loop end when "smpl" is present
|
||||||
0x0c (2): ? (small, 0..~0x400)
|
0x0c (2): ? (small, 0..~0x400)
|
||||||
0x10 (4): setup_offset within data (0 = no seek table)
|
0x10 (4): setup_offset within data (0 = no seek table)
|
||||||
0x14 (4): audio_offset within data
|
0x14 (4): audio_offset within data
|
||||||
0x18 (2): ? (small, 0..~0x400)
|
0x18 (2): biggest packet size (not including header)?
|
||||||
0x1a (2): ? (small, N..~0x100)
|
0x1a (2): ? (small, N..~0x100) uLastGranuleExtra?
|
||||||
0x1c (4): ? (mid, 0~0x5000)
|
0x1c (4): ? (mid, 0~0x5000) dwDecodeAllocSize?
|
||||||
0x20 (4): ? (mid, 0~0x5000)
|
0x20 (4): ? (mid, 0~0x5000) dwDecodeX64AllocSize?
|
||||||
0x24 (4): parent bank/event id? (shared by several .wem a game, but not all need to share it)
|
0x24 (4): parent bank/event id? uHashCodebook? (shared by several .wem a game, but not all need to share it)
|
||||||
0x28 (1): blocksize_1_exp (small) [removed when size is 0x28]
|
0x28 (1): blocksize_1_exp (small) [removed when size is 0x28]
|
||||||
0x29 (1): blocksize_0_exp (large) [removed when size is 0x28]
|
0x29 (1): blocksize_0_exp (large) [removed when size is 0x28]
|
||||||
|
|
||||||
|
|
||||||
- new format:
|
- new format:
|
||||||
"fmt" size 0x42, extra size 0x30
|
"fmt" size 0x42, extra size 0x30
|
||||||
0x12 (2): flag? (00,10,18): not related to seek table, codebook type, chunk count, looping, etc
|
0x12 (2): flag? (00,10,18): not related to seek table, codebook type, chunk count, looping, etc
|
||||||
0x14 (4): channel config
|
0x14 (4): channel config
|
||||||
0x18 (4): num_samples
|
0x18 (4): num_samples
|
||||||
0x1c (4): loop offset after seek table+setup (offset after setup if file doesn't loop)
|
0x1c (4): data start offset after seek table+setup, or loop start when "smpl" is present
|
||||||
0x20 (4): data size without seek table (setup+packets)
|
0x20 (4): data end offset after seek table (setup+packets), or loop end when "smpl" is present
|
||||||
0x24 (2): ?1 (small, 0..~0x400)
|
0x24 (2): ?1 (small, 0..~0x400)
|
||||||
0x26 (2): ?2 (small, N..~0x100): not related to seek table, codebook type, chunk count, looping, packet size, samples, etc
|
0x26 (2): ?2 (small, N..~0x100): not related to seek table, codebook type, chunk count, looping, packet size, samples, etc
|
||||||
0x28 (4): setup offset within data (0 = no seek table)
|
0x28 (4): setup offset within data (0 = no seek table)
|
||||||
0x2c (4): audio offset within data
|
0x2c (4): audio offset within data
|
||||||
0x30 (2): biggest packet size (not including header)
|
0x30 (2): biggest packet size (not including header)
|
||||||
0x32 (2): ?4 (small, 0..~0x100): may be same than ?2 (something related to the avg bitrate?)
|
0x32 (2): (small, 0..~0x100) uLastGranuleExtra?
|
||||||
0x34 (4): bitrate config? (mid, 0~0x5000)
|
0x34 (4): ? (mid, 0~0x5000) dwDecodeAllocSize?
|
||||||
0x38 (4): bitrate config? (mid, 0~0x5000) (2 byte with max/min?)
|
0x38 (4): ? (mid, 0~0x5000) dwDecodeX64AllocSize?
|
||||||
0x40 (1): blocksize_1_exp (small)
|
0x40 (1): blocksize_1_exp (small)
|
||||||
0x41 (1): blocksize_0_exp (large)
|
0x41 (1): blocksize_0_exp (large)
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ static const int wma_block_align_index[17] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef enum { PCM, XBOX_ADPCM, MS_ADPCM, XMA1, XMA2, WMA, XWMA, ATRAC3 } xact_codec;
|
typedef enum { PCM, XBOX_ADPCM, MS_ADPCM, XMA1, XMA2, WMA, XWMA, ATRAC3, OGG } xact_codec;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int little_endian;
|
int little_endian;
|
||||||
int version;
|
int version;
|
||||||
@ -124,8 +124,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
/* for Techland's XWB with no data */
|
/* for Techland's XWB with no data */
|
||||||
if (xwb.base_offset == 0) goto fail;
|
if (xwb.base_offset == 0) goto fail;
|
||||||
/* some BlazBlue Centralfiction songs have padding after data size */
|
|
||||||
if (xwb.data_offset + xwb.data_size > get_streamfile_size(streamFile)) goto fail;
|
|
||||||
|
|
||||||
/* read base entry (WAVEBANKDATA) */
|
/* read base entry (WAVEBANKDATA) */
|
||||||
off = xwb.base_offset;
|
off = xwb.base_offset;
|
||||||
@ -168,8 +166,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
xwb.loop_start = (uint32_t)read_32bit(off+0x0c, streamFile);
|
xwb.loop_start = (uint32_t)read_32bit(off+0x0c, streamFile);
|
||||||
xwb.loop_end = (uint32_t)read_32bit(off+0x10, streamFile);//length
|
xwb.loop_end = (uint32_t)read_32bit(off+0x10, streamFile);//length
|
||||||
|
|
||||||
xwb.loop_flag = (xwb.loop_end > 0 || xwb.loop_end_sample > xwb.loop_start);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint32_t entry_info = (uint32_t)read_32bit(off+0x00, streamFile);
|
uint32_t entry_info = (uint32_t)read_32bit(off+0x00, streamFile);
|
||||||
@ -190,9 +186,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
xwb.loop_start_sample = (uint32_t)read_32bit(off+0x10, streamFile);
|
xwb.loop_start_sample = (uint32_t)read_32bit(off+0x10, streamFile);
|
||||||
xwb.loop_end_sample = (uint32_t)read_32bit(off+0x14, streamFile) + xwb.loop_start_sample;
|
xwb.loop_end_sample = (uint32_t)read_32bit(off+0x14, streamFile) + xwb.loop_start_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
xwb.loop_flag = (xwb.loop_end > 0 || xwb.loop_end_sample > xwb.loop_start)
|
|
||||||
&& !(xwb.entry_flags & WAVEBANKENTRY_FLAGS_IGNORELOOP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -231,14 +224,17 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
case 1: xwb.codec = XBOX_ADPCM; break;
|
case 1: xwb.codec = XBOX_ADPCM; break;
|
||||||
default: goto fail;
|
default: goto fail;
|
||||||
}
|
}
|
||||||
} else if (xwb.version <= XACT1_1_MAX) {
|
}
|
||||||
|
else if (xwb.version <= XACT1_1_MAX) {
|
||||||
switch(xwb.tag){
|
switch(xwb.tag){
|
||||||
case 0: xwb.codec = PCM; break;
|
case 0: xwb.codec = PCM; break;
|
||||||
case 1: xwb.codec = XBOX_ADPCM; break;
|
case 1: xwb.codec = XBOX_ADPCM; break;
|
||||||
case 2: xwb.codec = WMA; break;
|
case 2: xwb.codec = WMA; break;
|
||||||
|
case 3: xwb.codec = OGG; break; /* extension */
|
||||||
default: goto fail;
|
default: goto fail;
|
||||||
}
|
}
|
||||||
} else if (xwb.version <= XACT2_2_MAX) {
|
}
|
||||||
|
else if (xwb.version <= XACT2_2_MAX) {
|
||||||
switch(xwb.tag) {
|
switch(xwb.tag) {
|
||||||
case 0: xwb.codec = PCM; break;
|
case 0: xwb.codec = PCM; break;
|
||||||
/* Table Tennis (v34): XMA1, Prey (v38): XMA2, v35/36/37: ? */
|
/* Table Tennis (v34): XMA1, Prey (v38): XMA2, v35/36/37: ? */
|
||||||
@ -246,7 +242,8 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
case 2: xwb.codec = MS_ADPCM; break;
|
case 2: xwb.codec = MS_ADPCM; break;
|
||||||
default: goto fail;
|
default: goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
switch(xwb.tag) {
|
switch(xwb.tag) {
|
||||||
case 0: xwb.codec = PCM; break;
|
case 0: xwb.codec = PCM; break;
|
||||||
case 1: xwb.codec = XMA2; break;
|
case 1: xwb.codec = XMA2; break;
|
||||||
@ -267,6 +264,26 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
xwb.num_samples = atrac3_bytes_to_samples(xwb.stream_size, xwb.block_align * xwb.channels);
|
xwb.num_samples = atrac3_bytes_to_samples(xwb.stream_size, xwb.block_align * xwb.channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Oddworld: Stranger's Wrath iOS/Android format hijack, with changed meanings */
|
||||||
|
if (xwb.codec == OGG) {
|
||||||
|
xwb.num_samples = xwb.stream_size / (2 * xwb.channels); /* uncompressed bytes */
|
||||||
|
xwb.stream_size = xwb.loop_end;
|
||||||
|
xwb.loop_start = 0;
|
||||||
|
xwb.loop_end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* test loop after the above fixes */
|
||||||
|
xwb.loop_flag = (xwb.loop_end > 0 || xwb.loop_end_sample > xwb.loop_start)
|
||||||
|
&& !(xwb.entry_flags & WAVEBANKENTRY_FLAGS_IGNORELOOP);
|
||||||
|
|
||||||
|
if (xwb.codec != OGG) {
|
||||||
|
/* for Oddworld OGG the data_size value is size of uncompressed bytes instead */
|
||||||
|
/* some BlazBlue Centralfiction songs have padding after data size (maybe wrong rip?) */
|
||||||
|
if (xwb.data_offset + xwb.data_size > get_streamfile_size(streamFile))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fix samples */
|
/* fix samples */
|
||||||
if (xwb.version <= XACT2_2_MAX && xwb.codec == PCM) {
|
if (xwb.version <= XACT2_2_MAX && xwb.codec == PCM) {
|
||||||
@ -435,7 +452,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ATRAC3: { /* Techland extension */
|
case ATRAC3: { /* Techland PS3 extension */
|
||||||
uint8_t buf[200];
|
uint8_t buf[200];
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
@ -452,6 +469,15 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
|||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OGG: { /* Oddworld: Strangers Wrath iOS/Android extension */
|
||||||
|
vgmstream->codec_data = init_ffmpeg_offset(streamFile, xwb.stream_offset, xwb.stream_size);
|
||||||
|
if ( !vgmstream->codec_data ) goto fail;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "formats.h"
|
|
||||||
#include "vgmstream.h"
|
#include "vgmstream.h"
|
||||||
#include "meta/meta.h"
|
#include "meta/meta.h"
|
||||||
#include "layout/layout.h"
|
#include "layout/layout.h"
|
||||||
@ -202,7 +201,6 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
|||||||
init_vgmstream_wii_smp,
|
init_vgmstream_wii_smp,
|
||||||
init_vgmstream_emff_ps2,
|
init_vgmstream_emff_ps2,
|
||||||
init_vgmstream_emff_ngc,
|
init_vgmstream_emff_ngc,
|
||||||
init_vgmstream_ss_stream,
|
|
||||||
init_vgmstream_thp,
|
init_vgmstream_thp,
|
||||||
init_vgmstream_wii_sts,
|
init_vgmstream_wii_sts,
|
||||||
init_vgmstream_ps2_p2bt,
|
init_vgmstream_ps2_p2bt,
|
||||||
|
@ -1147,6 +1147,7 @@ typedef struct {
|
|||||||
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
||||||
VGMSTREAM * init_vgmstream(const char * const filename);
|
VGMSTREAM * init_vgmstream(const char * const filename);
|
||||||
|
|
||||||
|
/* init with custom IO via streamfile */
|
||||||
VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile);
|
VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile);
|
||||||
|
|
||||||
/* reset a VGMSTREAM to start of stream */
|
/* reset a VGMSTREAM to start of stream */
|
||||||
@ -1169,6 +1170,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length);
|
|||||||
* stream. Compares files by absolute paths. */
|
* stream. Compares files by absolute paths. */
|
||||||
int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream);
|
int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
/* List of supported formats and elements in the list, for plugins that need to know. */
|
||||||
|
const char ** vgmstream_get_formats(size_t * size);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------*/
|
/* -------------------------------------------------------------------------*/
|
||||||
/* vgmstream "private" API */
|
/* vgmstream "private" API */
|
||||||
/* -------------------------------------------------------------------------*/
|
/* -------------------------------------------------------------------------*/
|
||||||
@ -1203,4 +1207,9 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream);
|
|||||||
* returns 0 on failure */
|
* returns 0 on failure */
|
||||||
int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset);
|
int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset);
|
||||||
|
|
||||||
|
/* get description info */
|
||||||
|
const char * get_vgmstream_coding_description(coding_t coding_type);
|
||||||
|
const char * get_vgmstream_layout_description(layout_t layout_type);
|
||||||
|
const char * get_vgmstream_meta_description(meta_t meta_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,8 +14,9 @@ REM #TODO: escape & ! % in file/folder names
|
|||||||
|
|
||||||
setlocal enableDelayedExpansion
|
setlocal enableDelayedExpansion
|
||||||
|
|
||||||
|
REM #-------------------------------------------------------------------------
|
||||||
REM #options
|
REM #options
|
||||||
|
REM #-------------------------------------------------------------------------
|
||||||
REM # -vo <exe> -vn <exe>: path to old/new exe
|
REM # -vo <exe> -vn <exe>: path to old/new exe
|
||||||
set OP_CMD_OLD=test_old.exe
|
set OP_CMD_OLD=test_old.exe
|
||||||
set OP_CMD_NEW=test.exe
|
set OP_CMD_NEW=test.exe
|
||||||
@ -27,6 +28,8 @@ REM # -nd: don't delete compared files
|
|||||||
set OP_NODELETE=
|
set OP_NODELETE=
|
||||||
REM # -nc: don't report correct files
|
REM # -nc: don't report correct files
|
||||||
set OP_NOCORRECT=
|
set OP_NOCORRECT=
|
||||||
|
REM # -p: performance test (decode with new exe and no comparison done)
|
||||||
|
set OP_PERFORMANCE=
|
||||||
|
|
||||||
|
|
||||||
REM # parse options
|
REM # parse options
|
||||||
@ -38,6 +41,7 @@ if "%~1"=="-f" set OP_SEARCH=%2
|
|||||||
if "%~1"=="-r" set OP_RECURSIVE=/s
|
if "%~1"=="-r" set OP_RECURSIVE=/s
|
||||||
if "%~1"=="-nd" set OP_NODELETE=true
|
if "%~1"=="-nd" set OP_NODELETE=true
|
||||||
if "%~1"=="-nc" set OP_NOCORRECT=true
|
if "%~1"=="-nc" set OP_NOCORRECT=true
|
||||||
|
if "%~1"=="-p" set OP_PERFORMANCE=true
|
||||||
shift
|
shift
|
||||||
goto set_options
|
goto set_options
|
||||||
:end_options
|
:end_options
|
||||||
@ -61,7 +65,8 @@ if %OP_SEARCH%=="" (
|
|||||||
)
|
)
|
||||||
|
|
||||||
REM # process start
|
REM # process start
|
||||||
echo VRTS: start @%time%
|
set TIME_START=%time%
|
||||||
|
echo VRTS: start @%TIME_START%
|
||||||
|
|
||||||
REM # search for files
|
REM # search for files
|
||||||
set CMD_DIR=dir /a:-d /b %OP_RECURSIVE% %OP_SEARCH%
|
set CMD_DIR=dir /a:-d /b %OP_RECURSIVE% %OP_SEARCH%
|
||||||
@ -70,18 +75,39 @@ set CMD_FIND=findstr /i /v "\.exe$ \.dll$ \.zip$ \.7z$ \.rar$ \.bat$ \.sh$ \.txt
|
|||||||
REM # process files
|
REM # process files
|
||||||
for /f "delims=" %%x in ('%CMD_DIR% ^| %CMD_FIND%') do (
|
for /f "delims=" %%x in ('%CMD_DIR% ^| %CMD_FIND%') do (
|
||||||
set CMD_FILE=%%x
|
set CMD_FILE=%%x
|
||||||
call :process_file "!CMD_FILE!"
|
|
||||||
|
if "%OP_PERFORMANCE%" == "" (
|
||||||
|
call :process_file "!CMD_FILE!"
|
||||||
|
) else (
|
||||||
|
call :performance_file "!CMD_FILE!"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
REM # find time elapsed
|
||||||
|
set TIME_END=%time%
|
||||||
|
for /F "tokens=1-4 delims=:.," %%a in ("%TIME_START%") do (
|
||||||
|
set /A "TIME_START_S=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
|
||||||
|
)
|
||||||
|
for /F "tokens=1-4 delims=:.," %%a in ("%TIME_END%") do (
|
||||||
|
set /A "TIME_END_S=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
|
||||||
|
)
|
||||||
|
set /A TIME_ELAPSED_S=(TIME_END_S-TIME_START_S)/100
|
||||||
|
set /A TIME_ELAPSED_C=(TIME_END_S-TIME_START_S)%%100
|
||||||
|
|
||||||
|
|
||||||
REM # process end (ok)
|
REM # process end (ok)
|
||||||
goto done
|
echo VRTS: done @%TIME_END% (%TIME_ELAPSED_S%,%TIME_ELAPSED_C%s)
|
||||||
|
|
||||||
|
goto exit
|
||||||
|
|
||||||
|
|
||||||
|
REM # ########################################################################
|
||||||
REM # test a single file
|
REM # test a single file
|
||||||
|
REM # ########################################################################
|
||||||
:process_file outer
|
:process_file outer
|
||||||
REM # ignore files starting with dot (no filename)
|
REM # ignore files starting with dot (no filename)
|
||||||
set CMD_SHORTNAME=%~n1
|
set CMD_SHORTNAME=%~n1
|
||||||
if "%CMD_SHORTNAME%" == "" goto continue
|
if "%CMD_SHORTNAME%" == "" goto process_file_continue
|
||||||
|
|
||||||
REM # get file
|
REM # get file
|
||||||
set CMD_FILE=%1
|
set CMD_FILE=%1
|
||||||
@ -105,7 +131,7 @@ REM # test a single file
|
|||||||
REM echo VRTS: nothing created for file %CMD_FILE%
|
REM echo VRTS: nothing created for file %CMD_FILE%
|
||||||
if exist "%TXT_NEW%" del /a:a "%TXT_NEW%"
|
if exist "%TXT_NEW%" del /a:a "%TXT_NEW%"
|
||||||
if exist "%TXT_OLD%" del /a:a "%TXT_OLD%"
|
if exist "%TXT_OLD%" del /a:a "%TXT_OLD%"
|
||||||
goto continue
|
goto process_file_continue
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -146,12 +172,42 @@ REM # test a single file
|
|||||||
if exist "%TXT_NEW%" del /a:a "%TXT_NEW%"
|
if exist "%TXT_NEW%" del /a:a "%TXT_NEW%"
|
||||||
)
|
)
|
||||||
|
|
||||||
:continue
|
:process_file_continue
|
||||||
exit /B
|
exit /B
|
||||||
REM :process_file end, continue from last call
|
REM :process_file end, continue from last call
|
||||||
|
|
||||||
|
|
||||||
|
REM # ########################################################################
|
||||||
|
REM # decode only (no comparisons done), for performance testing
|
||||||
|
REM # ########################################################################
|
||||||
|
:performance_file
|
||||||
|
REM # ignore files starting with dot (no filename)
|
||||||
|
set CMD_SHORTNAME=%~n1
|
||||||
|
if "%CMD_SHORTNAME%" == "" goto performance_file_continue
|
||||||
|
|
||||||
|
REM # get file
|
||||||
|
set CMD_FILE=%1
|
||||||
|
set CMD_FILE=%CMD_FILE:"=%
|
||||||
|
REM echo VTRS: file %CMD_FILE%
|
||||||
|
|
||||||
|
REM # new temp output
|
||||||
|
set WAV_NEW=%CMD_FILE%.test.wav
|
||||||
|
set CMD_VGM_NEW="%OP_CMD_NEW%" -o "%WAV_NEW%" "%CMD_FILE%"
|
||||||
|
%CMD_VGM_NEW% 1> nul 2>&1 & REM || goto error
|
||||||
|
|
||||||
|
call :echo_color %C_O% "%CMD_FILE%" "done"
|
||||||
|
|
||||||
|
REM # ignore output
|
||||||
|
if exist "%WAV_NEW%" del /a:a "%WAV_NEW%"
|
||||||
|
|
||||||
|
:performance_file_continue
|
||||||
|
exit /B
|
||||||
|
REM :performance_file end, continue from last call
|
||||||
|
|
||||||
|
|
||||||
|
REM # ########################################################################
|
||||||
REM # hack to get colored output in Windows CMD using findstr + temp file
|
REM # hack to get colored output in Windows CMD using findstr + temp file
|
||||||
|
REM # ########################################################################
|
||||||
:echo_color
|
:echo_color
|
||||||
set TEMP_FILE=%2-result
|
set TEMP_FILE=%2-result
|
||||||
set TEMP_FILE=%TEMP_FILE:"=%
|
set TEMP_FILE=%TEMP_FILE:"=%
|
||||||
@ -165,14 +221,10 @@ exit /B
|
|||||||
REM :echo_color end, continue from last call
|
REM :echo_color end, continue from last call
|
||||||
|
|
||||||
|
|
||||||
:done
|
REM # ########################################################################
|
||||||
echo VRTS: done @%time%
|
|
||||||
goto exit
|
|
||||||
|
|
||||||
|
|
||||||
:error
|
:error
|
||||||
echo VRTS: error @%time%
|
echo VRTS: error
|
||||||
goto exit
|
goto exit
|
||||||
|
|
||||||
|
|
||||||
:exit
|
:exit
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
/* Normally Winamp opens unicode files by their DOS 8.3 name. #define this to use wchar_t filenames,
|
/* Normally Winamp opens unicode files by their DOS 8.3 name. #define this to use wchar_t filenames,
|
||||||
* which must be opened with _wfopen in a WINAMP_STREAMFILE (needed for dual files like .pos).
|
* which must be opened with _wfopen in a WINAMP_STREAMFILE (needed for dual files like .pos).
|
||||||
* Only for Winamp paths, other parts would need #define UNICODE for Windows. */
|
* Only for Winamp paths, other parts would need #define UNICODE for Windows. */
|
||||||
//#define UNICODE_INPUT_PLUGIN
|
#ifdef VGM_WINAMP_UNICODE
|
||||||
|
#define UNICODE_INPUT_PLUGIN
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define _CRT_SECURE_NO_DEPRECATE
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
@ -19,7 +20,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "../src/formats.h"
|
|
||||||
#include "../src/vgmstream.h"
|
#include "../src/vgmstream.h"
|
||||||
#include "in2.h"
|
#include "in2.h"
|
||||||
#include "wa_ipc.h"
|
#include "wa_ipc.h"
|
||||||
@ -68,7 +68,7 @@ In_Module input_module;
|
|||||||
DWORD WINAPI __stdcall decode(void *arg);
|
DWORD WINAPI __stdcall decode(void *arg);
|
||||||
|
|
||||||
/* Winamp Play extension list, needed to accept/play and associate extensions in Windows */
|
/* Winamp Play extension list, needed to accept/play and associate extensions in Windows */
|
||||||
#define EXTENSION_LIST_SIZE VGM_EXTENSION_LIST_CHAR_SIZE * 6
|
#define EXTENSION_LIST_SIZE (0x2000 * 6)
|
||||||
#define EXT_BUFFER_SIZE 200
|
#define EXT_BUFFER_SIZE 200
|
||||||
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
|
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
|
||||||
|
|
||||||
@ -463,14 +463,13 @@ static void add_extension(int length, char * dst, const char * ext) {
|
|||||||
* Each extension must be in this format: "extension\0Description\0" */
|
* Each extension must be in this format: "extension\0Description\0" */
|
||||||
static void build_extension_list() {
|
static void build_extension_list() {
|
||||||
const char ** ext_list;
|
const char ** ext_list;
|
||||||
int ext_list_len;
|
size_t ext_list_len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
working_extension_list[0]='\0';
|
working_extension_list[0]='\0';
|
||||||
working_extension_list[1]='\0';
|
working_extension_list[1]='\0';
|
||||||
|
|
||||||
ext_list = vgmstream_get_formats();
|
ext_list = vgmstream_get_formats(&ext_list_len);
|
||||||
ext_list_len = vgmstream_get_formats_length();
|
|
||||||
|
|
||||||
for (i=0; i < ext_list_len; i++) {
|
for (i=0; i < ext_list_len; i++) {
|
||||||
add_extension(EXTENSION_LIST_SIZE, working_extension_list, ext_list[i]);
|
add_extension(EXTENSION_LIST_SIZE, working_extension_list, ext_list[i]);
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "../src/formats.h"
|
|
||||||
#include "../src/vgmstream.h"
|
#include "../src/vgmstream.h"
|
||||||
#include "xmpin.h"
|
#include "xmpin.h"
|
||||||
|
|
||||||
@ -27,7 +26,7 @@
|
|||||||
|
|
||||||
/* XMPlay extension list, only needed to associate extensions in Windows */
|
/* XMPlay extension list, only needed to associate extensions in Windows */
|
||||||
/* todo: as of v3.8.2.17, any more than ~1000 will crash XMplay's file list screen (but not using the non-native Winamp plugin...) */
|
/* todo: as of v3.8.2.17, any more than ~1000 will crash XMplay's file list screen (but not using the non-native Winamp plugin...) */
|
||||||
#define EXTENSION_LIST_SIZE 1000 /*VGM_EXTENSION_LIST_CHAR_SIZE * 2*/
|
#define EXTENSION_LIST_SIZE 1000 /* (0x2000 * 2) */
|
||||||
#define XMPLAY_MAX_PATH 32768
|
#define XMPLAY_MAX_PATH 32768
|
||||||
|
|
||||||
/* XMPlay function library */
|
/* XMPlay function library */
|
||||||
@ -205,13 +204,12 @@ static int add_extension(int length, char * dst, const char * ext) {
|
|||||||
* Extensions must be in this format: "Description\0extension1/.../extensionN" */
|
* Extensions must be in this format: "Description\0extension1/.../extensionN" */
|
||||||
static void build_extension_list() {
|
static void build_extension_list() {
|
||||||
const char ** ext_list;
|
const char ** ext_list;
|
||||||
int ext_list_len;
|
size_t ext_list_len;
|
||||||
int i, written;
|
int i, written;
|
||||||
|
|
||||||
written = sprintf(working_extension_list, "%s%c", "vgmstream files",'\0');
|
written = sprintf(working_extension_list, "%s%c", "vgmstream files",'\0');
|
||||||
|
|
||||||
ext_list = vgmstream_get_formats();
|
ext_list = vgmstream_get_formats(&ext_list_len);
|
||||||
ext_list_len = vgmstream_get_formats_length();
|
|
||||||
|
|
||||||
for (i=0; i < ext_list_len; i++) {
|
for (i=0; i < ext_list_len; i++) {
|
||||||
written += add_extension(EXTENSION_LIST_SIZE-written, working_extension_list + written, ext_list[i]);
|
written += add_extension(EXTENSION_LIST_SIZE-written, working_extension_list + written, ext_list[i]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user