mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 07:44:43 +01:00
Merge pull request #142 from bnnm/ima-dvi-xa-pcm-eacs
IMA, DVI, XA, PCM, EACS
This commit is contained in:
commit
bf41d53690
19
BUILD.md
19
BUILD.md
@ -149,22 +149,25 @@ C is restricted to features VS2010 can understand. This mainly means means decla
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Overview
|
### Overview
|
||||||
vgmstream works by parsing a music stream header (*meta/*), reading/demuxing data or looping (*layout/*) and decoding the compressed data into listenable PCM samples (*coding/*).
|
vgmstream works by parsing a music stream header (*meta/*), preparing/demuxing data (*layout/*) and decoding the compressed data into listenable PCM samples (*coding/*).
|
||||||
|
|
||||||
Very simplified it goes like this:
|
Very simplified it goes like this:
|
||||||
- player (test.exe, plugin, etc) inits the stream *[main]*
|
- player (test.exe, plugin, etc) opens a file stream *[plugin's main/decode]*
|
||||||
- init tries all parsers (metas) until one works *[init_vgmstream]*
|
- init tries all parsers (metas) until one works *[init_vgmstream]*
|
||||||
- parser reads header (channels, sample rate, loop points) and set ups a VGMSTREAM struct + layout/coding, if the format is correct *[init_vgmstream_(format-name)]*
|
- parser reads header (channels, sample rate, loop points) and set ups a VGMSTREAM struct + layout/coding, if the format is correct *[init_vgmstream_(format-name)]*
|
||||||
- player gets total_samples to play, based on the number of loops and other settings *[get_vgmstream_play_samples]*
|
- player gets total_samples to play, based on the number of loops and other settings *[get_vgmstream_play_samples]*
|
||||||
- player asks to fill a small sample buffer *[render_vgmstream]*
|
- player asks to fill a small sample buffer *[render_vgmstream]*
|
||||||
- layout prepares bytes to read from the stream *[render_vgmstream_(layout)]*
|
- layout prepares byte offsets to read from the stream *[render_vgmstream_(layout)]*
|
||||||
- decoder decodes bytes into PCM samples *[decode_vgmstream_(coding)]*
|
- decoder reads and decodes bytes into PCM samples *[decode_vgmstream_(coding)]*
|
||||||
- player plays those samples, asks to fill sample buffer, repeats (until total_samples)
|
- player plays those samples, asks to fill sample buffer again, repeats (until total_samples)
|
||||||
- layout moves back to loop_start when loop_end is reached *[vgmstream_do_loop]*
|
- layout moves offsets back to loop_start when loop_end is reached *[vgmstream_do_loop]*
|
||||||
|
- close the VGMSTREAM once the stream is finished
|
||||||
|
|
||||||
|
The VGMSTREAM struct created during holds the stream's parameters and decoder state (such as file streams, or offsets per channel).
|
||||||
|
|
||||||
### 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 init_vgmstream_(format-name) 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 tests the extension and header id, and reads all needed info from the stream header and inits the VGMSTREAM
|
||||||
- *src/meta/meta.h*: define parser's init
|
- *src/meta/meta.h*: define parser's init
|
||||||
- *src/vgmstream.h*: define meta description in the meta_t list
|
- *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
|
||||||
@ -173,6 +176,8 @@ For new simple formats, assuming existing layout/coding:
|
|||||||
- *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*
|
||||||
|
|
||||||
|
The new meta is usually named after the format's header id or main extension, possibly with prepended platform. Each file should parse one format (regardless of accepted extensions or decoders used) for consistency, but variations can be found as code evolved. Differents formats can use the same extension, this is not a problem as long as the header id or some other validation tells them apart. If the format is headerless and the extension isn't unique enough it may need a generic GENH/TXTH header instead of direct support.
|
||||||
|
|
||||||
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).
|
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.
|
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.
|
||||||
|
10
README.md
10
README.md
@ -224,15 +224,15 @@ This list is not complete and many other files are supported.
|
|||||||
- .spsd
|
- .spsd
|
||||||
- IMA ADPCM:
|
- IMA ADPCM:
|
||||||
- .bar (IMA ADPCM)
|
- .bar (IMA ADPCM)
|
||||||
- .dvi (DVI IMA ADPCM)
|
- .pcm/dvi (DVI IMA ADPCM)
|
||||||
- .hwas (IMA ADPCM)
|
- .hwas (IMA ADPCM)
|
||||||
- .idvi (DVI IMA ADPCM)
|
- .dvi/idvi (DVI IMA ADPCM)
|
||||||
- .ivaud (IMA ADPCM)
|
- .ivaud (IMA ADPCM)
|
||||||
- .myspd (IMA ADPCM)
|
- .myspd (IMA ADPCM)
|
||||||
- .strm (IMA ADPCM)
|
- .strm (IMA ADPCM)
|
||||||
- multi:
|
- multi:
|
||||||
- .aifc (SDX2 DPCM, DVI IMA ADPCM)
|
- .aifc (SDX2 DPCM, DVI IMA ADPCM)
|
||||||
- .asf/as4 (8/16 bit PCM, EACS IMA ADPCM)
|
- .asf/as4 (8/16 bit PCM, DVI IMA ADPCM)
|
||||||
- .ast (GC AFC ADPCM, 16 bit PCM)
|
- .ast (GC AFC ADPCM, 16 bit PCM)
|
||||||
- .aud (IMA ADPCM, WS DPCM)
|
- .aud (IMA ADPCM, WS DPCM)
|
||||||
- .aus (PSX ADPCM, Xbox IMA ADPCM)
|
- .aus (PSX ADPCM, Xbox IMA ADPCM)
|
||||||
@ -256,7 +256,7 @@ This list is not complete and many other files are supported.
|
|||||||
- .seg (Xbox IMA ADPCM, PS2 ADPCM)
|
- .seg (Xbox IMA ADPCM, PS2 ADPCM)
|
||||||
- .sng/asf/str/eam/aud (8/16 bit PCM, EA-XA ADPCM, PSX ADPCM, GC DSP ADPCM, XBOX IMA ADPCM, MPEG audio, EALayer3)
|
- .sng/asf/str/eam/aud (8/16 bit PCM, EA-XA ADPCM, PSX ADPCM, GC DSP ADPCM, XBOX IMA ADPCM, MPEG audio, EALayer3)
|
||||||
- .strm (NDS IMA ADPCM, 8/16 bit PCM)
|
- .strm (NDS IMA ADPCM, 8/16 bit PCM)
|
||||||
- .ss7 (EACS IMA ADPCM, IMA ADPCM)
|
- .sb0..7 (Ubi IMA ADPCM, GC DSP ADPCM, PSX ADPCM, Xbox IMA ADPCM, ATRAC3)
|
||||||
- .swav (NDS IMA ADPCM, 8/16 bit PCM)
|
- .swav (NDS IMA ADPCM, 8/16 bit PCM)
|
||||||
- .xwb (PCM, Xbox IMA ADPCM, MS ADPCM, XMA, XWMA, ATRAC3)
|
- .xwb (PCM, Xbox IMA ADPCM, MS ADPCM, XMA, XWMA, ATRAC3)
|
||||||
- .xwb+xwh (PCM, PSX ADPCM, ATRAC3)
|
- .xwb+xwh (PCM, PSX ADPCM, ATRAC3)
|
||||||
@ -279,7 +279,7 @@ This list is not complete and many other files are supported.
|
|||||||
- .caf (Apple IMA4 ADPCM, others)
|
- .caf (Apple IMA4 ADPCM, others)
|
||||||
- .de2 (MS ADPCM)
|
- .de2 (MS ADPCM)
|
||||||
- .hca (CRI High Compression Audio)
|
- .hca (CRI High Compression Audio)
|
||||||
- .kcey (EACS IMA ADPCM)
|
- .pcm/kcey (DVI IMA ADPCM)
|
||||||
- .lsf (LSF ADPCM)
|
- .lsf (LSF ADPCM)
|
||||||
- .mc3 (Paradigm MC3 ADPCM)
|
- .mc3 (Paradigm MC3 ADPCM)
|
||||||
- .mp4/lmp4 (AAC)
|
- .mp4/lmp4 (AAC)
|
||||||
|
@ -17,17 +17,17 @@ libg719_decode.a: libg719_decode.def
|
|||||||
libat3plusdecoder.a: at3plusdecoder.def
|
libat3plusdecoder.a: at3plusdecoder.def
|
||||||
$(DLLTOOL) -d at3plusdecoder.def -l libat3plusdecoder.a
|
$(DLLTOOL) -d at3plusdecoder.def -l libat3plusdecoder.a
|
||||||
|
|
||||||
libavcodec.a: avcodec-vgmstream-57.dll avcodec-vgmstream-57.def
|
libavcodec.a: avcodec-vgmstream-58.dll avcodec-vgmstream-58.def
|
||||||
$(DLLTOOL) -D avcodec-vgmstream-57.dll -d avcodec-vgmstream-57.def -l libavcodec.a
|
$(DLLTOOL) -D avcodec-vgmstream-58.dll -d avcodec-vgmstream-58.def -l libavcodec.a
|
||||||
|
|
||||||
libavformat.a: avformat-vgmstream-57.dll avformat-vgmstream-57.def
|
libavformat.a: avformat-vgmstream-58.dll avformat-vgmstream-58.def
|
||||||
$(DLLTOOL) -D avformat-vgmstream-57.dll -d avformat-vgmstream-57.def -l libavformat.a
|
$(DLLTOOL) -D avformat-vgmstream-58.dll -d avformat-vgmstream-58.def -l libavformat.a
|
||||||
|
|
||||||
libavutil.a: avutil-vgmstream-55.dll avutil-vgmstream-55.def
|
libavutil.a: avutil-vgmstream-56.dll avutil-vgmstream-56.def
|
||||||
$(DLLTOOL) -D avutil-vgmstream-55.dll -d avutil-vgmstream-55.def -l libavutil.a
|
$(DLLTOOL) -D avutil-vgmstream-56.dll -d avutil-vgmstream-56.def -l libavutil.a
|
||||||
|
|
||||||
libswresample.a: swresample-vgmstream-2.dll swresample-vgmstream-2.def
|
libswresample.a: swresample-vgmstream-3.dll swresample-vgmstream-3.def
|
||||||
$(DLLTOOL) -D swresample-vgmstream-2.dll -d swresample-vgmstream-2.def -l libswresample.a
|
$(DLLTOOL) -D swresample-vgmstream-3.dll -d swresample-vgmstream-3.def -l libswresample.a
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f libvorbis.a libmpg123-0.a libg7221_decode.a libg719_decode.a libat3plusdecoder.a libavcodec.a libavformat.a libavutil.a libswresample.a
|
rm -f libvorbis.a libmpg123-0.a libg7221_decode.a libg719_decode.a libat3plusdecoder.a libavcodec.a libavformat.a libavutil.a libswresample.a
|
||||||
|
@ -19,10 +19,9 @@ void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
|||||||
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_xbox_ima_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_xbox_ima_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
void decode_eacs_ima(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
|
||||||
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
void decode_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_standard_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo, int is_high_first);
|
||||||
|
void decode_3ds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
@ -80,7 +79,8 @@ size_t ps_bytes_to_samples(size_t bytes, int channels);
|
|||||||
|
|
||||||
/* xa_decoder */
|
/* xa_decoder */
|
||||||
void decode_xa(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_xa(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
void init_get_high_nibble(VGMSTREAM * vgmstream);
|
void xa_init_get_high_nibble(VGMSTREAM * vgmstream);
|
||||||
|
size_t xa_bytes_to_samples(size_t bytes, int channels, int is_blocked);
|
||||||
|
|
||||||
/* ea_xa_decoder */
|
/* ea_xa_decoder */
|
||||||
void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
|
@ -41,11 +41,10 @@ static const int IMA_IndexTable[16] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Alt IMA */
|
/* 3DS IMA (Mario Golf, Mario Tennis; maybe other Camelot games) */
|
||||||
static void ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
static void n3ds_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||||
int sample_nibble, sample_decoded, step, delta;
|
int sample_nibble, sample_decoded, step, delta;
|
||||||
|
|
||||||
//"original" ima nibble expansion
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
|
|
||||||
@ -64,7 +63,7 @@ static void ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int
|
|||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Microsoft's IMA (most common) */
|
/* Standard IMA (most common) */
|
||||||
static void ms_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
static void ms_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||||
int sample_nibble, sample_decoded, step, delta;
|
int sample_nibble, sample_decoded, step, delta;
|
||||||
|
|
||||||
@ -86,7 +85,7 @@ static void ms_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, i
|
|||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apple's MS IMA variation. Exactly the same except it uses 16b history (probably more sensitive to overflow/sign extend) */
|
/* Apple's IMA variation. Exactly the same except it uses 16b history (probably more sensitive to overflow/sign extend) */
|
||||||
static void ms_ima_expand_nibble_16(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int16_t * hist1, int32_t * step_index) {
|
static void ms_ima_expand_nibble_16(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int16_t * hist1, int32_t * step_index) {
|
||||||
int sample_nibble, sample_decoded, step, delta;
|
int sample_nibble, sample_decoded, step, delta;
|
||||||
|
|
||||||
@ -169,6 +168,7 @@ static void ubi_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample_decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *** */
|
||||||
|
|
||||||
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||||
int i, sample_count;
|
int i, sample_count;
|
||||||
@ -426,19 +426,29 @@ void decode_xbox_ima_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channel
|
|||||||
stream->adpcm_step_index = step_index;
|
stream->adpcm_step_index = step_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
/* Standard DVI/IMA ADPCM (as in, ADPCM recommended by the IMA using Intel/DVI's implementation).
|
||||||
int i, sample_count;
|
* Configurable: stereo or mono/interleave nibbles, and high or low nibble first.
|
||||||
|
* For vgmstream, low nibble is called "IMA ADPCM" and high nibble is "DVI IMA ADPCM" (same thing though). */
|
||||||
|
void decode_standard_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo, int is_high_first) {
|
||||||
|
int i, sample_count = 0;
|
||||||
|
|
||||||
int32_t hist1 = stream->adpcm_history1_32;
|
int32_t hist1 = stream->adpcm_history1_32;
|
||||||
int step_index = stream->adpcm_step_index;
|
int step_index = stream->adpcm_step_index;
|
||||||
|
|
||||||
//external interleave
|
/* external interleave */
|
||||||
|
|
||||||
//no header
|
/* no header (external setup), pre-clamp for wrong values */
|
||||||
|
if (step_index < 0) step_index=0;
|
||||||
|
if (step_index > 88) step_index=88;
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
/* decode nibbles */
|
||||||
off_t byte_offset = stream->offset + i/2;
|
for (i = first_sample; i < first_sample + samples_to_do; i++, sample_count += channelspacing) {
|
||||||
int nibble_shift = (i&1?0:4); //high nibble first (old-style DVI)
|
off_t byte_offset = is_stereo ?
|
||||||
|
stream->offset + i : /* stereo: one nibble per channel */
|
||||||
|
stream->offset + i/2; /* mono: consecutive nibbles */
|
||||||
|
int nibble_shift = is_high_first ?
|
||||||
|
is_stereo ? (!(channel&1) ? 4:0) : (!(i&1) ? 4:0) : /* even = high, odd = low */
|
||||||
|
is_stereo ? (!(channel&1) ? 0:4) : (!(i&1) ? 0:4); /* even = low, odd = high */
|
||||||
|
|
||||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||||
outbuf[sample_count] = (short)(hist1);
|
outbuf[sample_count] = (short)(hist1);
|
||||||
@ -448,35 +458,7 @@ void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
|||||||
stream->adpcm_step_index = step_index;
|
stream->adpcm_step_index = step_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* basically DVI stereo (high=L + low=R nibbles) and DVI mono (high=L, low=L) all-in-one, can be simplified/removed */
|
void decode_3ds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||||
void decode_eacs_ima(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
|
||||||
VGMSTREAMCHANNEL * stream = &(vgmstream->ch[channel]);//todo pass externally for consistency
|
|
||||||
int i, sample_count;
|
|
||||||
|
|
||||||
int32_t hist1 = stream->adpcm_history1_32;
|
|
||||||
int step_index = stream->adpcm_step_index;
|
|
||||||
|
|
||||||
//external interleave
|
|
||||||
|
|
||||||
//no header
|
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
||||||
off_t byte_offset = channelspacing == 1 ?
|
|
||||||
stream->offset + i/2 : /* mono mode */
|
|
||||||
stream->offset + i; /* stereo mode */
|
|
||||||
int nibble_shift = channelspacing == 1 ?
|
|
||||||
(!(i%2) ? 4:0) : /* mono mode (high first) */
|
|
||||||
(channel==0 ? 4:0); /* stereo mode (high=L,low=R) */
|
|
||||||
|
|
||||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
|
||||||
outbuf[sample_count] = (short)(hist1);
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->adpcm_history1_32 = hist1;
|
|
||||||
stream->adpcm_step_index = step_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decode_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
||||||
int i, sample_count;
|
int i, sample_count;
|
||||||
|
|
||||||
int32_t hist1 = stream->adpcm_history1_32;
|
int32_t hist1 = stream->adpcm_history1_32;
|
||||||
@ -490,7 +472,7 @@ void decode_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
|||||||
off_t byte_offset = stream->offset + i/2;
|
off_t byte_offset = stream->offset + i/2;
|
||||||
int nibble_shift = (i&1?4:0); //low nibble order
|
int nibble_shift = (i&1?4:0); //low nibble order
|
||||||
|
|
||||||
ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
n3ds_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||||
outbuf[sample_count] = (short)(hist1);
|
outbuf[sample_count] = (short)(hist1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ static int CLAMP(int value, int Minim, int Maxim)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_get_high_nibble(VGMSTREAM *vgmstream) {
|
void xa_init_get_high_nibble(VGMSTREAM *vgmstream) {
|
||||||
vgmstream->get_high_nibble=1;
|
vgmstream->xa_get_high_nibble=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decode_xa(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
void decode_xa(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||||
@ -41,18 +41,18 @@ void decode_xa(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32
|
|||||||
|
|
||||||
first_sample = first_sample % 28;
|
first_sample = first_sample % 28;
|
||||||
|
|
||||||
vgmstream->get_high_nibble=!vgmstream->get_high_nibble;
|
vgmstream->xa_get_high_nibble=!vgmstream->xa_get_high_nibble;
|
||||||
|
|
||||||
if((first_sample) && (channelspacing==1))
|
if((first_sample) && (channelspacing==1))
|
||||||
vgmstream->get_high_nibble=!vgmstream->get_high_nibble;
|
vgmstream->xa_get_high_nibble=!vgmstream->xa_get_high_nibble;
|
||||||
|
|
||||||
predict_nr = read_8bit(stream->offset+HeadTable[framesin]+vgmstream->get_high_nibble,stream->streamfile) >> 4;
|
predict_nr = read_8bit(stream->offset+HeadTable[framesin]+vgmstream->xa_get_high_nibble,stream->streamfile) >> 4;
|
||||||
shift_factor = read_8bit(stream->offset+HeadTable[framesin]+vgmstream->get_high_nibble,stream->streamfile) & 0xf;
|
shift_factor = read_8bit(stream->offset+HeadTable[framesin]+vgmstream->xa_get_high_nibble,stream->streamfile) & 0xf;
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||||
short sample_byte = (short)read_8bit(stream->offset+16+framesin+(i*4),stream->streamfile);
|
short sample_byte = (short)read_8bit(stream->offset+16+framesin+(i*4),stream->streamfile);
|
||||||
|
|
||||||
scale = ((vgmstream->get_high_nibble ?
|
scale = ((vgmstream->xa_get_high_nibble ?
|
||||||
sample_byte >> 4 :
|
sample_byte >> 4 :
|
||||||
sample_byte & 0x0f)<<12);
|
sample_byte & 0x0f)<<12);
|
||||||
|
|
||||||
@ -70,3 +70,13 @@ void decode_xa(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32
|
|||||||
stream->adpcm_history1_32=hist1;
|
stream->adpcm_history1_32=hist1;
|
||||||
stream->adpcm_history2_32=hist2;
|
stream->adpcm_history2_32=hist2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t xa_bytes_to_samples(size_t bytes, int channels, int is_blocked) {
|
||||||
|
if (is_blocked) {
|
||||||
|
//todo with -0x10 misses the last sector, not sure if bug or feature
|
||||||
|
return ((bytes - 0x10) / 0x930) * (0x900 - 18*0x10) * 2 / channels;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ((bytes / 0x80)*0xE0) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
103
src/formats.c
103
src/formats.c
@ -133,7 +133,7 @@ static const char* extension_list[] = {
|
|||||||
"iab",
|
"iab",
|
||||||
"iadp",
|
"iadp",
|
||||||
"idsp",
|
"idsp",
|
||||||
"idvi",
|
"idvi", //fake extension (to be removed)
|
||||||
"ikm",
|
"ikm",
|
||||||
"ild",
|
"ild",
|
||||||
"int",
|
"int",
|
||||||
@ -148,7 +148,7 @@ static const char* extension_list[] = {
|
|||||||
"jstm",
|
"jstm",
|
||||||
|
|
||||||
"kces",
|
"kces",
|
||||||
"kcey",
|
"kcey", //fake extension (to be removed)
|
||||||
"khv",
|
"khv",
|
||||||
"kovs",
|
"kovs",
|
||||||
"kraw",
|
"kraw",
|
||||||
@ -401,51 +401,53 @@ static const coding_info coding_info_list[] = {
|
|||||||
{coding_PCM16LE, "Little Endian 16-bit PCM"},
|
{coding_PCM16LE, "Little Endian 16-bit PCM"},
|
||||||
{coding_PCM16LE_XOR_int, "Little Endian 16-bit PCM with 2 byte interleave and XOR obfuscation"},
|
{coding_PCM16LE_XOR_int, "Little Endian 16-bit PCM with 2 byte interleave and XOR obfuscation"},
|
||||||
{coding_PCM16BE, "Big Endian 16-bit PCM"},
|
{coding_PCM16BE, "Big Endian 16-bit PCM"},
|
||||||
{coding_PCM16_int, "16-bit PCM with 2 byte interleave"},
|
{coding_PCM16_int, "16-bit PCM with 2 byte interleave (block)"},
|
||||||
{coding_PCM8, "8-bit PCM"},
|
{coding_PCM8, "8-bit PCM"},
|
||||||
|
{coding_PCM8_int, "8-bit PCM with 1 byte interleave (block)"},
|
||||||
{coding_PCM8_U, "8-bit unsigned PCM"},
|
{coding_PCM8_U, "8-bit unsigned PCM"},
|
||||||
{coding_PCM8_U_int, "8-bit unsigned PCM with 1 byte interleave"},
|
{coding_PCM8_U_int, "8-bit unsigned PCM with 1 byte interleave (block)"},
|
||||||
{coding_PCM8_int, "8-bit PCM with 1 byte interleave"},
|
{coding_PCM8_SB_int, "8-bit PCM with sign bit, 1 byte interleave (block)"},
|
||||||
{coding_PCM8_SB_int, "8-bit PCM with sign bit, 1 byte interleave"},
|
|
||||||
{coding_ULAW, "8-bit u-Law"},
|
{coding_ULAW, "8-bit u-Law"},
|
||||||
{coding_ALAW, "8-bit a-Law"},
|
{coding_ALAW, "8-bit a-Law"},
|
||||||
{coding_PCMFLOAT, "32-bit float PCM"},
|
{coding_PCMFLOAT, "32-bit float PCM"},
|
||||||
|
|
||||||
{coding_CRI_ADX, "CRI ADX 4-bit ADPCM"},
|
{coding_CRI_ADX, "CRI ADX 4-bit ADPCM"},
|
||||||
{coding_CRI_ADX_exp, "CRI ADX 4-bit ADPCM with exponential scale"},
|
{coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM (fixed coefficients)"},
|
||||||
{coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM with fixed coefficients"},
|
{coding_CRI_ADX_exp, "CRI ADX 4-bit ADPCM (exponential scale)"},
|
||||||
{coding_CRI_ADX_enc_8, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
|
{coding_CRI_ADX_enc_8, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
|
||||||
{coding_CRI_ADX_enc_9, "CRI ADX 4-bit ADPCM (type 9 encryption)"},
|
{coding_CRI_ADX_enc_9, "CRI ADX 4-bit ADPCM (type 9 encryption)"},
|
||||||
|
|
||||||
{coding_NGC_DSP, "Nintendo DSP 4-bit ADPCM"},
|
{coding_NGC_DSP, "Nintendo DSP 4-bit ADPCM"},
|
||||||
{coding_NGC_DTK, "Nintendo DTK 4-bit ADPCM"},
|
{coding_NGC_DTK, "Nintendo DTK 4-bit ADPCM"},
|
||||||
{coding_NGC_AFC, "Nintendo AFC 4-bit ADPCM"},
|
{coding_NGC_AFC, "Nintendo AFC 4-bit ADPCM"},
|
||||||
{coding_CRI_HCA, "CRI HCA"},
|
|
||||||
{coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"},
|
|
||||||
{coding_DAT4_IMA, "Eurocom DAT4 4-bit IMA ADPCM"},
|
|
||||||
{coding_G721, "CCITT G.721 4-bit ADPCM"},
|
{coding_G721, "CCITT G.721 4-bit ADPCM"},
|
||||||
|
|
||||||
|
{coding_XA, "CD-ROM XA 4-bit ADPCM"},
|
||||||
{coding_PSX, "Playstation 4-bit ADPCM"},
|
{coding_PSX, "Playstation 4-bit ADPCM"},
|
||||||
{coding_PSX_badflags, "Playstation 4-bit ADPCM (bad flags)"},
|
{coding_PSX_badflags, "Playstation 4-bit ADPCM (bad flags)"},
|
||||||
{coding_PSX_bmdx, "Playstation 4-bit ADPCM (BMDX encryption)"},
|
{coding_PSX_bmdx, "Playstation 4-bit ADPCM (BMDX encryption)"},
|
||||||
{coding_PSX_cfg, "Playstation 4-bit ADPCM (configurable)"},
|
{coding_PSX_cfg, "Playstation 4-bit ADPCM (configurable)"},
|
||||||
{coding_HEVAG, "Playstation Vita HEVAG 4-bit ADPCM"},
|
{coding_HEVAG, "Playstation Vita HEVAG 4-bit ADPCM"},
|
||||||
{coding_XA, "CD-ROM XA 4-bit ADPCM"},
|
|
||||||
{coding_XBOX, "XBOX 4-bit IMA ADPCM"},
|
{coding_EA_XA, "Electronic Arts EA-XA 4-bit ADPCM v1"},
|
||||||
{coding_XBOX_int, "XBOX 4-bit IMA ADPCM (interleaved)"},
|
{coding_EA_XA_int, "Electronic Arts EA-XA 4-bit ADPCM v1 (mono/interleave)"},
|
||||||
{coding_EA_XA, "Electronic Arts EA-XA 4-bit ADPCM (v1)"},
|
{coding_EA_XA_V2, "Electronic Arts EA-XA 4-bit ADPCM v2"},
|
||||||
{coding_EA_XA_int, "Electronic Arts EA-XA 4-bit ADPCM (v1) (interleaved)"},
|
|
||||||
{coding_EA_XA_V2, "Electronic Arts EA-XA 4-bit ADPCM (v2)"},
|
|
||||||
{coding_MAXIS_XA, "Maxis EA-XA 4-bit ADPCM"},
|
{coding_MAXIS_XA, "Maxis EA-XA 4-bit ADPCM"},
|
||||||
{coding_SDX2, "Squareroot-delta-exact (SDX2) 8-bit DPCM"},
|
{coding_EA_XAS, "Electronic Arts EA-XAS 4-bit ADPCM"},
|
||||||
{coding_SDX2_int, "Squareroot-delta-exact (SDX2) 8-bit DPCM with 1 byte interleave"},
|
|
||||||
{coding_CBD2, "Cuberoot-delta-exact (CBD2) 8-bit DPCM"},
|
|
||||||
{coding_CBD2_int, "Cuberoot-delta-exact (CBD2) 8-bit DPCM with 1 byte interleave"},
|
|
||||||
{coding_DVI_IMA, "Intel DVI 4-bit IMA ADPCM"},
|
|
||||||
{coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (interleaved)"},
|
|
||||||
{coding_EACS_IMA, "EACS 4-bit IMA ADPCM"},
|
|
||||||
{coding_IMA_int, "IMA 4-bit ADPCM (interleaved)"},
|
|
||||||
{coding_IMA, "IMA 4-bit ADPCM"},
|
{coding_IMA, "IMA 4-bit ADPCM"},
|
||||||
|
{coding_IMA_int, "IMA 4-bit ADPCM (mono/interleave)"},
|
||||||
|
{coding_DVI_IMA, "Intel DVI 4-bit IMA ADPCM"},
|
||||||
|
{coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"},
|
||||||
|
{coding_3DS_IMA, "3DS IMA 4-bit ADPCM"},
|
||||||
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
|
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
|
||||||
|
{coding_XBOX, "XBOX 4-bit IMA ADPCM"},
|
||||||
|
{coding_XBOX_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"},
|
||||||
|
{coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"},
|
||||||
|
{coding_DAT4_IMA, "Eurocom DAT4 4-bit IMA ADPCM"},
|
||||||
{coding_RAD_IMA, "Radical 4-bit IMA ADPCM"},
|
{coding_RAD_IMA, "Radical 4-bit IMA ADPCM"},
|
||||||
{coding_RAD_IMA_mono, "Radical 4-bit IMA ADPCM (mono)"},
|
{coding_RAD_IMA_mono, "Radical 4-bit IMA ADPCM (mono/interleave)"},
|
||||||
{coding_APPLE_IMA4, "Apple Quicktime 4-bit IMA ADPCM"},
|
{coding_APPLE_IMA4, "Apple Quicktime 4-bit IMA ADPCM"},
|
||||||
{coding_SNDS_IMA, "Heavy Iron .snds 4-bit IMA ADPCM"},
|
{coding_SNDS_IMA, "Heavy Iron .snds 4-bit IMA ADPCM"},
|
||||||
{coding_OTNS_IMA, "Omikron: The Nomad Soul 4-bit IMA ADPCM"},
|
{coding_OTNS_IMA, "Omikron: The Nomad Soul 4-bit IMA ADPCM"},
|
||||||
@ -454,15 +456,9 @@ static const coding_info coding_info_list[] = {
|
|||||||
{coding_REF_IMA, "Reflections 4-bit IMA ADPCM"},
|
{coding_REF_IMA, "Reflections 4-bit IMA ADPCM"},
|
||||||
{coding_AWC_IMA, "Rockstar AWC 4-bit IMA ADPCM"},
|
{coding_AWC_IMA, "Rockstar AWC 4-bit IMA ADPCM"},
|
||||||
{coding_UBI_IMA, "Ubisoft 4-bit IMA ADPCM"},
|
{coding_UBI_IMA, "Ubisoft 4-bit IMA ADPCM"},
|
||||||
{coding_WS, "Westwood Studios VBR ADPCM"},
|
|
||||||
{coding_ACM, "InterPlay ACM"},
|
|
||||||
{coding_NWA0, "NWA DPCM Level 0"},
|
|
||||||
{coding_NWA1, "NWA DPCM Level 1"},
|
|
||||||
{coding_NWA2, "NWA DPCM Level 2"},
|
|
||||||
{coding_NWA3, "NWA DPCM Level 3"},
|
|
||||||
{coding_NWA4, "NWA DPCM Level 4"},
|
|
||||||
{coding_NWA5, "NWA DPCM Level 5"},
|
|
||||||
{coding_MSADPCM, "Microsoft 4-bit ADPCM"},
|
{coding_MSADPCM, "Microsoft 4-bit ADPCM"},
|
||||||
|
{coding_WS, "Westwood Studios VBR ADPCM"},
|
||||||
{coding_AICA, "Yamaha AICA 4-bit ADPCM"},
|
{coding_AICA, "Yamaha AICA 4-bit ADPCM"},
|
||||||
{coding_NDS_PROCYON, "Procyon Studio Digital Sound Elements NDS 4-bit APDCM"},
|
{coding_NDS_PROCYON, "Procyon Studio Digital Sound Elements NDS 4-bit APDCM"},
|
||||||
{coding_L5_555, "Level-5 0x555 4-bit ADPCM"},
|
{coding_L5_555, "Level-5 0x555 4-bit ADPCM"},
|
||||||
@ -471,7 +467,20 @@ static const coding_info coding_info_list[] = {
|
|||||||
{coding_MTAF, "Konami MTAF 4-bit ADPCM"},
|
{coding_MTAF, "Konami MTAF 4-bit ADPCM"},
|
||||||
{coding_MTA2, "Konami MTA2 4-bit ADPCM"},
|
{coding_MTA2, "Konami MTA2 4-bit ADPCM"},
|
||||||
{coding_MC3, "Paradigm MC3 3-bit ADPCM"},
|
{coding_MC3, "Paradigm MC3 3-bit ADPCM"},
|
||||||
{coding_EA_XAS, "Electronic Arts EA-XAS 4-bit ADPCM"},
|
|
||||||
|
{coding_SDX2, "Squareroot-delta-exact (SDX2) 8-bit DPCM"},
|
||||||
|
{coding_SDX2_int, "Squareroot-delta-exact (SDX2) 8-bit DPCM with 1 byte interleave"},
|
||||||
|
{coding_CBD2, "Cuberoot-delta-exact (CBD2) 8-bit DPCM"},
|
||||||
|
{coding_CBD2_int, "Cuberoot-delta-exact (CBD2) 8-bit DPCM with 1 byte interleave"},
|
||||||
|
{coding_ACM, "InterPlay ACM"},
|
||||||
|
{coding_NWA0, "NWA DPCM Level 0"},
|
||||||
|
{coding_NWA1, "NWA DPCM Level 1"},
|
||||||
|
{coding_NWA2, "NWA DPCM Level 2"},
|
||||||
|
{coding_NWA3, "NWA DPCM Level 3"},
|
||||||
|
{coding_NWA4, "NWA DPCM Level 4"},
|
||||||
|
{coding_NWA5, "NWA DPCM Level 5"},
|
||||||
|
|
||||||
|
{coding_CRI_HCA, "CRI HCA"},
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
{coding_ogg_vorbis, "Ogg Vorbis"},
|
{coding_ogg_vorbis, "Ogg Vorbis"},
|
||||||
@ -508,8 +517,8 @@ static const layout_info layout_info_list[] = {
|
|||||||
{layout_ast_blocked, "AST blocked"},
|
{layout_ast_blocked, "AST blocked"},
|
||||||
{layout_halpst_blocked, "HALPST blocked"},
|
{layout_halpst_blocked, "HALPST blocked"},
|
||||||
{layout_xa_blocked, "CD-ROM XA"},
|
{layout_xa_blocked, "CD-ROM XA"},
|
||||||
{layout_ea_blocked, "Electronic Arts SCxx blocked"},
|
{layout_ea_blocked, "blocked (EA SCHl)"},
|
||||||
{layout_eacs_blocked, "Electronic Arts EACS blocked"},
|
{layout_blocked_ea_1snh, "blocked (EA 1SNh)"},
|
||||||
{layout_caf_blocked, "CAF blocked"},
|
{layout_caf_blocked, "CAF blocked"},
|
||||||
{layout_wsi_blocked, ".wsi blocked"},
|
{layout_wsi_blocked, ".wsi blocked"},
|
||||||
{layout_xvas_blocked, ".xvas blocked"},
|
{layout_xvas_blocked, ".xvas blocked"},
|
||||||
@ -629,9 +638,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_HGC1, "Knights of the Temple 2 hgC1 Header"},
|
{meta_HGC1, "Knights of the Temple 2 hgC1 Header"},
|
||||||
{meta_AUS, "Capcom AUS Header"},
|
{meta_AUS, "Capcom AUS Header"},
|
||||||
{meta_RWS, "RenderWare RWS header"},
|
{meta_RWS, "RenderWare RWS header"},
|
||||||
{meta_EACS_PC, "Electronic Arts EACS header (PC)"},
|
{meta_EA_1SNH, "Electronic Arts 1SNh/EACS header"},
|
||||||
{meta_EACS_PSX, "Electronic Arts EACS header (PSX)"},
|
|
||||||
{meta_EACS_SAT, "Electronic Arts EACS header (SATURN)"},
|
|
||||||
{meta_SL3, "SL3 Header"},
|
{meta_SL3, "SL3 Header"},
|
||||||
{meta_FSB1, "FMOD Sample Bank (FSB1) Header"},
|
{meta_FSB1, "FMOD Sample Bank (FSB1) Header"},
|
||||||
{meta_FSB2, "FMOD Sample Bank (FSB2) Header"},
|
{meta_FSB2, "FMOD Sample Bank (FSB2) Header"},
|
||||||
@ -651,8 +658,8 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_FILP, "Bio Hazard - Gun Survivor FILp Header"},
|
{meta_FILP, "Bio Hazard - Gun Survivor FILp Header"},
|
||||||
{meta_IKM, "Zwei!! IKM Header"},
|
{meta_IKM, "Zwei!! IKM Header"},
|
||||||
{meta_SFS, "Baroque SFS Header"},
|
{meta_SFS, "Baroque SFS Header"},
|
||||||
{meta_DVI, "DVI Header"},
|
{meta_SAT_DVI, "Konami KCEN DVI. header"},
|
||||||
{meta_KCEY, "KCEYCOMP Header"},
|
{meta_DC_KCEY, "Konami KCEY KCEYCOMP header"},
|
||||||
{meta_BG00, "Falcom BG00 Header"},
|
{meta_BG00, "Falcom BG00 Header"},
|
||||||
{meta_PS2_RSTM, "Rockstar Games RSTM Header"},
|
{meta_PS2_RSTM, "Rockstar Games RSTM Header"},
|
||||||
{meta_ACM, "InterPlay ACM Header"},
|
{meta_ACM, "InterPlay ACM Header"},
|
||||||
@ -665,8 +672,8 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_RIFX_WAVE, "RIFX WAVE header"},
|
{meta_RIFX_WAVE, "RIFX WAVE header"},
|
||||||
{meta_RIFX_WAVE_smpl, "RIFX WAVE header with sample looping info"},
|
{meta_RIFX_WAVE_smpl, "RIFX WAVE header with sample looping info"},
|
||||||
{meta_XNB, "Microsoft XNA Game Studio 4.0 header"},
|
{meta_XNB, "Microsoft XNA Game Studio 4.0 header"},
|
||||||
{meta_PCM_SCD, "PCM file with custom header (SCD)"},
|
{meta_SCD_PCM, "Lunar: Eternal Blue .PCM header"},
|
||||||
{meta_PCM_PS2, "PCM file with custom header (PS2)"},
|
{meta_PS2_PCM, "Konami KCEJ East .PCM header"},
|
||||||
{meta_PS2_RKV, "Legacy of Kain - Blood Omen 2 RKV Header"},
|
{meta_PS2_RKV, "Legacy of Kain - Blood Omen 2 RKV Header"},
|
||||||
{meta_PS2_PSW, "Rayman Raving Rabbids Riff Container File"},
|
{meta_PS2_PSW, "Rayman Raving Rabbids Riff Container File"},
|
||||||
{meta_PS2_VAS, "Pro Baseball Spirits 5 VAS Header"},
|
{meta_PS2_VAS, "Pro Baseball Spirits 5 VAS Header"},
|
||||||
@ -681,7 +688,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_XBOX_XMU, "XMU header"},
|
{meta_XBOX_XMU, "XMU header"},
|
||||||
{meta_XBOX_XVAS, "assumed TMNT file by .xvas extension"},
|
{meta_XBOX_XVAS, "assumed TMNT file by .xvas extension"},
|
||||||
{meta_PS2_XA2, "Acclaim XA2 Header"},
|
{meta_PS2_XA2, "Acclaim XA2 Header"},
|
||||||
{meta_DC_IDVI, "IDVI Header"},
|
{meta_DC_IDVI, "Capcom IDVI header"},
|
||||||
{meta_NGC_YMF, "YMF DSP Header"},
|
{meta_NGC_YMF, "YMF DSP Header"},
|
||||||
{meta_PS2_CCC, "CCC Header"},
|
{meta_PS2_CCC, "CCC Header"},
|
||||||
{meta_PSX_FAG, "FAG Header"},
|
{meta_PSX_FAG, "FAG Header"},
|
||||||
@ -774,7 +781,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_WII_WAS, "WAS (iSWS) DSP header"},
|
{meta_WII_WAS, "WAS (iSWS) DSP header"},
|
||||||
{meta_XBOX_HLWAV, "Half Life 2 bgm header"},
|
{meta_XBOX_HLWAV, "Half Life 2 bgm header"},
|
||||||
{meta_STX, "Nintendo .stx header"},
|
{meta_STX, "Nintendo .stx header"},
|
||||||
{meta_MYSPD, "U-Sing .myspd header"},
|
{meta_MYSPD, "U-Sing .MYSPD header"},
|
||||||
{meta_HIS, "Her Interactive Sound header"},
|
{meta_HIS, "Her Interactive Sound header"},
|
||||||
{meta_PS2_AST, "KOEI AST header"},
|
{meta_PS2_AST, "KOEI AST header"},
|
||||||
{meta_CAPDSP, "Capcom DSP header"},
|
{meta_CAPDSP, "Capcom DSP header"},
|
||||||
@ -824,7 +831,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_NGCA, "NGCA header"},
|
{meta_NGCA, "NGCA header"},
|
||||||
{meta_WII_RAS, "RAS header"},
|
{meta_WII_RAS, "RAS header"},
|
||||||
{meta_PS2_SPM, "SPM header"},
|
{meta_PS2_SPM, "SPM header"},
|
||||||
{meta_X360_TRA, "assumed DefJam Rapstar Audio File by .tra extension"},
|
{meta_X360_TRA, "Terminal Reality .TRA raw header"},
|
||||||
{meta_PS2_VGS, "Princess Soft VGS header"},
|
{meta_PS2_VGS, "Princess Soft VGS header"},
|
||||||
{meta_PS2_IAB, "IAB header"},
|
{meta_PS2_IAB, "IAB header"},
|
||||||
{meta_PS2_STRLR, "STR L/R header"},
|
{meta_PS2_STRLR, "STR L/R header"},
|
||||||
@ -842,7 +849,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_PS2_MTAF, "Konami MTAF header"},
|
{meta_PS2_MTAF, "Konami MTAF header"},
|
||||||
{meta_PS2_VAG1, "Konami VAG Mono header (VAG1)"},
|
{meta_PS2_VAG1, "Konami VAG Mono header (VAG1)"},
|
||||||
{meta_PS2_VAG2, "Konami VAG Stereo header (VAG2)"},
|
{meta_PS2_VAG2, "Konami VAG Stereo header (VAG2)"},
|
||||||
{meta_TUN, "TUN 'ALP' header"},
|
{meta_TUN, "Lego Racers ALP header"},
|
||||||
{meta_WPD, "WPD 'DPW' header"},
|
{meta_WPD, "WPD 'DPW' header"},
|
||||||
{meta_MN_STR, "Mini Ninjas 'STR' header"},
|
{meta_MN_STR, "Mini Ninjas 'STR' header"},
|
||||||
{meta_MSS, "Guerilla MCSS header"},
|
{meta_MSS, "Guerilla MCSS header"},
|
||||||
|
@ -8,23 +8,24 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
|||||||
int samples_per_frame = get_vgmstream_samples_per_frame(vgmstream);
|
int samples_per_frame = get_vgmstream_samples_per_frame(vgmstream);
|
||||||
int samples_this_block;
|
int samples_this_block;
|
||||||
|
|
||||||
|
/* get samples in the current block */
|
||||||
if (vgmstream->current_block_samples) {
|
if (vgmstream->current_block_samples) {
|
||||||
samples_this_block = vgmstream->current_block_samples;
|
samples_this_block = vgmstream->current_block_samples;
|
||||||
} else if (frame_size == 0) {
|
} else if (frame_size == 0) { /* assume 4 bit */ //TODO: get_vgmstream_frame_size() really should return bits... */
|
||||||
/* assume 4 bit */
|
|
||||||
/* TODO: get_vgmstream_frame_size() really should return bits... */
|
|
||||||
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
|
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
|
||||||
} else {
|
} else {
|
||||||
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
|
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (samples_written<sample_count) {
|
/* decode all samples */
|
||||||
|
while (samples_written < sample_count) {
|
||||||
int samples_to_do;
|
int samples_to_do;
|
||||||
|
|
||||||
if (vgmstream->loop_flag && vgmstream_do_loop(vgmstream)) {
|
if (vgmstream->loop_flag && vgmstream_do_loop(vgmstream)) {
|
||||||
|
/* on loop those values are changed */
|
||||||
if (vgmstream->current_block_samples) {
|
if (vgmstream->current_block_samples) {
|
||||||
samples_this_block = vgmstream->current_block_samples;
|
samples_this_block = vgmstream->current_block_samples;
|
||||||
} else if (frame_size == 0) {
|
} else if (frame_size == 0) { /* assume 4 bit */ //TODO: get_vgmstream_frame_size() really should return bits... */
|
||||||
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
|
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
|
||||||
} else {
|
} else {
|
||||||
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
|
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
|
||||||
@ -32,25 +33,35 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* probably block bug or EOF, next calcs would give wrong values and buffer segfaults */
|
||||||
|
if (samples_this_block <= 0) {
|
||||||
|
VGM_LOG("layout_blocked: empty/wrong block\n");
|
||||||
|
memset(buffer + samples_written*vgmstream->channels, 0, (sample_count - samples_written) * vgmstream->channels * sizeof(sample));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
samples_to_do = vgmstream_samples_to_do(samples_this_block, samples_per_frame, vgmstream);
|
samples_to_do = vgmstream_samples_to_do(samples_this_block, samples_per_frame, vgmstream);
|
||||||
|
if (samples_written + samples_to_do > sample_count)
|
||||||
|
samples_to_do = sample_count - samples_written;
|
||||||
|
|
||||||
if (samples_written+samples_to_do > sample_count)
|
if (vgmstream->current_block_offset >= 0) {
|
||||||
samples_to_do=sample_count-samples_written;
|
|
||||||
|
|
||||||
if (vgmstream->current_block_offset>=0)
|
|
||||||
decode_vgmstream(vgmstream, samples_written, samples_to_do, buffer);
|
decode_vgmstream(vgmstream, samples_written, samples_to_do, buffer);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
/* block end signal (used below): partially 0-set buffer */
|
||||||
int i;
|
int i;
|
||||||
/* we've run off the end! */
|
for (i = samples_written*vgmstream->channels; i < (samples_written+samples_to_do)*vgmstream->channels; i++) {
|
||||||
for (i=samples_written*vgmstream->channels;
|
|
||||||
i<(samples_written+samples_to_do)*vgmstream->channels;i++)
|
|
||||||
buffer[i]=0;
|
buffer[i]=0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
samples_written += samples_to_do;
|
samples_written += samples_to_do;
|
||||||
vgmstream->current_sample += samples_to_do;
|
vgmstream->current_sample += samples_to_do;
|
||||||
vgmstream->samples_into_block+=samples_to_do;
|
vgmstream->samples_into_block += samples_to_do;
|
||||||
|
|
||||||
|
|
||||||
|
/* move to next block when all samples are consumed */
|
||||||
if (vgmstream->samples_into_block==samples_this_block
|
if (vgmstream->samples_into_block==samples_this_block
|
||||||
/*&& vgmstream->current_sample < vgmstream->num_samples*/) { /* don't go past last block */
|
/*&& vgmstream->current_sample < vgmstream->num_samples*/) { /* don't go past last block */
|
||||||
switch (vgmstream->layout_type) {
|
switch (vgmstream->layout_type) {
|
||||||
@ -64,7 +75,7 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
|||||||
if (vgmstream->next_block_offset>=0)
|
if (vgmstream->next_block_offset>=0)
|
||||||
halpst_block_update(vgmstream->next_block_offset,vgmstream);
|
halpst_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
else
|
else
|
||||||
vgmstream->current_block_offset=-1;
|
vgmstream->current_block_offset = -1;
|
||||||
break;
|
break;
|
||||||
case layout_xa_blocked:
|
case layout_xa_blocked:
|
||||||
xa_block_update(vgmstream->next_block_offset,vgmstream);
|
xa_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
@ -72,8 +83,8 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
|||||||
case layout_ea_blocked:
|
case layout_ea_blocked:
|
||||||
ea_schl_block_update(vgmstream->next_block_offset,vgmstream);
|
ea_schl_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
break;
|
break;
|
||||||
case layout_eacs_blocked:
|
case layout_blocked_ea_1snh:
|
||||||
eacs_block_update(vgmstream->next_block_offset,vgmstream);
|
block_update_ea_1snh(vgmstream->next_block_offset,vgmstream);
|
||||||
break;
|
break;
|
||||||
case layout_caf_blocked:
|
case layout_caf_blocked:
|
||||||
caf_block_update(vgmstream->next_block_offset,vgmstream);
|
caf_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
@ -155,17 +166,19 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* for VBR these may change */
|
/* for VBR these may change */
|
||||||
frame_size = get_vgmstream_frame_size(vgmstream);
|
frame_size = get_vgmstream_frame_size(vgmstream); /* for VBR these may change */
|
||||||
samples_per_frame = get_vgmstream_samples_per_frame(vgmstream);
|
samples_per_frame = get_vgmstream_samples_per_frame(vgmstream);
|
||||||
|
|
||||||
|
/* get samples in the current block */
|
||||||
if (vgmstream->current_block_samples) {
|
if (vgmstream->current_block_samples) {
|
||||||
samples_this_block = vgmstream->current_block_samples;
|
samples_this_block = vgmstream->current_block_samples;
|
||||||
} else if (frame_size == 0) {
|
} else if (frame_size == 0) { /* assume 4 bit */ //TODO: get_vgmstream_frame_size() really should return bits... */
|
||||||
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
|
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
|
||||||
} else {
|
} else {
|
||||||
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
|
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
|
||||||
}
|
}
|
||||||
vgmstream->samples_into_block=0;
|
|
||||||
|
vgmstream->samples_into_block = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
83
src/layout/blocked_ea_1snh.c
Normal file
83
src/layout/blocked_ea_1snh.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "layout.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
/* set up for the block at the given offset */
|
||||||
|
void block_update_ea_1snh(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||||
|
int i;
|
||||||
|
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
|
||||||
|
uint32_t id;
|
||||||
|
size_t file_size, block_size = 0, block_header = 0;
|
||||||
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_32bitBE : read_32bitLE;
|
||||||
|
|
||||||
|
|
||||||
|
/* find target block ID and skip the rest */
|
||||||
|
file_size = get_streamfile_size(streamFile);
|
||||||
|
while (block_offset < file_size) {
|
||||||
|
id = read_32bitBE(block_offset+0x00,streamFile);
|
||||||
|
block_size = read_32bit(block_offset+0x04,streamFile); /* includes id/size */
|
||||||
|
block_header = 0x0;
|
||||||
|
|
||||||
|
if (id == 0x31534E68) { /* "1SNh" header block found */
|
||||||
|
block_header = read_32bitBE(block_offset+0x08, streamFile) == 0x45414353 ? 0x28 : 0x2c; /* "EACS" */
|
||||||
|
if (block_header < block_size) /* sometimes has data */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0x31534E64) { /* "1SNd" data block found */
|
||||||
|
block_header = 0x08;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0x00000000 || id == 0xFFFFFFFF) { /* EOF: possible? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* any other blocks "1SNl" "1SNe" etc */ //todo parse movie blocks
|
||||||
|
block_offset += block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
vgmstream->current_block_offset = block_offset;
|
||||||
|
vgmstream->next_block_offset = block_offset + block_size;
|
||||||
|
vgmstream->current_block_size = block_size - block_header;
|
||||||
|
|
||||||
|
|
||||||
|
/* set new channel offsets and block sizes */
|
||||||
|
switch(vgmstream->coding_type) {
|
||||||
|
case coding_PCM8_int:
|
||||||
|
vgmstream->current_block_size /= vgmstream->channels;
|
||||||
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
|
vgmstream->ch[i].offset = block_offset + block_header + i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case coding_PCM16_int:
|
||||||
|
vgmstream->current_block_size /= vgmstream->channels;
|
||||||
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
|
vgmstream->ch[i].offset = block_offset + block_header + (i*2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case coding_PSX:
|
||||||
|
vgmstream->current_block_size /= vgmstream->channels;
|
||||||
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
|
vgmstream->ch[i].offset = block_offset + block_header + i*vgmstream->current_block_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case coding_DVI_IMA:
|
||||||
|
vgmstream->current_block_size -= 0x14;
|
||||||
|
for(i = 0; i < vgmstream->channels; i++) {
|
||||||
|
off_t adpcm_offset = block_offset + block_header + 0x04;
|
||||||
|
vgmstream->ch[i].adpcm_step_index = read_32bit(adpcm_offset + i*0x04, streamFile);
|
||||||
|
vgmstream->ch[i].adpcm_history1_32 = read_32bit(adpcm_offset + 0x04*vgmstream->channels + i*0x04, streamFile);
|
||||||
|
// todo some demuxed vids don't have ADPCM hist? not sure how to correctly detect
|
||||||
|
vgmstream->ch[i].offset = block_offset + block_header + 0x14;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -91,7 +91,7 @@ void ea_schl_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* id, size, IMA hist, stereo/mono data */
|
/* id, size, IMA hist, stereo/mono data */
|
||||||
case coding_EACS_IMA:
|
case coding_DVI_IMA:
|
||||||
for(i = 0; i < vgmstream->channels; i++) {
|
for(i = 0; i < vgmstream->channels; i++) {
|
||||||
off_t header_offset = block_offset + 0xc + i*4;
|
off_t header_offset = block_offset + 0xc + i*4;
|
||||||
vgmstream->ch[i].adpcm_history1_32 = read_16bitLE(header_offset+0x00, vgmstream->ch[i].streamfile);
|
vgmstream->ch[i].adpcm_history1_32 = read_16bitLE(header_offset+0x00, vgmstream->ch[i].streamfile);
|
||||||
@ -172,53 +172,3 @@ void ea_schl_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eacs_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
|
||||||
int i;
|
|
||||||
off_t block_size=vgmstream->current_block_size;
|
|
||||||
|
|
||||||
if(read_32bitBE(block_offset,vgmstream->ch[0].streamfile)==0x31534E6C) {
|
|
||||||
block_offset+=0x0C;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->current_block_offset = block_offset;
|
|
||||||
|
|
||||||
if(read_32bitBE(block_offset,vgmstream->ch[0].streamfile)==0x31534E64) { /* 1Snd */
|
|
||||||
block_offset+=4;
|
|
||||||
if(vgmstream->ea_platform==0)
|
|
||||||
block_size=read_32bitLE(vgmstream->current_block_offset+0x04,
|
|
||||||
vgmstream->ch[0].streamfile);
|
|
||||||
else
|
|
||||||
block_size=read_32bitBE(vgmstream->current_block_offset+0x04,
|
|
||||||
vgmstream->ch[0].streamfile);
|
|
||||||
block_offset+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->current_block_size=block_size-8;
|
|
||||||
|
|
||||||
if(vgmstream->coding_type==coding_EACS_IMA) {
|
|
||||||
vgmstream->current_block_size=read_32bitLE(block_offset,vgmstream->ch[0].streamfile);
|
|
||||||
|
|
||||||
for(i=0;i<vgmstream->channels;i++) {
|
|
||||||
vgmstream->ch[i].adpcm_step_index = read_32bitLE(block_offset+0x04+i*4,vgmstream->ch[0].streamfile);
|
|
||||||
vgmstream->ch[i].adpcm_history1_32 = read_32bitLE(block_offset+0x04+i*4+(4*vgmstream->channels),vgmstream->ch[0].streamfile);
|
|
||||||
vgmstream->ch[i].offset = block_offset+0x14;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(vgmstream->coding_type==coding_PSX) {
|
|
||||||
for (i=0;i<vgmstream->channels;i++)
|
|
||||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+8+(i*(vgmstream->current_block_size/2));
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for (i=0;i<vgmstream->channels;i++) {
|
|
||||||
if(vgmstream->coding_type==coding_PCM16_int)
|
|
||||||
vgmstream->ch[i].offset = block_offset+(i*2);
|
|
||||||
else
|
|
||||||
vgmstream->ch[i].offset = block_offset+i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vgmstream->current_block_size/=vgmstream->channels;
|
|
||||||
}
|
|
||||||
vgmstream->next_block_offset = vgmstream->current_block_offset +
|
|
||||||
(off_t)block_size;
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,7 @@ void xa_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|||||||
|
|
||||||
void ea_schl_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
void ea_schl_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void eacs_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
void block_update_ea_1snh(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void caf_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
void caf_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
@ -4,34 +4,55 @@
|
|||||||
|
|
||||||
/* set up for the block at the given offset */
|
/* set up for the block at the given offset */
|
||||||
void xa_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
void xa_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int8_t currentChannel=0;
|
int8_t currentChannel=0;
|
||||||
int8_t subAudio=0;
|
int8_t subAudio=0;
|
||||||
|
|
||||||
init_get_high_nibble(vgmstream);
|
xa_init_get_high_nibble(vgmstream);
|
||||||
|
|
||||||
if(vgmstream->samples_into_block!=0)
|
/* don't change this variable in the init process */
|
||||||
// don't change this variable in the init process
|
if (vgmstream->samples_into_block != 0)
|
||||||
vgmstream->xa_sector_length+=128;
|
vgmstream->xa_sector_length += 0x80;
|
||||||
|
|
||||||
|
/* XA mode2/form2 sector
|
||||||
|
* 0x00: sync word
|
||||||
|
* 0x0c: header = minute, second, sector, mode (always 0x02)
|
||||||
|
* 0x10: subheader = file, channel (marker), submode flags, xa header
|
||||||
|
* 0x14: subheader again
|
||||||
|
* 0x18: data
|
||||||
|
* 0x918: unused
|
||||||
|
* 0x92c: EDC/checksum or null
|
||||||
|
* 0x930: end
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* submode flags (typical audio value = 0x64)
|
||||||
|
* - 7: end of file
|
||||||
|
* - 6: real time mode
|
||||||
|
* - 5: sector form (0=form1, 1=form2)
|
||||||
|
* - 4: trigger (for application)
|
||||||
|
* - 3: data sector
|
||||||
|
* - 2: audio sector
|
||||||
|
* - 1: video sector
|
||||||
|
* - 0: end of audio
|
||||||
|
*/
|
||||||
|
|
||||||
// We get to the end of a sector ?
|
// We get to the end of a sector ?
|
||||||
if(vgmstream->xa_sector_length==(18*128)) {
|
if (vgmstream->xa_sector_length == (18*0x80)) {
|
||||||
vgmstream->xa_sector_length=0;
|
vgmstream->xa_sector_length = 0;
|
||||||
|
|
||||||
// 0x30 of unused bytes/sector :(
|
// 0x30 of unused bytes/sector :(
|
||||||
if (!vgmstream->xa_headerless) {
|
if (!vgmstream->xa_headerless) {
|
||||||
block_offset+=0x30;
|
block_offset += 0x30;
|
||||||
begin:
|
begin:
|
||||||
// Search for selected channel & valid audio
|
// Search for selected channel & valid audio
|
||||||
currentChannel=read_8bit(block_offset-7,vgmstream->ch[0].streamfile);
|
currentChannel = read_8bit(block_offset-0x07,vgmstream->ch[0].streamfile);
|
||||||
subAudio=read_8bit(block_offset-6,vgmstream->ch[0].streamfile);
|
subAudio = read_8bit(block_offset-0x06,vgmstream->ch[0].streamfile);
|
||||||
|
|
||||||
// audio is coded as 0x64
|
// audio is coded as 0x64
|
||||||
if(!((subAudio==0x64) && (currentChannel==vgmstream->xa_channel))) {
|
if (!((subAudio==0x64) && (currentChannel==vgmstream->xa_channel))) {
|
||||||
// go to next sector
|
// go to next sector
|
||||||
block_offset+=2352;
|
block_offset += 0x930;
|
||||||
if(currentChannel!=-1) goto begin;
|
if (currentChannel!=-1) goto begin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,9 +63,9 @@ begin:
|
|||||||
// i set up 0 to current_block_size to make vgmstream not playing bad samples
|
// i set up 0 to current_block_size to make vgmstream not playing bad samples
|
||||||
// another way to do it ???
|
// another way to do it ???
|
||||||
// (as the number of samples can be false in cd-xa due to multi-channels)
|
// (as the number of samples can be false in cd-xa due to multi-channels)
|
||||||
vgmstream->current_block_size = (currentChannel==-1?0:112);
|
vgmstream->current_block_size = (currentChannel==-1 ? 0 : 0x70);
|
||||||
|
|
||||||
vgmstream->next_block_offset = vgmstream->current_block_offset+128;
|
vgmstream->next_block_offset = vgmstream->current_block_offset + 0x80;
|
||||||
for (i=0;i<vgmstream->channels;i++) {
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
vgmstream->ch[i].offset = vgmstream->current_block_offset;
|
vgmstream->ch[i].offset = vgmstream->current_block_offset;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\ea_old.c"
|
RelativePath=".\meta\ea_1snh.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@ -691,7 +691,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\pcm.c"
|
RelativePath=".\meta\scd_pcm.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@ -858,6 +858,10 @@
|
|||||||
RelativePath=".\meta\ps2_p2bt.c"
|
RelativePath=".\meta\ps2_p2bt.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\meta\ps2_pcm.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\ps2_pnb.c"
|
RelativePath=".\meta\ps2_pnb.c"
|
||||||
>
|
>
|
||||||
@ -1586,6 +1590,10 @@
|
|||||||
RelativePath=".\layout\blocked_awc.c"
|
RelativePath=".\layout\blocked_awc.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\layout\blocked_ea_1snh.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\layout\blocked_vgs.c"
|
RelativePath=".\layout\blocked_vgs.c"
|
||||||
>
|
>
|
||||||
|
@ -223,7 +223,7 @@
|
|||||||
<ClCompile Include="meta\dsp_sth_str.c" />
|
<ClCompile Include="meta\dsp_sth_str.c" />
|
||||||
<ClCompile Include="meta\ea_schl.c" />
|
<ClCompile Include="meta\ea_schl.c" />
|
||||||
<ClCompile Include="meta\ea_schl_fixed.c" />
|
<ClCompile Include="meta\ea_schl_fixed.c" />
|
||||||
<ClCompile Include="meta\ea_old.c" />
|
<ClCompile Include="meta\ea_1snh.c" />
|
||||||
<ClCompile Include="meta\ea_snu.c" />
|
<ClCompile Include="meta\ea_snu.c" />
|
||||||
<ClCompile Include="meta\emff.c" />
|
<ClCompile Include="meta\emff.c" />
|
||||||
<ClCompile Include="meta\exakt_sc.c" />
|
<ClCompile Include="meta\exakt_sc.c" />
|
||||||
@ -296,7 +296,7 @@
|
|||||||
<ClCompile Include="meta\pc_smp.c" />
|
<ClCompile Include="meta\pc_smp.c" />
|
||||||
<ClCompile Include="meta\sab.c" />
|
<ClCompile Include="meta\sab.c" />
|
||||||
<ClCompile Include="meta\pc_xa30.c" />
|
<ClCompile Include="meta\pc_xa30.c" />
|
||||||
<ClCompile Include="meta\pcm.c" />
|
<ClCompile Include="meta\scd_pcm.c" />
|
||||||
<ClCompile Include="meta\pona.c" />
|
<ClCompile Include="meta\pona.c" />
|
||||||
<ClCompile Include="meta\pos.c" />
|
<ClCompile Include="meta\pos.c" />
|
||||||
<ClCompile Include="meta\ps2_vds_vdm.c" />
|
<ClCompile Include="meta\ps2_vds_vdm.c" />
|
||||||
@ -333,6 +333,7 @@
|
|||||||
<ClCompile Include="meta\ps2_msa.c" />
|
<ClCompile Include="meta\ps2_msa.c" />
|
||||||
<ClCompile Include="meta\ps2_npsf.c" />
|
<ClCompile Include="meta\ps2_npsf.c" />
|
||||||
<ClCompile Include="meta\ps2_p2bt.c" />
|
<ClCompile Include="meta\ps2_p2bt.c" />
|
||||||
|
<ClCompile Include="meta\ps2_pcm.c" />
|
||||||
<ClCompile Include="meta\ps2_pnb.c" />
|
<ClCompile Include="meta\ps2_pnb.c" />
|
||||||
<ClCompile Include="meta\ps2_psh.c" />
|
<ClCompile Include="meta\ps2_psh.c" />
|
||||||
<ClCompile Include="meta\ps2_psw.c" />
|
<ClCompile Include="meta\ps2_psw.c" />
|
||||||
@ -470,6 +471,7 @@
|
|||||||
<ClCompile Include="layout\bdsp_blocked.c" />
|
<ClCompile Include="layout\bdsp_blocked.c" />
|
||||||
<ClCompile Include="layout\blocked.c" />
|
<ClCompile Include="layout\blocked.c" />
|
||||||
<ClCompile Include="layout\blocked_awc.c" />
|
<ClCompile Include="layout\blocked_awc.c" />
|
||||||
|
<ClCompile Include="layout\blocked_ea_1snh.c" />
|
||||||
<ClCompile Include="layout\blocked_vgs.c" />
|
<ClCompile Include="layout\blocked_vgs.c" />
|
||||||
<ClCompile Include="layout\caf_blocked.c" />
|
<ClCompile Include="layout\caf_blocked.c" />
|
||||||
<ClCompile Include="layout\de2_blocked.c" />
|
<ClCompile Include="layout\de2_blocked.c" />
|
||||||
|
@ -208,7 +208,7 @@
|
|||||||
<ClCompile Include="meta\ea_schl_fixed.c">
|
<ClCompile Include="meta\ea_schl_fixed.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\ea_old.c">
|
<ClCompile Include="meta\ea_1snh.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\ea_snu.c">
|
<ClCompile Include="meta\ea_snu.c">
|
||||||
@ -406,7 +406,7 @@
|
|||||||
<ClCompile Include="meta\pc_xa30.c">
|
<ClCompile Include="meta\pc_xa30.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\pcm.c">
|
<ClCompile Include="meta\scd_pcm.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\pona.c">
|
<ClCompile Include="meta\pona.c">
|
||||||
@ -517,6 +517,9 @@
|
|||||||
<ClCompile Include="meta\ps2_p2bt.c">
|
<ClCompile Include="meta\ps2_p2bt.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="meta\ps2_pcm.c">
|
||||||
|
<Filter>meta\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="meta\ps2_pnb.c">
|
<ClCompile Include="meta\ps2_pnb.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -922,6 +925,9 @@
|
|||||||
<ClCompile Include="layout\blocked_awc.c">
|
<ClCompile Include="layout\blocked_awc.c">
|
||||||
<Filter>layout\Source Files</Filter>
|
<Filter>layout\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="layout\blocked_ea_1snh.c">
|
||||||
|
<Filter>layout\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="layout\blocked_vgs.c">
|
<ClCompile Include="layout\blocked_vgs.c">
|
||||||
<Filter>layout\Source Files</Filter>
|
<Filter>layout\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -173,7 +173,7 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
|
|||||||
interleave = 1;
|
interleave = 1;
|
||||||
break;
|
break;
|
||||||
case 0x41445034: /* ADP4 */
|
case 0x41445034: /* ADP4 */
|
||||||
coding_type = coding_DVI_IMA;
|
coding_type = coding_DVI_IMA_int;
|
||||||
/* don't know how stereo DVI is laid out */
|
/* don't know how stereo DVI is laid out */
|
||||||
if (channel_count != 1) break;
|
if (channel_count != 1) break;
|
||||||
break;
|
break;
|
||||||
|
@ -75,7 +75,7 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
|||||||
if (seek_offset == 0) goto fail;
|
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 */
|
if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */
|
||||||
ima = 1;
|
ima = 1;
|
||||||
coding_type = coding_IMA_int;
|
coding_type = coding_3DS_IMA;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
coding_type = coding_NGC_DSP;
|
coding_type = coding_NGC_DSP;
|
||||||
|
@ -1,40 +1,35 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
/* IDVI (Eldorado Gate Volume 1-7) */
|
/* IDVI - from Capcom's Eldorado Gate Volume 1-7 (DC) */
|
||||||
VGMSTREAM * init_vgmstream_dc_idvi(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_dc_idvi(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
|
||||||
int loop_flag;
|
/* check extension (.dvi: original, .idvi: renamed to header id) */
|
||||||
int channel_count;
|
if ( !check_extensions(streamFile,"dvi,idvi") )
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("idvi",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header */
|
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x49445649) /* "IDVI." */
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = read_32bitLE(0x0C,streamFile);
|
/* check header */
|
||||||
channel_count = read_32bitLE(0x04,streamFile);
|
if (read_32bitBE(0x00,streamFile) != 0x49445649) /* "IDVI" */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
loop_flag = (read_32bitLE(0x0C,streamFile) != 0);
|
||||||
|
channel_count = read_32bitLE(0x04,streamFile); /* always 2? */
|
||||||
|
start_offset = 0x800;
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
start_offset = 0x800;
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
|
||||||
vgmstream->coding_type = coding_DVI_IMA_int;
|
vgmstream->num_samples = ima_bytes_to_samples(get_streamfile_size(streamFile) - start_offset, channel_count);
|
||||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset);
|
|
||||||
if (loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x0C,streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(0x0C,streamFile);
|
||||||
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset);
|
vgmstream->loop_end_sample = ima_bytes_to_samples(get_streamfile_size(streamFile) - start_offset, channel_count);
|
||||||
}
|
|
||||||
|
vgmstream->coding_type = coding_DVI_IMA_int;
|
||||||
vgmstream->meta_type = meta_DC_IDVI;
|
vgmstream->meta_type = meta_DC_IDVI;
|
||||||
|
|
||||||
/* Calculating the short block... */
|
/* Calculating the short block... */
|
||||||
@ -47,24 +42,10 @@ VGMSTREAM * init_vgmstream_dc_idvi(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = file;
|
|
||||||
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
|
||||||
vgmstream->ch[i].offset=start_offset+
|
|
||||||
vgmstream->interleave_block_size*i;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1,65 +1,42 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../coding/coding.h"
|
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_kcey(STREAMFILE *streamFile) {
|
/* DVI - from Konami KCE Yokohama DC games (Pop'n Music series) */
|
||||||
|
VGMSTREAM * init_vgmstream_dc_kcey(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
|
||||||
int loop_flag = 0;
|
/* check extension (.pcm: original, .kcey: renamed to header id) */
|
||||||
int channel_count;
|
if ( !check_extensions(streamFile,"pcm,kcey") )
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("kcey",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header */
|
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x4B434559) /* "DVI." */
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitBE(0x14,streamFile)!=0xFFFFFFFF);
|
/* check header */
|
||||||
|
if (read_32bitBE(0x00,streamFile) != 0x4B434559) /* "KCEY" (also "COMP") */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
start_offset = read_32bitBE(0x10,streamFile);
|
||||||
|
loop_flag = (read_32bitBE(0x14,streamFile) != 0xFFFFFFFF);
|
||||||
channel_count = read_32bitBE(0x08,streamFile);
|
channel_count = read_32bitBE(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 */
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
start_offset = read_32bitBE(0x10,streamFile);
|
|
||||||
vgmstream->sample_rate = 37800;
|
vgmstream->sample_rate = 37800;
|
||||||
vgmstream->coding_type = coding_EACS_IMA;
|
|
||||||
|
|
||||||
vgmstream->num_samples = read_32bitBE(0x0C,streamFile);
|
vgmstream->num_samples = read_32bitBE(0x0C,streamFile);
|
||||||
|
|
||||||
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(0x0C,streamFile);
|
vgmstream->loop_end_sample = read_32bitBE(0x0C,streamFile);
|
||||||
}
|
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_DVI_IMA; /* stereo/mono, high nibble first */
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->meta_type = meta_KCEY;
|
vgmstream->meta_type = meta_DC_KCEY;
|
||||||
vgmstream->get_high_nibble=1;
|
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = file;
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
|
||||||
vgmstream->ch[i].offset=start_offset+(i*vgmstream->interleave_block_size);
|
|
||||||
vgmstream->ch[i].adpcm_history1_32=0;
|
|
||||||
vgmstream->ch[i].adpcm_step_index=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
173
src/meta/ea_1snh.c
Normal file
173
src/meta/ea_1snh.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
#include "../layout/layout.h"
|
||||||
|
|
||||||
|
#define EA_CODEC_PCM 0x00
|
||||||
|
//#define EA_CODEC_??? 0x01 //used in SAT videos
|
||||||
|
#define EA_CODEC_IMA 0x02
|
||||||
|
#define EA_CODEC_PSX 0xFF //fake value
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t sample_rate;
|
||||||
|
uint8_t bits;
|
||||||
|
uint8_t channels;
|
||||||
|
uint8_t codec;
|
||||||
|
uint8_t type;
|
||||||
|
int32_t num_samples;
|
||||||
|
int32_t loop_start;
|
||||||
|
int32_t loop_end;
|
||||||
|
int32_t loop_start_offset;
|
||||||
|
|
||||||
|
int big_endian;
|
||||||
|
int loop_flag;
|
||||||
|
} ea_header;
|
||||||
|
|
||||||
|
static int parse_header(STREAMFILE* streamFile, ea_header* ea, off_t begin_offset);
|
||||||
|
static void set_ea_1snh_psx_samples(STREAMFILE* streamFile, off_t start_offset, ea_header* ea);
|
||||||
|
|
||||||
|
/* EA 1SNh - from early EA games (~1996, ex. Need for Speed) */
|
||||||
|
VGMSTREAM * init_vgmstream_ea_1snh(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset;
|
||||||
|
ea_header ea = {0};
|
||||||
|
|
||||||
|
|
||||||
|
/* check extension (.asf/as4: common, cnk: some PS games) */
|
||||||
|
if (!check_extensions(streamFile,"asf,as4,cnk"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* check header (first block) */
|
||||||
|
if (read_32bitBE(0,streamFile)!=0x31534E68) /* "1SNh" */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* use block size as endian marker (Saturn = BE) */
|
||||||
|
ea.big_endian = !(read_32bitLE(0x04,streamFile) < 0x0000FFFF);
|
||||||
|
|
||||||
|
if (!parse_header(streamFile,&ea, 0x08))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
start_offset = 0x00;
|
||||||
|
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(ea.channels, ea.loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->sample_rate = ea.sample_rate;
|
||||||
|
vgmstream->num_samples = ea.num_samples;
|
||||||
|
vgmstream->loop_start_sample = ea.loop_start;
|
||||||
|
vgmstream->loop_end_sample = ea.loop_end;
|
||||||
|
|
||||||
|
vgmstream->codec_endian = ea.big_endian;
|
||||||
|
vgmstream->layout_type = layout_blocked_ea_1snh;
|
||||||
|
vgmstream->meta_type = meta_EA_1SNH;
|
||||||
|
|
||||||
|
switch (ea.codec) {
|
||||||
|
case EA_CODEC_PCM:
|
||||||
|
vgmstream->coding_type = ea.bits==1 ? coding_PCM8_int : coding_PCM16_int;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EA_CODEC_IMA:
|
||||||
|
if (ea.bits!=2) goto fail;
|
||||||
|
vgmstream->coding_type = coding_DVI_IMA; /* stereo/mono, high nibble first */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EA_CODEC_PSX:
|
||||||
|
vgmstream->coding_type = coding_PSX;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
VGM_LOG("EA: unknown codec 0x%02x\n", ea.codec);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open files; channel offsets are updated below */
|
||||||
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
block_update_ea_1snh(start_offset,vgmstream);
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_header(STREAMFILE* streamFile, ea_header* ea, off_t offset) {
|
||||||
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||||
|
|
||||||
|
if (read_32bitBE(offset+0x00, streamFile) == 0x45414353) { /* "EACS" */
|
||||||
|
/* PC/SAT EACS subheader */
|
||||||
|
ea->sample_rate = read_32bit(offset+0x04, streamFile);
|
||||||
|
ea->bits = read_8bit(offset+0x08, streamFile);
|
||||||
|
ea->channels = read_8bit(offset+0x09, streamFile);
|
||||||
|
ea->codec = read_8bit(offset+0x0a, streamFile);
|
||||||
|
ea->type = read_8bit(offset+0x0b, streamFile);
|
||||||
|
ea->num_samples = read_32bit(offset+0x0c, streamFile);
|
||||||
|
ea->loop_start = read_32bit(offset+0x10, streamFile);
|
||||||
|
ea->loop_end = read_32bit(offset+0x14, streamFile) + ea->loop_start; /* loop length */
|
||||||
|
/* 0x18: data start? (0x00), 0x1c: pan/volume/etc? (0x7F), rest can be padding/garbage */
|
||||||
|
VGM_ASSERT(ea->type != 0, "EA EACS: unknown type\n"); /* block type? */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* PS subheader */
|
||||||
|
ea->sample_rate = read_32bit(offset+0x00, streamFile);
|
||||||
|
ea->channels = read_8bit(offset+0x18, streamFile);
|
||||||
|
ea->codec = EA_CODEC_PSX;
|
||||||
|
set_ea_1snh_psx_samples(streamFile, 0x00, ea);
|
||||||
|
if (ea->loop_start_offset)/* found offset, now find sample start */
|
||||||
|
set_ea_1snh_psx_samples(streamFile, 0x00, ea);
|
||||||
|
}
|
||||||
|
|
||||||
|
ea->loop_flag = (ea->loop_end > 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get total samples by parsing block headers, needed when EACS isn't present */
|
||||||
|
static void set_ea_1snh_psx_samples(STREAMFILE* streamFile, off_t start_offset, ea_header* ea) {
|
||||||
|
int num_samples = 0, loop_start = 0, loop_end = 0, loop_start_offset = 0;
|
||||||
|
off_t block_offset = start_offset;
|
||||||
|
size_t file_size = get_streamfile_size(streamFile);
|
||||||
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||||
|
|
||||||
|
while (block_offset < file_size) {
|
||||||
|
uint32_t id = read_32bitBE(block_offset+0x00,streamFile);
|
||||||
|
size_t block_size = read_32bit(block_offset+0x04,streamFile); /* includes id/size */
|
||||||
|
|
||||||
|
if (id == 0x31534E68) { /* "1SNh" header block found */
|
||||||
|
size_t block_header = read_32bitBE(block_offset+0x08, streamFile) == 0x45414353 ? 0x28 : 0x2c; /* "EACS" */
|
||||||
|
if (block_header < block_size) /* sometimes has data */
|
||||||
|
num_samples += ps_bytes_to_samples(block_size - block_header, ea->channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0x31534E64) { /* "1SNd" data block found */
|
||||||
|
num_samples += ps_bytes_to_samples(block_size - 0x08, ea->channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0x31534E6C) { /* "1SNl" loop point found */
|
||||||
|
loop_start_offset = read_32bit(block_offset+0x08,streamFile);
|
||||||
|
loop_end = num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0x00000000 || id == 0xFFFFFFFF) { /* EOF: possible? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is a loop start offset this was called again just to find it */
|
||||||
|
if (ea->loop_start_offset && ea->loop_start_offset == block_offset) {
|
||||||
|
ea->loop_start = num_samples;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* any other blocks "1SNl" "1SNe" etc */ //todo parse movie blocks
|
||||||
|
block_offset += block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ea->num_samples = num_samples;
|
||||||
|
ea->loop_start = loop_start;
|
||||||
|
ea->loop_end = loop_end;
|
||||||
|
ea->loop_start_offset = loop_start_offset;
|
||||||
|
}
|
@ -1,160 +0,0 @@
|
|||||||
#include "meta.h"
|
|
||||||
#include "../coding/coding.h"
|
|
||||||
#include "../layout/layout.h"
|
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char szID[4];
|
|
||||||
int dwSampleRate;
|
|
||||||
char bBits;
|
|
||||||
char bChannels;
|
|
||||||
char bCompression;
|
|
||||||
char bType;
|
|
||||||
int dwNumSamples;
|
|
||||||
int dwLoopStart;
|
|
||||||
int dwLoopLength;
|
|
||||||
int dwDataStart;
|
|
||||||
int dwUnknown;
|
|
||||||
} EACSHeader;
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_eacs(STREAMFILE *streamFile) {
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
int channel_count;
|
|
||||||
int loop_flag=0;
|
|
||||||
char little_endian=0;
|
|
||||||
EACSHeader *ea_header = NULL;
|
|
||||||
int32_t samples_count=0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("cnk",filename_extension(filename)) &&
|
|
||||||
strcasecmp("as4",filename_extension(filename)) &&
|
|
||||||
strcasecmp("asf",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
ea_header=(EACSHeader *)malloc(sizeof(EACSHeader));
|
|
||||||
|
|
||||||
/* check header */
|
|
||||||
if ((uint32_t)read_32bitBE(0,streamFile)!=0x31534E68) /* "1SNh" */
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* check if we are little or big endian */
|
|
||||||
if ((uint32_t)read_32bitBE(4,streamFile)<0x40)
|
|
||||||
little_endian=1;
|
|
||||||
|
|
||||||
/* check type details */
|
|
||||||
|
|
||||||
if((uint32_t)read_32bitBE(0x08,streamFile)==0x45414353) { /* EACS */
|
|
||||||
read_streamfile((uint8_t*)ea_header,0x08,sizeof(EACSHeader),streamFile);
|
|
||||||
loop_flag = 0; //(ea_header->dwLoopStart!=0);
|
|
||||||
channel_count = (ea_header->bChannels);
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,0);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
|
||||||
init_get_high_nibble(vgmstream);
|
|
||||||
|
|
||||||
vgmstream->sample_rate = ea_header->dwSampleRate;
|
|
||||||
|
|
||||||
if(ea_header->bCompression==0) {
|
|
||||||
vgmstream->coding_type = coding_PCM16_int;
|
|
||||||
if(ea_header->bBits==1)
|
|
||||||
vgmstream->coding_type = coding_PCM8_int;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vgmstream->coding_type = coding_EACS_IMA;
|
|
||||||
|
|
||||||
vgmstream->layout_type = layout_eacs_blocked;
|
|
||||||
vgmstream->meta_type = meta_EACS_PC;
|
|
||||||
|
|
||||||
if(little_endian)
|
|
||||||
vgmstream->meta_type = meta_EACS_SAT;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
channel_count=read_32bitLE(0x20,streamFile);
|
|
||||||
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,0);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
|
|
||||||
vgmstream->coding_type = coding_PSX;
|
|
||||||
vgmstream->layout_type=layout_eacs_blocked;
|
|
||||||
vgmstream->meta_type=meta_EACS_PSX;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->ea_platform=little_endian;
|
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
|
||||||
{
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
|
|
||||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calc the samples length ...
|
|
||||||
if(little_endian)
|
|
||||||
vgmstream->next_block_offset=read_32bitBE(0x04,streamFile);
|
|
||||||
else
|
|
||||||
vgmstream->next_block_offset=read_32bitLE(0x04,streamFile);
|
|
||||||
|
|
||||||
if(vgmstream->next_block_offset>0x30) {
|
|
||||||
vgmstream->current_block_size=vgmstream->next_block_offset-sizeof(EACSHeader);
|
|
||||||
samples_count=(int32_t)vgmstream->current_block_size/get_vgmstream_frame_size(vgmstream)*get_vgmstream_samples_per_frame(vgmstream);
|
|
||||||
samples_count/=vgmstream->channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(read_32bitBE(vgmstream->next_block_offset,vgmstream->ch[0].streamfile)==0x31534E6C) {
|
|
||||||
ea_header->dwLoopStart=read_32bitLE(vgmstream->next_block_offset+0x08,vgmstream->ch[0].streamfile);
|
|
||||||
vgmstream->next_block_offset+=0x0C;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(read_32bitBE(vgmstream->next_block_offset,vgmstream->ch[0].streamfile)==0x31534E65)
|
|
||||||
break;
|
|
||||||
|
|
||||||
eacs_block_update(vgmstream->next_block_offset,vgmstream);
|
|
||||||
samples_count+=vgmstream->current_block_size/get_vgmstream_frame_size(vgmstream)*get_vgmstream_samples_per_frame(vgmstream);
|
|
||||||
} while(vgmstream->next_block_offset<get_streamfile_size(streamFile)-8);
|
|
||||||
|
|
||||||
// Reset values ...
|
|
||||||
// setting up the first header by calling the eacs_block_update sub
|
|
||||||
if(little_endian)
|
|
||||||
vgmstream->next_block_offset=read_32bitBE(0x04,streamFile);
|
|
||||||
else
|
|
||||||
vgmstream->next_block_offset=read_32bitLE(0x04,streamFile);
|
|
||||||
|
|
||||||
vgmstream->current_block_size=vgmstream->next_block_offset-sizeof(EACSHeader);
|
|
||||||
|
|
||||||
if(vgmstream->coding_type!=coding_PSX)
|
|
||||||
vgmstream->current_block_size-=8;
|
|
||||||
|
|
||||||
if(vgmstream->coding_type==coding_PSX)
|
|
||||||
eacs_block_update(0x2C,vgmstream);
|
|
||||||
else
|
|
||||||
eacs_block_update(0x28,vgmstream);
|
|
||||||
|
|
||||||
// re-allocate the sample count
|
|
||||||
vgmstream->num_samples=samples_count;
|
|
||||||
|
|
||||||
if(loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = ea_header->dwLoopStart;
|
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ea_header)
|
|
||||||
free(ea_header);
|
|
||||||
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
|
||||||
if(ea_header)
|
|
||||||
free(ea_header);
|
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -66,7 +66,7 @@ VGMSTREAM * init_vgmstream_ea_schl_fixed(STREAMFILE *streamFile) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EA_CODEC_IMA:
|
case EA_CODEC_IMA:
|
||||||
vgmstream->coding_type = coding_EACS_IMA;
|
vgmstream->coding_type = coding_DVI_IMA; /* stereo/mono, high nibble first */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -155,7 +155,6 @@ static void find_hca_key(hca_codec_data * hca_data, clHCA * hca, uint8_t * buffe
|
|||||||
f++;
|
f++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//;VGM_LOG("HCA: key %08x%08x clip_count=%i\n", ciphKey2,ciphKey1, clip_count);
|
|
||||||
if (min_clip_count < 0 || clip_count < min_clip_count) {
|
if (min_clip_count < 0 || clip_count < min_clip_count) {
|
||||||
min_clip_count = clip_count;
|
min_clip_count = clip_count;
|
||||||
best_key2 = key2;
|
best_key2 = key2;
|
||||||
@ -176,7 +175,7 @@ static void find_hca_key(hca_codec_data * hca_data, clHCA * hca, uint8_t * buffe
|
|||||||
read_streamfile(buffer, hca_data->start, header_size, hca_data->streamfile);
|
read_streamfile(buffer, hca_data->start, header_size, hca_data->streamfile);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
VGM_LOG("HCA: best key=%08x%08x (clips=%i)\n", best_key2,best_key1, min_clip_count);
|
VGM_ASSERT(min_clip_count > 0, "HCA: best key=%08x%08x (clips=%i)\n", best_key2,best_key1, min_clip_count);
|
||||||
*out_key2 = best_key2;
|
*out_key2 = best_key2;
|
||||||
*out_key1 = best_key1;
|
*out_key1 = best_key1;
|
||||||
free(testbuf);//free(temp);
|
free(testbuf);//free(temp);
|
||||||
|
@ -12,7 +12,7 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
static const hcakey_info hcakey_list[] = {
|
static const hcakey_info hcakey_list[] = {
|
||||||
|
|
||||||
// HCA Decoder default
|
// CRI HCA decoder default
|
||||||
{9621963164387704}, // CF222F1FE0748978
|
{9621963164387704}, // CF222F1FE0748978
|
||||||
|
|
||||||
// Phantasy Star Online 2 (multi?)
|
// Phantasy Star Online 2 (multi?)
|
||||||
@ -28,7 +28,13 @@ static const hcakey_info hcakey_list[] = {
|
|||||||
// Ro-Kyu-Bu! Himitsu no Otoshimono (PSP)
|
// Ro-Kyu-Bu! Himitsu no Otoshimono (PSP)
|
||||||
{2012082716}, // 0000000077EDF21C
|
{2012082716}, // 0000000077EDF21C
|
||||||
|
|
||||||
// Ro-Kyu-Bu! Naisho no Shutter Chance (PSV)
|
// VRIDGE Inc. games:
|
||||||
|
// - HatsuKare * Renai Debut Sengen! (PSP)
|
||||||
|
// - Seitokai no Ichizon Lv. 2 Portable (PSP)
|
||||||
|
// - Koi wa Kousoku ni Shibararenai! (PSP)
|
||||||
|
// - StormLover 2nd (PSP)
|
||||||
|
// - Prince of Stride (PSVita)
|
||||||
|
// - Ro-Kyu-Bu! Naisho no Shutter Chance (PSVita)
|
||||||
{1234253142}, // 0000000049913556
|
{1234253142}, // 0000000049913556
|
||||||
|
|
||||||
// Idolm@ster Cinderella Stage (iOS/Android)
|
// Idolm@ster Cinderella Stage (iOS/Android)
|
||||||
@ -123,6 +129,21 @@ static const hcakey_info hcakey_list[] = {
|
|||||||
// Schoolgirl Strikers ~Twinkle Melodies~ (iOS/Android)
|
// Schoolgirl Strikers ~Twinkle Melodies~ (iOS/Android)
|
||||||
{0xDB5B61B8343D0000}, // DB5B61B8343D0000
|
{0xDB5B61B8343D0000}, // DB5B61B8343D0000
|
||||||
|
|
||||||
|
// Bad Apple Wars (PSVita)
|
||||||
|
{241352432}, // 000000000E62BEF0
|
||||||
|
|
||||||
|
// Koi to Senkyo to Chocolate Portable (PSP)
|
||||||
|
{243812156}, // 000000000E88473C
|
||||||
|
|
||||||
|
// Custom Drive (PSP)
|
||||||
|
{2012062010}, // 0000000077EDA13A
|
||||||
|
|
||||||
|
// Root Letter (PSVita)
|
||||||
|
{1547531215412131}, // 00057F78B05F9BA3
|
||||||
|
|
||||||
|
// Pro Evolution Soccer 2018 / Winning Eleven 2018 (Android)
|
||||||
|
{14121473}, // 0000000000D77A01
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ VGMSTREAM * init_vgmstream_pos(STREAMFILE * streamFile);
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_nwa(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_nwa(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_eacs(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_ea_1snh(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_xss(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_xss(STREAMFILE * streamFile);
|
||||||
|
|
||||||
@ -200,11 +200,11 @@ VGMSTREAM * init_vgmstream_ikm(STREAMFILE * streamFile);
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sfs(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_sfs(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_dvi(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_sat_dvi(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_bg00(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_bg00(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_kcey(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_dc_kcey(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ps2_rstm(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_ps2_rstm(STREAMFILE * streamFile);
|
||||||
|
|
||||||
@ -218,9 +218,9 @@ VGMSTREAM * init_vgmstream_ps2_psh(STREAMFILE * streamFile);
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_mus_acm(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_mus_acm(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_scd_pcm(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_pcm_ps2(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_ps2_pcm(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ps2_rkv(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_ps2_rkv(STREAMFILE * streamFile);
|
||||||
|
|
||||||
|
@ -1,59 +1,42 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
/* U-Sing (Wii) .myspd */
|
|
||||||
|
|
||||||
|
/* .MYSPF - from U-Sing (Wii) */
|
||||||
VGMSTREAM * init_vgmstream_myspd(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_myspd(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
int loop_flag = 0, channel_count;
|
||||||
int channel_count;
|
|
||||||
int loop_flag = 0;
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
size_t channel_size;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if (!check_extensions(streamFile,"myspd"))
|
||||||
if (strcasecmp("myspd",filename_extension(filename))) goto fail;
|
goto fail;
|
||||||
|
|
||||||
channel_count = 2;
|
channel_count = 2;
|
||||||
start_offset = 0x20;
|
start_offset = 0x20;
|
||||||
|
channel_size = read_32bitBE(0x00,streamFile);
|
||||||
|
|
||||||
/* check size */
|
/* check size */
|
||||||
if ((read_32bitBE(0x0,streamFile)*channel_count+start_offset) != get_streamfile_size(streamFile))
|
if ((channel_size * channel_count + start_offset) != get_streamfile_size(streamFile))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* 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 */
|
vgmstream->num_samples = ima_bytes_to_samples(channel_size*channel_count, channel_count);
|
||||||
vgmstream->num_samples = read_32bitBE(0x0,streamFile) * 2;
|
vgmstream->sample_rate = read_32bitBE(0x04,streamFile);
|
||||||
vgmstream->sample_rate = read_32bitBE(0x4,streamFile);
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_IMA;
|
|
||||||
vgmstream->meta_type = meta_MYSPD;
|
vgmstream->meta_type = meta_MYSPD;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->coding_type = coding_IMA_int;
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = channel_size;
|
||||||
|
|
||||||
/* open the file for reading */
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
{
|
goto fail;
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
vgmstream->ch[0].streamfile = file;
|
|
||||||
|
|
||||||
vgmstream->ch[0].channel_start_offset=
|
|
||||||
vgmstream->ch[0].offset=start_offset;
|
|
||||||
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
vgmstream->ch[1].streamfile = file;
|
|
||||||
|
|
||||||
vgmstream->ch[0].channel_start_offset=
|
|
||||||
vgmstream->ch[1].offset=start_offset + read_32bitBE(0x0,streamFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_nds_hwas(STREAMFILE *streamFile) {
|
|||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int channel_count, loop_flag = 0;
|
int channel_count, loop_flag = 0;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive (made-up extension) */
|
||||||
if (!check_extensions(streamFile,"hwas"))
|
if (!check_extensions(streamFile,"hwas"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ VGMSTREAM * init_vgmstream_nds_hwas(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
vgmstream->meta_type = meta_NDS_HWAS;
|
vgmstream->meta_type = meta_NDS_HWAS;
|
||||||
|
|
||||||
vgmstream->coding_type = coding_IMA;
|
vgmstream->coding_type = coding_IMA_int;
|
||||||
vgmstream->layout_type = layout_hwas_blocked;
|
vgmstream->layout_type = layout_hwas_blocked;
|
||||||
vgmstream->full_block_size = read_32bitLE(0x04,streamFile); /* usually 0x2000, 0x4000 or 0x8000 */
|
vgmstream->full_block_size = read_32bitLE(0x04,streamFile); /* usually 0x2000, 0x4000 or 0x8000 */
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ VGMSTREAM * init_vgmstream_nds_rrds(STREAMFILE *streamFile) {
|
|||||||
int loop_flag;
|
int loop_flag;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive (made-up extension) */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("rrds",filename_extension(filename))) goto fail;
|
if (strcasecmp("rrds",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ VGMSTREAM * init_vgmstream_nds_rrds(STREAMFILE *streamFile) {
|
|||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->coding_type = coding_IMA;
|
vgmstream->coding_type = coding_IMA_int;
|
||||||
vgmstream->meta_type = meta_NDS_RRDS;
|
vgmstream->meta_type = meta_NDS_RRDS;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* STRM - from Final Fantasy Tactics A2 (NDS) */
|
/* STRM - from Final Fantasy Tactics A2 (NDS) */
|
||||||
VGMSTREAM * init_vgmstream_nds_strm_ffta2(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_nds_strm_ffta2(STREAMFILE *streamFile) {
|
||||||
@ -18,25 +17,24 @@ VGMSTREAM * init_vgmstream_nds_strm_ffta2(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
loop_flag = (read_32bitLE(0x20,streamFile) !=0);
|
loop_flag = (read_32bitLE(0x20,streamFile) !=0);
|
||||||
channel_count = read_32bitLE(0x24,streamFile);
|
channel_count = read_32bitLE(0x24,streamFile);
|
||||||
|
start_offset = 0x2C;
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
start_offset = 0x2C;
|
|
||||||
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_IMA_int; //todo: seems it has some diffs vs regular IMA
|
|
||||||
vgmstream->num_samples = (read_32bitLE(0x04,streamFile)-start_offset);
|
vgmstream->num_samples = (read_32bitLE(0x04,streamFile)-start_offset);
|
||||||
if (loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x20,streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(0x20,streamFile);
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x28,streamFile);
|
vgmstream->loop_end_sample = read_32bitLE(0x28,streamFile);
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->interleave_block_size = 0x80;
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
|
||||||
vgmstream->meta_type = meta_NDS_STRM_FFTA2;
|
vgmstream->meta_type = meta_NDS_STRM_FFTA2;
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_DVI_IMA_int;
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = 0x80;
|
||||||
|
|
||||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE *streamFile) {
|
|||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->coding_type = coding_DVI_IMA;
|
vgmstream->coding_type = coding_DVI_IMA_int;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->meta_type = meta_BOS_ADP;
|
vgmstream->meta_type = meta_BOS_ADP;
|
||||||
|
|
||||||
|
128
src/meta/pcm.c
128
src/meta/pcm.c
@ -1,128 +0,0 @@
|
|||||||
#include "meta.h"
|
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* PCM (from Lunar: Eternal Blue (Sega CD) */
|
|
||||||
VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE *streamFile) {
|
|
||||||
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
|
||||||
|
|
||||||
int loop_flag;
|
|
||||||
int channel_count;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header */
|
|
||||||
if (read_32bitBE(0x0,streamFile) != 0x00020000)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x02,streamFile)!=0);
|
|
||||||
channel_count = 1;
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
|
||||||
start_offset = 0x200;
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
vgmstream->sample_rate = 32000;
|
|
||||||
vgmstream->coding_type = coding_PCM8_SB_int;
|
|
||||||
vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2;
|
|
||||||
if(loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*0x400*2;
|
|
||||||
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 */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = file;
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
|
||||||
vgmstream->ch[i].offset=start_offset+
|
|
||||||
vgmstream->interleave_block_size*i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* PCM - Custom header from Konami, which contains only loop infos...
|
|
||||||
found in: Ephemeral Fantasia [Reiselied]
|
|
||||||
Yu-Gi-Oh! The Duelists of the Roses [Yu-Gi-Oh! Shin Duel Monsters II]
|
|
||||||
*/
|
|
||||||
VGMSTREAM * init_vgmstream_pcm_ps2(STREAMFILE *streamFile) {
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
|
||||||
int loop_flag = 0;
|
|
||||||
int channel_count;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
// if ((read_32bitLE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile)))
|
|
||||||
// goto fail;
|
|
||||||
if ((read_32bitLE(0x00,streamFile)) != (read_32bitLE(0x04,streamFile)*4))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
loop_flag = (read_32bitLE(0x08,streamFile) != 0x0);
|
|
||||||
channel_count = 2;
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
|
||||||
start_offset = 0x800;
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
vgmstream->sample_rate = 24000;
|
|
||||||
vgmstream->coding_type = coding_PCM16LE;
|
|
||||||
vgmstream->num_samples = read_32bitLE(0x0,streamFile)/2/channel_count;
|
|
||||||
if (loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile);
|
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
|
||||||
vgmstream->interleave_block_size = 0x2;
|
|
||||||
vgmstream->meta_type = meta_PCM_PS2;
|
|
||||||
|
|
||||||
/* open the file for reading */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = file;
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
|
||||||
vgmstream->ch[i].offset=start_offset+
|
|
||||||
vgmstream->interleave_block_size*i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
48
src/meta/ps2_pcm.c
Normal file
48
src/meta/ps2_pcm.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
|
/* .PCM - KCE Japan East PS2 games (Ephemeral Fantasia, Yu-Gi-Oh! The Duelists of the Roses, 7 Blades) */
|
||||||
|
VGMSTREAM * init_vgmstream_ps2_pcm(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
|
||||||
|
/* check extension */
|
||||||
|
if ( !check_extensions(streamFile,"pcm") )
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* check header (data_size vs num_samples) */
|
||||||
|
if (pcm_bytes_to_samples(read_32bitLE(0x00,streamFile), 2, 16) != read_32bitLE(0x04,streamFile))
|
||||||
|
goto fail;
|
||||||
|
/* should work too */
|
||||||
|
//if (read_32bitLE(0x00,streamFile)+0x800 != get_streamfile_size(streamFile))
|
||||||
|
// goto fail;
|
||||||
|
|
||||||
|
loop_flag = (read_32bitLE(0x0C,streamFile) != 0x00);
|
||||||
|
channel_count = 2;
|
||||||
|
start_offset = 0x800;
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->channels = channel_count;
|
||||||
|
vgmstream->sample_rate = 24000;
|
||||||
|
vgmstream->num_samples = read_32bitLE(0x04,streamFile);
|
||||||
|
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile);
|
||||||
|
vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile);
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_PCM16LE;
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = 0x2;
|
||||||
|
vgmstream->meta_type = meta_PS2_PCM;
|
||||||
|
|
||||||
|
/* open the file for reading */
|
||||||
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
|
goto fail;
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -1,135 +1,118 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../layout/layout.h"
|
#include "../layout/layout.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
/* Sony PSX CD-XA */
|
|
||||||
/* No looped file ! */
|
|
||||||
|
|
||||||
static off_t init_xa_channel(int *channel,STREAMFILE *streamFile);
|
|
||||||
|
|
||||||
static uint8_t AUDIO_CODING_GET_STEREO(uint8_t value) {
|
|
||||||
return (uint8_t)(value & 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t AUDIO_CODING_GET_FREQ(uint8_t value) {
|
|
||||||
return (uint8_t)((value >> 2) & 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* CD-XA - from Sony PS1 CDs */
|
||||||
VGMSTREAM * init_vgmstream_cdxa(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_cdxa(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
|
|
||||||
int channel_count;
|
|
||||||
int headerless=0;
|
|
||||||
int xa_channel=0;
|
|
||||||
uint8_t bCoding;
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
int loop_flag = 0, channel_count, sample_rate;
|
||||||
|
int xa_channel=0;
|
||||||
|
int is_blocked;
|
||||||
|
size_t file_size = get_streamfile_size(streamFile);
|
||||||
|
|
||||||
int i;
|
/* check extension (.xa: common, .str: sometimes used) */
|
||||||
|
if ( !check_extensions(streamFile,"xa,str") )
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("xa",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check RIFF Header */
|
|
||||||
if (!((read_32bitBE(0x00,streamFile) == 0x52494646) &&
|
|
||||||
(read_32bitBE(0x08,streamFile) == 0x43445841) &&
|
|
||||||
(read_32bitBE(0x0C,streamFile) == 0x666D7420)))
|
|
||||||
headerless=1;
|
|
||||||
|
|
||||||
/* don't misdetect Reflections' XA ("XA30" / "04SW") */
|
|
||||||
if (read_32bitBE(0x00,streamFile) == 0x58413330 || read_32bitBE(0x00,streamFile) == 0x30345357) goto fail;
|
|
||||||
/* don't misdetect Maxis XA ("XAI\0" / "XAJ\0") */
|
|
||||||
if (read_32bitBE(0x00,streamFile) == 0x58414900 || read_32bitBE(0x00,streamFile) == 0x58414A00) goto fail;
|
|
||||||
|
|
||||||
/* First init to have the correct info of the channel */
|
|
||||||
if (!headerless) {
|
|
||||||
start_offset=init_xa_channel(&xa_channel,streamFile);
|
|
||||||
|
|
||||||
/* No sound ? */
|
|
||||||
if(start_offset==0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
bCoding = read_8bit(start_offset-5,streamFile);
|
/* Proper XA comes in raw (BIN 2352 mode2/form2) CD sectors, that contain XA subheaders.
|
||||||
|
* This also has minimal support for headerless (ISO 2048 mode1/data) mode. */
|
||||||
|
|
||||||
switch (AUDIO_CODING_GET_STEREO(bCoding)) {
|
/* check RIFF header = raw (optional, added when ripping and not part of the CD data) */
|
||||||
|
if (read_32bitBE(0x00,streamFile) == 0x52494646 && /* "RIFF" */
|
||||||
|
read_32bitBE(0x08,streamFile) == 0x43445841 && /* "CDXA" */
|
||||||
|
read_32bitBE(0x0C,streamFile) == 0x666D7420) { /* "fmt " */
|
||||||
|
is_blocked = 1;
|
||||||
|
start_offset = 0x2c; /* after "data" (chunk size tends to be a bit off) */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* sector sync word = raw */
|
||||||
|
if (read_32bitBE(0x00,streamFile) == 0x00FFFFFF &&
|
||||||
|
read_32bitBE(0x04,streamFile) == 0xFFFFFFFF &&
|
||||||
|
read_32bitBE(0x08,streamFile) == 0xFFFFFF00) {
|
||||||
|
is_blocked = 1;
|
||||||
|
start_offset = 0x00;
|
||||||
|
}
|
||||||
|
else { /* headerless */
|
||||||
|
is_blocked = 0;
|
||||||
|
start_offset = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test first block (except when RIFF) */
|
||||||
|
if (start_offset == 0) {
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
/* 0x80 frames for 1 sector (max ~0x800 for ISO mode) */
|
||||||
|
for (i = 0; i < (0x800/0x80); i++) {
|
||||||
|
off_t test_offset = start_offset + (is_blocked ? 0x18 : 0x00) + 0x80*i;
|
||||||
|
|
||||||
|
/* ADPCM predictors should be 0..3 index */
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
uint8_t header = read_8bit(test_offset + i, streamFile);
|
||||||
|
if (((header >> 4) & 0xF) > 3)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* data is ok: parse header */
|
||||||
|
if (is_blocked) {
|
||||||
|
uint8_t xa_header;
|
||||||
|
|
||||||
|
/* parse 0x18 sector header (also see xa_blocked.c) */
|
||||||
|
xa_channel = read_8bit(start_offset + 0x11,streamFile);
|
||||||
|
xa_header = read_8bit(start_offset + 0x13,streamFile);
|
||||||
|
|
||||||
|
switch((xa_header >> 0) & 3) { /* 0..1: stereo */
|
||||||
case 0: channel_count = 1; break;
|
case 0: channel_count = 1; break;
|
||||||
case 1: channel_count = 2; break;
|
case 1: channel_count = 2; break;
|
||||||
default: channel_count = 0; break;
|
default: goto fail;
|
||||||
}
|
}
|
||||||
|
switch((xa_header >> 2) & 3) { /* 2..3: sample rate */
|
||||||
|
case 0: sample_rate = 37800; break;
|
||||||
|
case 1: sample_rate = 18900; break;
|
||||||
|
default: goto fail;
|
||||||
|
}
|
||||||
|
VGM_ASSERT(((xa_header >> 4) & 3) == 1, /* 4..5: bits per sample (0=4, 1=8) */
|
||||||
|
"XA: 8 bits per sample mode found\n"); /* spec only? */
|
||||||
|
/* 6: emphasis (applies a filter but apparently not used by games)
|
||||||
|
* XA is also filtered when resampled to 44100 during output, differently from PS-ADPCM */
|
||||||
|
/* 7: reserved */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* headerless, probably will go wrong */
|
||||||
|
channel_count = 2;
|
||||||
|
sample_rate = 44100; /* not 37800? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,0);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
vgmstream->sample_rate = sample_rate;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->num_samples = xa_bytes_to_samples(file_size - start_offset, channel_count, is_blocked);
|
||||||
|
vgmstream->xa_headerless = !is_blocked;
|
||||||
vgmstream->xa_channel = xa_channel;
|
vgmstream->xa_channel = xa_channel;
|
||||||
|
|
||||||
switch (AUDIO_CODING_GET_FREQ(bCoding)) {
|
|
||||||
case 0: vgmstream->sample_rate = 37800; break;
|
|
||||||
case 1: vgmstream->sample_rate = 18900; break;
|
|
||||||
default: vgmstream->sample_rate = 0; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for Compression Scheme */
|
|
||||||
vgmstream->num_samples = (int32_t)((((get_streamfile_size(streamFile) - 0x3C)/2352)*0x1F80)/(2*channel_count));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
channel_count=2;
|
|
||||||
vgmstream = allocate_vgmstream(2,0);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
vgmstream->xa_headerless=1;
|
|
||||||
vgmstream->sample_rate=44100;
|
|
||||||
vgmstream->channels=2;
|
|
||||||
vgmstream->num_samples = (int32_t)(((get_streamfile_size(streamFile)/ 0x80)*0xE0)/2);
|
|
||||||
start_offset=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_XA;
|
vgmstream->coding_type = coding_XA;
|
||||||
vgmstream->layout_type = layout_xa_blocked;
|
vgmstream->layout_type = layout_xa_blocked;
|
||||||
vgmstream->meta_type = meta_PSX_XA;
|
vgmstream->meta_type = meta_PSX_XA;
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
if (is_blocked)
|
||||||
{
|
start_offset += 0x18; /* move to first frame (hack for xa_blocked.c) */
|
||||||
STREAMFILE *chstreamfile;
|
|
||||||
chstreamfile = streamFile->open(streamFile,filename,2352);
|
|
||||||
|
|
||||||
if (!chstreamfile) goto fail;
|
/* open the file for reading */
|
||||||
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
for (i=0;i<channel_count;i++) {
|
goto fail;
|
||||||
vgmstream->ch[i].streamfile = chstreamfile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xa_block_update(start_offset,vgmstream);
|
xa_block_update(start_offset,vgmstream);
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t init_xa_channel(int* channel,STREAMFILE* streamFile) {
|
|
||||||
|
|
||||||
off_t block_offset=0x44;
|
|
||||||
size_t filelength=get_streamfile_size(streamFile);
|
|
||||||
|
|
||||||
int8_t currentChannel;
|
|
||||||
|
|
||||||
// 0 can't be a correct value
|
|
||||||
if(block_offset>=(off_t)filelength)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
currentChannel=read_8bit(block_offset-7,streamFile);
|
|
||||||
//subAudio=read_8bit(block_offset-6,streamFile);
|
|
||||||
*channel=currentChannel;
|
|
||||||
//if (!((currentChannel==channel) && (subAudio==0x64))) {
|
|
||||||
// block_offset+=2352;
|
|
||||||
// goto begin;
|
|
||||||
//}
|
|
||||||
return block_offset;
|
|
||||||
}
|
|
||||||
|
@ -245,7 +245,7 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
|||||||
coding_type = coding_NGC_DSP;
|
coding_type = coding_NGC_DSP;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
coding_type = coding_IMA;
|
coding_type = coding_3DS_IMA;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -343,7 +343,7 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_IMA) {
|
if (vgmstream->coding_type == coding_3DS_IMA) {
|
||||||
vgmstream->ch[j].adpcm_history1_16 = read_16bit(codec_info_offset,streamFile);
|
vgmstream->ch[j].adpcm_history1_16 = read_16bit(codec_info_offset,streamFile);
|
||||||
vgmstream->ch[j].adpcm_step_index = read_16bit(codec_info_offset+2,streamFile);
|
vgmstream->ch[j].adpcm_step_index = read_16bit(codec_info_offset+2,streamFile);
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,54 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* DVI (Castlevania Symphony of the Night) */
|
/* DVI - from Konami KCE Nayoga SAT games (Castlevania Symphony of the Night, Jikkyou Oshaberi Parodius - Forever with Me) */
|
||||||
VGMSTREAM * init_vgmstream_dvi(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_sat_dvi(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
|
||||||
int loop_flag = 0;
|
/* check extension (.pcm: original, .dvi: renamed to header id) */
|
||||||
int channel_count;
|
if ( !check_extensions(streamFile,"pcm,dvi") )
|
||||||
|
goto fail;
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("dvi",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x4456492E) /* "DVI." */
|
if (read_32bitBE(0x00,streamFile) != 0x4456492E) /* "DVI." */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (read_32bitBE(0x0C,streamFile)!=0xFFFFFFFF);
|
start_offset = read_32bitBE(0x04,streamFile);
|
||||||
channel_count = 2;
|
loop_flag = (read_32bitBE(0x0C,streamFile) != 0xFFFFFFFF);
|
||||||
|
channel_count = 2; /* no mono files seem to exists */
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
start_offset = read_32bitBE(0x04,streamFile);
|
|
||||||
vgmstream->sample_rate = 44100;
|
vgmstream->sample_rate = 44100;
|
||||||
vgmstream->coding_type = coding_DVI_IMA_int;
|
|
||||||
|
|
||||||
vgmstream->num_samples = read_32bitBE(0x08,streamFile);
|
vgmstream->num_samples = read_32bitBE(0x08,streamFile);
|
||||||
|
|
||||||
if (loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x0C,streamFile);
|
vgmstream->loop_start_sample = read_32bitBE(0x0C,streamFile);
|
||||||
vgmstream->loop_end_sample = read_32bitBE(0x08,streamFile);
|
vgmstream->loop_end_sample = read_32bitBE(0x08,streamFile);
|
||||||
}
|
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_DVI_IMA_int;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 4;
|
vgmstream->interleave_block_size = 0x4;
|
||||||
vgmstream->meta_type = meta_DVI;
|
vgmstream->meta_type = meta_SAT_DVI;
|
||||||
vgmstream->get_high_nibble=1;
|
|
||||||
|
|
||||||
|
/* at 0x10 (L) / 0x20 (R): probably ADPCM loop history @+0x00 and step @+0x17 (not init values) */
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
/* for some reason right channel goes first (tested in SOTN vs emu and PS/OST version), swap offsets */
|
||||||
if (!file) goto fail;
|
if (channel_count == 2) {
|
||||||
for (i=0;i<channel_count;i++) {
|
off_t temp = vgmstream->ch[0].offset;
|
||||||
vgmstream->ch[i].streamfile = file;
|
vgmstream->ch[0].channel_start_offset =
|
||||||
vgmstream->ch[i].channel_start_offset=
|
vgmstream->ch[0].offset = vgmstream->ch[1].offset;
|
||||||
vgmstream->ch[i].offset=start_offset+(i*vgmstream->interleave_block_size);
|
vgmstream->ch[1].channel_start_offset =
|
||||||
vgmstream->ch[i].adpcm_history1_32=0;
|
vgmstream->ch[1].offset = temp;
|
||||||
vgmstream->ch[i].adpcm_step_index=0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
63
src/meta/scd_pcm.c
Normal file
63
src/meta/scd_pcm.c
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#include "meta.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
/* PCM (from Lunar: Eternal Blue (Sega CD) */
|
||||||
|
VGMSTREAM * init_vgmstream_scd_pcm(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
off_t start_offset;
|
||||||
|
|
||||||
|
int loop_flag;
|
||||||
|
int channel_count;
|
||||||
|
|
||||||
|
/* check extension, case insensitive */
|
||||||
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
|
if (strcasecmp("pcm",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
|
/* check header */
|
||||||
|
if (read_32bitBE(0x0,streamFile) != 0x00020000)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
loop_flag = (read_32bitLE(0x02,streamFile)!=0);
|
||||||
|
channel_count = 1;
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
/* fill in the vital statistics */
|
||||||
|
start_offset = 0x200;
|
||||||
|
vgmstream->channels = channel_count;
|
||||||
|
vgmstream->sample_rate = 32000;
|
||||||
|
vgmstream->coding_type = coding_PCM8_SB_int;
|
||||||
|
vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2;
|
||||||
|
if(loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*0x400*2;
|
||||||
|
vgmstream->loop_end_sample = read_32bitBE(0x06,streamFile)*2;
|
||||||
|
}
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = 0x1;
|
||||||
|
vgmstream->meta_type = meta_SCD_PCM;
|
||||||
|
|
||||||
|
/* open the file for reading */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
STREAMFILE * file;
|
||||||
|
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
if (!file) goto fail;
|
||||||
|
for (i=0;i<channel_count;i++) {
|
||||||
|
vgmstream->ch[i].streamfile = file;
|
||||||
|
vgmstream->ch[i].channel_start_offset=
|
||||||
|
vgmstream->ch[i].offset=start_offset+
|
||||||
|
vgmstream->interleave_block_size*i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
/* clean up anything we may have opened */
|
||||||
|
fail:
|
||||||
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -1,58 +1,43 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
/* TUN (from LEGO Racers (PC)) */
|
/* ALP - from LEGO Racers (PC) */
|
||||||
VGMSTREAM * init_vgmstream_tun(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_tun(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int channel_count;
|
int loop_flag, channel_count;
|
||||||
int loop_flag;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if ( !check_extensions(streamFile,"tun") )
|
||||||
if (strcasecmp("tun",filename_extension(filename))) goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x414C5020) /* "ALP " */
|
if (read_32bitBE(0x00,streamFile) != 0x414C5020) /* "ALP " */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
channel_count = 2;
|
channel_count = 2; /* probably at 0x0F */
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
|
start_offset = 0x10;
|
||||||
|
/* also "ADPCM" at 0x08 */
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
start_offset = 0x10;
|
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->sample_rate = 22050;
|
vgmstream->sample_rate = 22050;
|
||||||
vgmstream->coding_type = coding_DVI_IMA;
|
vgmstream->num_samples = ima_bytes_to_samples(get_streamfile_size(streamFile) - 0x10, channel_count);
|
||||||
vgmstream->num_samples = (get_streamfile_size(streamFile)) - 0x10;
|
|
||||||
|
vgmstream->coding_type = coding_DVI_IMA_int;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 1;
|
vgmstream->interleave_block_size = 0x01;
|
||||||
vgmstream->meta_type = meta_TUN;
|
vgmstream->meta_type = meta_TUN;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
STREAMFILE * file;
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = file;
|
|
||||||
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
|
||||||
vgmstream->ch[i].offset=start_offset+
|
|
||||||
vgmstream->interleave_block_size*i;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -55,7 +55,7 @@ VGMSTREAM * init_vgmstream_ws_aud(STREAMFILE *streamFile) {
|
|||||||
if (bytes_per_sample != 1) goto fail;
|
if (bytes_per_sample != 1) goto fail;
|
||||||
break;
|
break;
|
||||||
case 99: /* IMA ADPCM */
|
case 99: /* IMA ADPCM */
|
||||||
coding_type = coding_IMA;
|
coding_type = coding_IMA_int;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -36,7 +36,7 @@ VGMSTREAM * init_vgmstream_x360_tra(STREAMFILE *streamFile) {
|
|||||||
vgmstream->channels = 2;
|
vgmstream->channels = 2;
|
||||||
vgmstream->sample_rate = 24000;
|
vgmstream->sample_rate = 24000;
|
||||||
|
|
||||||
vgmstream->coding_type = coding_DVI_IMA;
|
vgmstream->coding_type = coding_DVI_IMA_int;
|
||||||
vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile) - ((get_streamfile_size(streamFile)/0x204)*4));
|
vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile) - ((get_streamfile_size(streamFile)/0x204)*4));
|
||||||
vgmstream->layout_type = layout_tra_blocked;
|
vgmstream->layout_type = layout_tra_blocked;
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
|||||||
init_vgmstream_rifx,
|
init_vgmstream_rifx,
|
||||||
init_vgmstream_pos,
|
init_vgmstream_pos,
|
||||||
init_vgmstream_nwa,
|
init_vgmstream_nwa,
|
||||||
init_vgmstream_eacs,
|
init_vgmstream_ea_1snh,
|
||||||
init_vgmstream_xss,
|
init_vgmstream_xss,
|
||||||
init_vgmstream_sl3,
|
init_vgmstream_sl3,
|
||||||
init_vgmstream_hgc1,
|
init_vgmstream_hgc1,
|
||||||
@ -113,16 +113,16 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
|||||||
init_vgmstream_ikm,
|
init_vgmstream_ikm,
|
||||||
init_vgmstream_sfs,
|
init_vgmstream_sfs,
|
||||||
init_vgmstream_bg00,
|
init_vgmstream_bg00,
|
||||||
init_vgmstream_dvi,
|
init_vgmstream_sat_dvi,
|
||||||
init_vgmstream_kcey,
|
init_vgmstream_dc_kcey,
|
||||||
init_vgmstream_ps2_rstm,
|
init_vgmstream_ps2_rstm,
|
||||||
init_vgmstream_acm,
|
init_vgmstream_acm,
|
||||||
init_vgmstream_mus_acm,
|
init_vgmstream_mus_acm,
|
||||||
init_vgmstream_ps2_kces,
|
init_vgmstream_ps2_kces,
|
||||||
init_vgmstream_ps2_dxh,
|
init_vgmstream_ps2_dxh,
|
||||||
init_vgmstream_ps2_psh,
|
init_vgmstream_ps2_psh,
|
||||||
init_vgmstream_pcm_scd,
|
init_vgmstream_scd_pcm,
|
||||||
init_vgmstream_pcm_ps2,
|
init_vgmstream_ps2_pcm,
|
||||||
init_vgmstream_ps2_rkv,
|
init_vgmstream_ps2_rkv,
|
||||||
init_vgmstream_ps2_psw,
|
init_vgmstream_ps2_psw,
|
||||||
init_vgmstream_ps2_vas,
|
init_vgmstream_ps2_vas,
|
||||||
@ -914,7 +914,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
|||||||
case layout_halpst_blocked:
|
case layout_halpst_blocked:
|
||||||
case layout_xa_blocked:
|
case layout_xa_blocked:
|
||||||
case layout_ea_blocked:
|
case layout_ea_blocked:
|
||||||
case layout_eacs_blocked:
|
case layout_blocked_ea_1snh:
|
||||||
case layout_caf_blocked:
|
case layout_caf_blocked:
|
||||||
case layout_wsi_blocked:
|
case layout_wsi_blocked:
|
||||||
case layout_str_snds_blocked:
|
case layout_str_snds_blocked:
|
||||||
@ -1018,15 +1018,15 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
|||||||
case coding_NGC_DTK:
|
case coding_NGC_DTK:
|
||||||
return 28;
|
return 28;
|
||||||
case coding_G721:
|
case coding_G721:
|
||||||
case coding_DVI_IMA:
|
|
||||||
case coding_EACS_IMA:
|
|
||||||
case coding_SNDS_IMA:
|
|
||||||
case coding_IMA:
|
case coding_IMA:
|
||||||
|
case coding_DVI_IMA:
|
||||||
|
case coding_SNDS_IMA:
|
||||||
case coding_OTNS_IMA:
|
case coding_OTNS_IMA:
|
||||||
case coding_UBI_IMA:
|
case coding_UBI_IMA:
|
||||||
return 1;
|
return 1;
|
||||||
case coding_IMA_int:
|
case coding_IMA_int:
|
||||||
case coding_DVI_IMA_int:
|
case coding_DVI_IMA_int:
|
||||||
|
case coding_3DS_IMA:
|
||||||
case coding_AICA:
|
case coding_AICA:
|
||||||
return 2;
|
return 2;
|
||||||
case coding_NGC_AFC:
|
case coding_NGC_AFC:
|
||||||
@ -1175,10 +1175,6 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
|||||||
return 0x14;
|
return 0x14;
|
||||||
case coding_NGC_DTK:
|
case coding_NGC_DTK:
|
||||||
return 32;
|
return 32;
|
||||||
case coding_EACS_IMA:
|
|
||||||
return 1;
|
|
||||||
case coding_DVI_IMA:
|
|
||||||
case coding_IMA:
|
|
||||||
case coding_G721:
|
case coding_G721:
|
||||||
case coding_SNDS_IMA:
|
case coding_SNDS_IMA:
|
||||||
case coding_OTNS_IMA:
|
case coding_OTNS_IMA:
|
||||||
@ -1212,8 +1208,12 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
|||||||
return 0x4c*vgmstream->channels;
|
return 0x4c*vgmstream->channels;
|
||||||
case coding_WS:
|
case coding_WS:
|
||||||
return vgmstream->current_block_size;
|
return vgmstream->current_block_size;
|
||||||
|
case coding_IMA:
|
||||||
case coding_IMA_int:
|
case coding_IMA_int:
|
||||||
|
case coding_DVI_IMA:
|
||||||
case coding_DVI_IMA_int:
|
case coding_DVI_IMA_int:
|
||||||
|
case coding_3DS_IMA:
|
||||||
|
return 0x01;
|
||||||
case coding_AICA:
|
case coding_AICA:
|
||||||
return 1;
|
return 1;
|
||||||
case coding_APPLE_IMA4:
|
case coding_APPLE_IMA4:
|
||||||
@ -1611,25 +1611,23 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
|||||||
samples_to_do);
|
samples_to_do);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case coding_IMA:
|
||||||
|
case coding_IMA_int:
|
||||||
case coding_DVI_IMA:
|
case coding_DVI_IMA:
|
||||||
case coding_DVI_IMA_int:
|
case coding_DVI_IMA_int:
|
||||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||||
decode_dvi_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
int is_stereo = (vgmstream->channels > 1 && vgmstream->coding_type == coding_IMA)
|
||||||
|
|| (vgmstream->channels > 1 && vgmstream->coding_type == coding_DVI_IMA);
|
||||||
|
int is_high_first = vgmstream->coding_type == coding_DVI_IMA || vgmstream->coding_type == coding_DVI_IMA_int;
|
||||||
|
|
||||||
|
decode_standard_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||||
vgmstream->channels,vgmstream->samples_into_block,
|
vgmstream->channels,vgmstream->samples_into_block,
|
||||||
samples_to_do);
|
samples_to_do, chan, is_stereo, is_high_first);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case coding_EACS_IMA:
|
case coding_3DS_IMA:
|
||||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||||
decode_eacs_ima(vgmstream,buffer+samples_written*vgmstream->channels+chan,
|
decode_3ds_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||||
vgmstream->channels,vgmstream->samples_into_block,
|
|
||||||
samples_to_do,chan);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case coding_IMA:
|
|
||||||
case coding_IMA_int:
|
|
||||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
||||||
decode_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
||||||
vgmstream->channels,vgmstream->samples_into_block,
|
vgmstream->channels,vgmstream->samples_into_block,
|
||||||
samples_to_do);
|
samples_to_do);
|
||||||
}
|
}
|
||||||
@ -1889,7 +1887,6 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
|
|||||||
if (vgmstream->meta_type == meta_DSP_STD ||
|
if (vgmstream->meta_type == meta_DSP_STD ||
|
||||||
vgmstream->meta_type == meta_DSP_RS03 ||
|
vgmstream->meta_type == meta_DSP_RS03 ||
|
||||||
vgmstream->meta_type == meta_DSP_CSTR ||
|
vgmstream->meta_type == meta_DSP_CSTR ||
|
||||||
vgmstream->meta_type == meta_NDS_STRM_FFTA2 || /* clicks in some files otherwise */
|
|
||||||
vgmstream->coding_type == coding_PSX ||
|
vgmstream->coding_type == coding_PSX ||
|
||||||
vgmstream->coding_type == coding_PSX_bmdx ||
|
vgmstream->coding_type == coding_PSX_bmdx ||
|
||||||
vgmstream->coding_type == coding_PSX_badflags) {
|
vgmstream->coding_type == coding_PSX_badflags) {
|
||||||
|
@ -75,15 +75,15 @@ enum { STREAM_NAME_SIZE = 255 }; /* reasonable max */
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/* PCM */
|
/* PCM */
|
||||||
coding_PCM16LE, /* little endian 16-bit PCM */
|
coding_PCM16LE, /* little endian 16-bit PCM */
|
||||||
coding_PCM16LE_XOR_int, /* little endian 16-bit PCM with sample-level xor */
|
coding_PCM16LE_XOR_int, /* little endian 16-bit PCM with sample-level xor (for blocks) */
|
||||||
coding_PCM16BE, /* big endian 16-bit PCM */
|
coding_PCM16BE, /* big endian 16-bit PCM */
|
||||||
coding_PCM16_int, /* 16-bit PCM with sample-level interleave */
|
coding_PCM16_int, /* 16-bit PCM with sample-level interleave (for blocks) */
|
||||||
|
|
||||||
coding_PCM8, /* 8-bit PCM */
|
coding_PCM8, /* 8-bit PCM */
|
||||||
coding_PCM8_int, /* 8-Bit PCM with sample-level interleave */
|
coding_PCM8_int, /* 8-Bit PCM with sample-level interleave (for blocks) */
|
||||||
coding_PCM8_U, /* 8-bit PCM, unsigned (0x80 = 0) */
|
coding_PCM8_U, /* 8-bit PCM, unsigned (0x80 = 0) */
|
||||||
coding_PCM8_U_int, /* 8-bit PCM, unsigned (0x80 = 0) with sample-level interleave */
|
coding_PCM8_U_int, /* 8-bit PCM, unsigned (0x80 = 0) with sample-level interleave (for blocks) */
|
||||||
coding_PCM8_SB_int, /* 8-bit PCM, sign bit (others are 2's complement) with sample-level interleave */
|
coding_PCM8_SB_int, /* 8-bit PCM, sign bit (others are 2's complement) with sample-level interleave (for blocks) */
|
||||||
|
|
||||||
coding_ULAW, /* 8-bit u-Law (non-linear PCM) */
|
coding_ULAW, /* 8-bit u-Law (non-linear PCM) */
|
||||||
coding_ALAW, /* 8-bit a-Law (non-linear PCM) */
|
coding_ALAW, /* 8-bit a-Law (non-linear PCM) */
|
||||||
@ -116,19 +116,19 @@ typedef enum {
|
|||||||
coding_MAXIS_XA, /* Maxis EA-XA ADPCM */
|
coding_MAXIS_XA, /* Maxis EA-XA ADPCM */
|
||||||
coding_EA_XAS, /* Electronic Arts EA-XAS ADPCM */
|
coding_EA_XAS, /* Electronic Arts EA-XAS ADPCM */
|
||||||
|
|
||||||
|
coding_IMA, /* IMA ADPCM (stereo or mono, low nibble first) */
|
||||||
|
coding_IMA_int, /* IMA ADPCM (mono/interleave, low nibble first) */
|
||||||
|
coding_DVI_IMA, /* DVI IMA ADPCM (stereo or mono, high nibble first) */
|
||||||
|
coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */
|
||||||
|
coding_3DS_IMA, /* 3DS IMA ADPCM */
|
||||||
|
coding_MS_IMA, /* Microsoft IMA ADPCM */
|
||||||
coding_XBOX, /* XBOX IMA ADPCM */
|
coding_XBOX, /* XBOX IMA ADPCM */
|
||||||
coding_XBOX_int, /* XBOX IMA ADPCM (interleaved) */
|
coding_XBOX_int, /* XBOX IMA ADPCM (interleaved) */
|
||||||
coding_IMA, /* IMA ADPCM (low nibble first) */
|
|
||||||
coding_IMA_int, /* IMA ADPCM (interleaved) */
|
|
||||||
coding_DVI_IMA, /* DVI IMA ADPCM (high nibble first), aka ADP4 */
|
|
||||||
coding_DVI_IMA_int, /* DVI IMA ADPCM (Interleaved) */
|
|
||||||
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
||||||
coding_EACS_IMA, /* Electronic Arts IMA ADPCM */
|
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
|
||||||
coding_MS_IMA, /* Microsoft IMA ADPCM */
|
|
||||||
coding_RAD_IMA, /* Radical IMA ADPCM */
|
coding_RAD_IMA, /* Radical IMA ADPCM */
|
||||||
coding_RAD_IMA_mono, /* Radical IMA ADPCM, mono (for interleave) */
|
coding_RAD_IMA_mono, /* Radical IMA ADPCM, mono (for interleave) */
|
||||||
coding_APPLE_IMA4, /* Apple Quicktime IMA4 */
|
coding_APPLE_IMA4, /* Apple Quicktime IMA4 */
|
||||||
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
|
|
||||||
coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */
|
coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */
|
||||||
coding_OTNS_IMA, /* Omikron The Nomad Soul IMA ADPCM */
|
coding_OTNS_IMA, /* Omikron The Nomad Soul IMA ADPCM */
|
||||||
coding_FSB_IMA, /* FMOD's FSB multichannel IMA ADPCM */
|
coding_FSB_IMA, /* FMOD's FSB multichannel IMA ADPCM */
|
||||||
@ -153,9 +153,7 @@ typedef enum {
|
|||||||
coding_SDX2_int, /* SDX2 2:1 Squareroot-Delta-Exact compression with sample-level interleave */
|
coding_SDX2_int, /* SDX2 2:1 Squareroot-Delta-Exact compression with sample-level interleave */
|
||||||
coding_CBD2, /* CBD2 2:1 Cuberoot-Delta-Exact compression DPCM */
|
coding_CBD2, /* CBD2 2:1 Cuberoot-Delta-Exact compression DPCM */
|
||||||
coding_CBD2_int, /* CBD2 2:1 Cuberoot-Delta-Exact compression, with sample-level interleave */
|
coding_CBD2_int, /* CBD2 2:1 Cuberoot-Delta-Exact compression, with sample-level interleave */
|
||||||
|
|
||||||
coding_ACM, /* InterPlay ACM */
|
coding_ACM, /* InterPlay ACM */
|
||||||
|
|
||||||
coding_NWA0, /* Visual Art's NWA (compressed at various levels) */
|
coding_NWA0, /* Visual Art's NWA (compressed at various levels) */
|
||||||
coding_NWA1,
|
coding_NWA1,
|
||||||
coding_NWA2,
|
coding_NWA2,
|
||||||
@ -215,7 +213,7 @@ typedef enum {
|
|||||||
layout_halpst_blocked,
|
layout_halpst_blocked,
|
||||||
layout_xa_blocked,
|
layout_xa_blocked,
|
||||||
layout_ea_blocked,
|
layout_ea_blocked,
|
||||||
layout_eacs_blocked,
|
layout_blocked_ea_1snh,
|
||||||
layout_caf_blocked,
|
layout_caf_blocked,
|
||||||
layout_wsi_blocked,
|
layout_wsi_blocked,
|
||||||
layout_str_snds_blocked,
|
layout_str_snds_blocked,
|
||||||
@ -317,7 +315,7 @@ typedef enum {
|
|||||||
meta_HIS, /* Her Ineractive .his */
|
meta_HIS, /* Her Ineractive .his */
|
||||||
meta_BNSF, /* Bandai Namco Sound Format */
|
meta_BNSF, /* Bandai Namco Sound Format */
|
||||||
|
|
||||||
meta_PSX_XA, /* CD-ROM XA with RIFF header */
|
meta_PSX_XA, /* CD-ROM XA */
|
||||||
meta_PS2_SShd, /* .ADS with SShd header */
|
meta_PS2_SShd, /* .ADS with SShd header */
|
||||||
meta_PS2_NPSF, /* Namco Production Sound File */
|
meta_PS2_NPSF, /* Namco Production Sound File */
|
||||||
meta_PS2_RXWS, /* Sony games (Genji, Okage Shadow King, Arc The Lad Twilight of Spirits) */
|
meta_PS2_RXWS, /* Sony games (Genji, Okage Shadow King, Arc The Lad Twilight of Spirits) */
|
||||||
@ -369,8 +367,8 @@ typedef enum {
|
|||||||
meta_PS2_KCES, /* Dance Dance Revolution */
|
meta_PS2_KCES, /* Dance Dance Revolution */
|
||||||
meta_PS2_DXH, /* Tokobot Plus - Myteries of the Karakuri */
|
meta_PS2_DXH, /* Tokobot Plus - Myteries of the Karakuri */
|
||||||
meta_PS2_PSH, /* Dawn of Mana - Seiken Densetsu 4 */
|
meta_PS2_PSH, /* Dawn of Mana - Seiken Densetsu 4 */
|
||||||
meta_PCM_SCD, /* Lunar - Eternal Blue */
|
meta_SCD_PCM, /* Lunar - Eternal Blue */
|
||||||
meta_PCM_PS2, /* Konami: Ephemeral Fantasia, Yu-Gi-Oh! The Duelists of the Roses */
|
meta_PS2_PCM, /* Konami KCEJ East: Ephemeral Fantasia, Yu-Gi-Oh! The Duelists of the Roses, 7 Blades */
|
||||||
meta_PS2_RKV, /* Legacy of Kain - Blood Omen 2 */
|
meta_PS2_RKV, /* Legacy of Kain - Blood Omen 2 */
|
||||||
meta_PS2_PSW, /* Rayman Raving Rabbids */
|
meta_PS2_PSW, /* Rayman Raving Rabbids */
|
||||||
meta_PS2_VAS, /* Pro Baseball Spirits 5 */
|
meta_PS2_VAS, /* Pro Baseball Spirits 5 */
|
||||||
@ -460,9 +458,7 @@ typedef enum {
|
|||||||
meta_EA_SCHL, /* Electronic Arts SCHl with variable header */
|
meta_EA_SCHL, /* Electronic Arts SCHl with variable header */
|
||||||
meta_EA_SCHL_fixed, /* Electronic Arts SCHl with fixed header */
|
meta_EA_SCHL_fixed, /* Electronic Arts SCHl with fixed header */
|
||||||
meta_EA_BNK, /* Electronic Arts BNK */
|
meta_EA_BNK, /* Electronic Arts BNK */
|
||||||
meta_EACS_PC, /* Electronic Arts EACS PC */
|
meta_EA_1SNH, /* Electronic Arts 1SNh/EACS */
|
||||||
meta_EACS_PSX, /* Electronic Arts EACS PSX */
|
|
||||||
meta_EACS_SAT, /* Electronic Arts EACS SATURN */
|
|
||||||
|
|
||||||
meta_RAW, /* RAW PCM file */
|
meta_RAW, /* RAW PCM file */
|
||||||
|
|
||||||
@ -487,8 +483,8 @@ typedef enum {
|
|||||||
meta_NWA, /* Visual Art's NWA */
|
meta_NWA, /* Visual Art's NWA */
|
||||||
meta_NWA_NWAINFOINI, /* Visual Art's NWA w/ NWAINFO.INI for looping */
|
meta_NWA_NWAINFOINI, /* Visual Art's NWA w/ NWAINFO.INI for looping */
|
||||||
meta_NWA_GAMEEXEINI, /* Visual Art's NWA w/ Gameexe.ini for looping */
|
meta_NWA_GAMEEXEINI, /* Visual Art's NWA w/ Gameexe.ini for looping */
|
||||||
meta_DVI, /* DVI Interleaved */
|
meta_SAT_DVI, /* Konami KCE Nagoya DVI (SAT games) */
|
||||||
meta_KCEY, /* KCEYCOMP */
|
meta_DC_KCEY, /* Konami KCE Yokohama KCEYCOMP (DC games) */
|
||||||
meta_ACM, /* InterPlay ACM header */
|
meta_ACM, /* InterPlay ACM header */
|
||||||
meta_MUS_ACM, /* MUS playlist of InterPlay ACM files */
|
meta_MUS_ACM, /* MUS playlist of InterPlay ACM files */
|
||||||
meta_DE2, /* Falcom (Gurumin) .de2 */
|
meta_DE2, /* Falcom (Gurumin) .de2 */
|
||||||
@ -715,10 +711,10 @@ typedef struct {
|
|||||||
layout_t layout_type; /* type of layout for data */
|
layout_t layout_type; /* type of layout for data */
|
||||||
meta_t meta_type; /* how we know the metadata */
|
meta_t meta_type; /* how we know the metadata */
|
||||||
|
|
||||||
/* streams (info only) */
|
/* subsongs */
|
||||||
int num_streams; /* for multi-stream formats (0=not set/one, 1=one stream) */
|
int num_streams; /* for multi-stream formats (0=not set/one stream, 1=one stream) */
|
||||||
int stream_index; /* current stream */
|
int stream_index; /* selected stream (also 1-based) */
|
||||||
char stream_name[STREAM_NAME_SIZE]; /* name of the current stream, if the file stores it and it's filled */
|
char stream_name[STREAM_NAME_SIZE]; /* name of the current stream (info), if the file stores it and it's filled */
|
||||||
|
|
||||||
/* looping */
|
/* looping */
|
||||||
int loop_flag; /* is this stream looped? */
|
int loop_flag; /* is this stream looped? */
|
||||||
@ -766,12 +762,8 @@ typedef struct {
|
|||||||
|
|
||||||
uint8_t xa_channel; /* XA ADPCM: selected channel */
|
uint8_t xa_channel; /* XA ADPCM: selected channel */
|
||||||
int32_t xa_sector_length; /* XA ADPCM: XA block */
|
int32_t xa_sector_length; /* XA ADPCM: XA block */
|
||||||
uint8_t xa_headerless; /* XA ADPCM: headerless XA block */
|
uint8_t xa_headerless; /* XA ADPCM: headerless XA */
|
||||||
|
int8_t xa_get_high_nibble; /* XA ADPCM: mono/stereo nibble selection (XA state could be simplified) */
|
||||||
int8_t get_high_nibble; /* ADPCM: which nibble (XA, IMA, EA) */
|
|
||||||
|
|
||||||
uint8_t ea_big_endian; /* EA ADPCM stuff */
|
|
||||||
uint8_t ea_platform;
|
|
||||||
|
|
||||||
int32_t ws_output_size; /* WS ADPCM: output bytes for this block */
|
int32_t ws_output_size; /* WS ADPCM: output bytes for this block */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user