mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 19:19:16 +01:00
Procyon Studio Digital Sound Elements NDS ADPCM (as seen in .sad) decoder added
extended .sad support git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@541 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
3e63969795
commit
a9ee80dc59
@ -189,7 +189,7 @@ multi:
|
||||
- .rwar (GC DSP ADPCM, 8/16 bit PCM)
|
||||
- .rwsd (GC DSP ADPCM, 8/16 bit PCM)
|
||||
- .rsd (PSX ADPCM, 16 bit PCM, GC DSP ADPCM, Xbox IMA ADPCM)
|
||||
- .sad (GC DSP ADPCM, NDS IMA ADPCM)
|
||||
- .sad (GC DSP ADPCM, NDS IMA ADPCM, Procyon Studios NDS ADPCM)
|
||||
- .sng, .asf, .str, .eam (EA/XA ADPCM or PSX ADPCM)
|
||||
- .strm (STRM: NDS IMA ADPCM, 8/16 bit PCM)
|
||||
- .ss7 (EACS IMA ADPCM, IMA ADPCM)
|
||||
|
@ -15,7 +15,8 @@ CODING_OBJS=coding/adx_decoder.o \
|
||||
coding/acm_decoder.o \
|
||||
coding/nwa_decoder.o \
|
||||
coding/msadpcm_decoder.o \
|
||||
coding/aica_decoder.o
|
||||
coding/aica_decoder.o \
|
||||
coding/nds_procyon_decoder.o
|
||||
|
||||
LAYOUT_OBJS=layout/ast_blocked.o \
|
||||
layout/blocked.o \
|
||||
|
@ -23,5 +23,6 @@ libcoding_la_SOURCES += acm_decoder.c
|
||||
libcoding_la_SOURCES += nwa_decoder.c
|
||||
libcoding_la_SOURCES += aica_decoder.c
|
||||
libcoding_la_SOURCES += msadpcm_decoder.c
|
||||
libcoding_la_SOURCES += nds_procyon_decoder.c
|
||||
|
||||
EXTRA_DIST = coding.h g72x_state.h
|
||||
|
@ -76,4 +76,6 @@ void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first
|
||||
|
||||
void decode_aica(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
void decode_nds_procyon(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
#endif
|
||||
|
60
src/coding/nds_procyon_decoder.c
Normal file
60
src/coding/nds_procyon_decoder.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* ADPCM found in NDS games using Procyon Studio Digital Sound Elements */
|
||||
|
||||
static const int8_t proc_coef[5][2] =
|
||||
{
|
||||
{0x00,0x00},
|
||||
{0x3C,0x00},
|
||||
{0x73,0xCC},
|
||||
{0x62,0xC9},
|
||||
{0x7A,0xC4},
|
||||
};
|
||||
|
||||
void decode_nds_procyon(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i=first_sample;
|
||||
int32_t sample_count;
|
||||
|
||||
int framesin = first_sample/30;
|
||||
|
||||
uint8_t header = read_8bit(framesin*16+15+stream->offset,stream->streamfile) ^ 0x80;
|
||||
int scale = 12 - (header & 0xf);
|
||||
int coef_index = (header >> 4) & 0xf;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int32_t hist2 = stream->adpcm_history2_32;
|
||||
int32_t coef1;
|
||||
int32_t coef2;
|
||||
|
||||
if (coef_index > 4) coef_index = 0;
|
||||
coef1 = proc_coef[coef_index][0];
|
||||
coef2 = proc_coef[coef_index][1];
|
||||
first_sample = first_sample%30;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int sample_byte = read_8bit(framesin*16+stream->offset+i/2,stream->streamfile) ^ 0x80;
|
||||
|
||||
int32_t sample =
|
||||
(int32_t)
|
||||
(i&1?
|
||||
get_high_nibble_signed(sample_byte):
|
||||
get_low_nibble_signed(sample_byte)
|
||||
) * 64 * 64;
|
||||
if (scale < 0)
|
||||
{
|
||||
sample <<= -scale;
|
||||
}
|
||||
else
|
||||
sample >>= scale;
|
||||
|
||||
sample = (hist1 * coef1 + hist2 * coef2 + 32) / 64 + (sample * 64);
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = sample;
|
||||
|
||||
outbuf[sample_count] = clamp16((sample + 32) / 64) / 64 * 64;
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_history2_32 = hist2;
|
||||
}
|
@ -794,6 +794,9 @@
|
||||
RelativePath=".\coding\msadpcm_decoder.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\coding\nds_procyon_decoder.c"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\coding\ngc_afc_decoder.c"
|
||||
>
|
||||
|
@ -9,6 +9,7 @@ VGMSTREAM * init_vgmstream_sadl(STREAMFILE *streamFile) {
|
||||
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
int coding_type;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
@ -22,12 +23,21 @@ VGMSTREAM * init_vgmstream_sadl(STREAMFILE *streamFile) {
|
||||
if (read_32bitLE(0x40,streamFile) != get_streamfile_size(streamFile) )
|
||||
goto fail;
|
||||
|
||||
/* check for the simple IMA type that we can handle */
|
||||
if (read_8bit(0xc,streamFile) != 0x11)
|
||||
goto fail;
|
||||
/* check coding type */
|
||||
switch (read_8bit(0x33,streamFile)&0xf0)
|
||||
{
|
||||
case 0x70:
|
||||
coding_type = coding_INT_IMA;
|
||||
break;
|
||||
case 0xb0:
|
||||
coding_type = coding_NDS_PROCYON;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
loop_flag = read_8bit(0x31,streamFile);
|
||||
channel_count = read_8bit(0x32,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
@ -36,12 +46,43 @@ VGMSTREAM * init_vgmstream_sadl(STREAMFILE *streamFile) {
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x100;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 16364;
|
||||
vgmstream->coding_type = coding_INT_IMA;
|
||||
vgmstream->num_samples = read_32bitLE(0x50,streamFile);;
|
||||
|
||||
switch (read_8bit(0x33,streamFile) & 6)
|
||||
{
|
||||
case 4:
|
||||
vgmstream->sample_rate = 32728;
|
||||
break;
|
||||
case 2:
|
||||
vgmstream->sample_rate = 16364;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->coding_type = coding_type;
|
||||
|
||||
if (coding_type == coding_INT_IMA)
|
||||
vgmstream->num_samples =
|
||||
(read_32bitLE(0x40,streamFile)-start_offset)/channel_count*2;
|
||||
else if (coding_type == coding_NDS_PROCYON)
|
||||
vgmstream->num_samples =
|
||||
(read_32bitLE(0x40,streamFile)-start_offset)/channel_count/16*30;
|
||||
|
||||
vgmstream->interleave_block_size=0x10;
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
if (loop_flag)
|
||||
{
|
||||
if (coding_type == coding_INT_IMA)
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x54,streamFile)-start_offset)/channel_count*2;
|
||||
else
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x54,streamFile)-start_offset)/channel_count/16*30;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
if (channel_count > 1)
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
else
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_SADL;
|
||||
|
||||
/* open the file for reading */
|
||||
|
@ -627,6 +627,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
return vgmstream->ws_output_size;
|
||||
case coding_MSADPCM:
|
||||
return (vgmstream->interleave_block_size-(7-1)*vgmstream->channels)*2/vgmstream->channels;
|
||||
case coding_NDS_PROCYON:
|
||||
return 30;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -681,6 +683,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_PSX:
|
||||
case coding_PSX_badflags:
|
||||
case coding_invert_PSX:
|
||||
case coding_NDS_PROCYON:
|
||||
return 16;
|
||||
case coding_XA:
|
||||
return 14*vgmstream->channels;
|
||||
@ -989,6 +992,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||
samples_to_do);
|
||||
}
|
||||
break;
|
||||
case coding_NDS_PROCYON:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
decode_nds_procyon(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||
vgmstream->channels,vgmstream->samples_into_block,
|
||||
samples_to_do);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1309,6 +1319,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case coding_AICA:
|
||||
snprintf(temp,TEMPSIZE,"Yamaha AICA 4-bit ADPCM");
|
||||
break;
|
||||
case coding_NDS_PROCYON:
|
||||
snprintf(temp,TEMPSIZE,"Procyon Studio Digital Sound Elements NDS 4-bit APDCM");
|
||||
break;
|
||||
default:
|
||||
snprintf(temp,TEMPSIZE,"CANNOT DECODE");
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ typedef enum {
|
||||
coding_XBOX, /* XBOX IMA */
|
||||
coding_EAXA, /* EA/XA ADPCM */
|
||||
coding_EA_ADPCM, /* EA ADPCM */
|
||||
coding_NDS_PROCYON, /* NDS Procyon Studio ADPCM */
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
coding_ogg_vorbis, /* vorbis */
|
||||
|
Loading…
x
Reference in New Issue
Block a user