From e580858ca32773df35dd81b2ec84df43bbd8fc1e Mon Sep 17 00:00:00 2001 From: halleyscometsw Date: Wed, 13 Aug 2008 06:11:05 +0000 Subject: [PATCH] Yamaha AICA decoder, and Dreamcast .str (Sega Stream Asset Builder) git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@408 51a99a44-fe44-0410-b1ba-c3e57ba2b86b --- src/Makefile | 264 ++++++++++++++++++------------------ src/coding/Makefile.unix.am | 1 + src/coding/aica_decoder.c | 50 +++++++ src/coding/coding.h | 2 + src/libvgmstream.vcproj | 4 + src/meta/Makefile.unix.am | 1 + src/meta/dc_str.c | 3 +- src/vgmstream.c | 16 +++ src/vgmstream.h | 3 +- 9 files changed, 211 insertions(+), 133 deletions(-) create mode 100644 src/coding/aica_decoder.c diff --git a/src/Makefile b/src/Makefile index f6c42894..eb3c8c14 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,134 +1,136 @@ -CODING_OBJS=coding/adx_decoder.o \ - coding/g721_decoder.o \ - coding/ima_decoder.o \ - coding/ngc_afc_decoder.o \ - coding/ngc_dsp_decoder.o \ - coding/ngc_dtk_decoder.o \ - coding/pcm_decoder.o \ - coding/psx_decoder.o \ - coding/xa_decoder.o \ - coding/eaxa_decoder.o \ - coding/ogg_vorbis_decoder.o \ - coding/sdx2_decoder.o \ - coding/ws_decoder.o \ - coding/mpeg_decoder.o \ - coding/acm_decoder.o \ - coding/nwa_decoder.o \ - coding/msadpcm_decoder.o - -LAYOUT_OBJS=layout/ast_blocked.o \ - layout/blocked.o \ - layout/halpst_blocked.o \ - layout/interleave.o \ - layout/nolayout.o \ - layout/xa_blocked.o \ - layout/caf_blocked.o \ - layout/ea_block.o \ - layout/wsi_blocked.o \ - layout/str_snds_blocked.o \ - layout/ws_aud_blocked.o \ - layout/interleave_byte.o \ - layout/mus_acm_layout.o \ +CODING_OBJS=coding/adx_decoder.o \ + coding/g721_decoder.o \ + coding/ima_decoder.o \ + coding/ngc_afc_decoder.o \ + coding/ngc_dsp_decoder.o \ + coding/ngc_dtk_decoder.o \ + coding/pcm_decoder.o \ + coding/psx_decoder.o \ + coding/xa_decoder.o \ + coding/eaxa_decoder.o \ + coding/ogg_vorbis_decoder.o \ + coding/sdx2_decoder.o \ + coding/ws_decoder.o \ + coding/mpeg_decoder.o \ + coding/acm_decoder.o \ + coding/nwa_decoder.o \ + coding/msadpcm_decoder.o \ + coding/aica_decoder.o + +LAYOUT_OBJS=layout/ast_blocked.o \ + layout/blocked.o \ + layout/halpst_blocked.o \ + layout/interleave.o \ + layout/nolayout.o \ + layout/xa_blocked.o \ + layout/caf_blocked.o \ + layout/ea_block.o \ + layout/wsi_blocked.o \ + layout/str_snds_blocked.o \ + layout/ws_aud_blocked.o \ + layout/interleave_byte.o \ + layout/mus_acm_layout.o \ layout/aix_layout.o \ layout/ims_block.o \ - layout/de2_blocked.o - -META_OBJS=meta/adx_header.o \ - meta/afc_header.o \ - meta/agsc.o \ - meta/ast.o \ - meta/brstm.o \ - meta/halpst.o \ - meta/nds_strm.o \ - meta/ngc_adpdtk.o \ - meta/rsf.o \ - meta/rs03.o \ - meta/ngc_dsp_std.o \ - meta/Cstr.o \ - meta/gcsw.o \ - meta/ps2_ads.o \ - meta/ps2_npsf.o \ - meta/rwsd.o \ - meta/psx_cdxa.o \ - meta/ps2_rxw.o \ - meta/ps2_int.o \ - meta/ps2_exst.o \ - meta/ps2_svag.o \ - meta/ps2_mib.o \ - meta/ps2_mic.o \ - meta/raw.o \ - meta/ps2_vag.o \ - meta/psx_gms.o \ - meta/ps2_str.o \ - meta/ps2_ild.o \ - meta/ps2_pnb.o \ - meta/xbox_wavm.o \ - meta/xbox_xwav.o \ - meta/ea_header.o \ - meta/ngc_caf.o \ - meta/ps2_vpk.o \ - meta/genh.o \ - meta/ogg_vorbis_file.o \ - meta/ps2_bmdx.o \ - meta/aifc.o \ - meta/str_snds.o \ - meta/ws_aud.o \ - meta/ahx.o \ - meta/ivb.o \ - meta/svs.o \ - meta/riff.o \ - meta/pos.o \ - meta/nwa.o \ - meta/ps2_rws.o \ - meta/ps2_hgc1.o \ - meta/xss.o \ - meta/ps2_sl3.o \ - meta/ps2_aus.o \ - meta/fsb.o \ - meta/rsd.o \ - meta/rwx.o \ - meta/xwb.o \ - meta/ea_old.o \ - meta/ps2_xa30.o \ - meta/musc.o \ - meta/musx.o \ - meta/ps2_leg.o \ - meta/ps2_filp.o \ - meta/ps2_ikm.o \ - meta/ps2_sfs.o \ - meta/sat_dvi.o \ - meta/ps2_bg00.o \ - meta/dc_kcey.o \ - meta/ps2_rstm.o \ - meta/acm.o \ - meta/mus_acm.o \ - meta/ps2_kces.o \ - meta/ps2_dxh.o \ - meta/ps2_psh.o \ - meta/sli.o \ - meta/sfl.o \ - meta/pcm.o \ - meta/ps2_psw.o \ - meta/ps2_rkv.o \ - meta/ps2_vas.o \ - meta/ps2_tec.o \ - meta/ps2_enth.o \ - meta/sdt.o \ - meta/aix.o \ - meta/ngc_tydsp.o \ - meta/ngc_vjdsp.o \ - meta/xbox_wvs.o \ + layout/de2_blocked.o + +META_OBJS=meta/adx_header.o \ + meta/afc_header.o \ + meta/agsc.o \ + meta/ast.o \ + meta/brstm.o \ + meta/halpst.o \ + meta/nds_strm.o \ + meta/ngc_adpdtk.o \ + meta/rsf.o \ + meta/rs03.o \ + meta/ngc_dsp_std.o \ + meta/Cstr.o \ + meta/gcsw.o \ + meta/ps2_ads.o \ + meta/ps2_npsf.o \ + meta/rwsd.o \ + meta/psx_cdxa.o \ + meta/ps2_rxw.o \ + meta/ps2_int.o \ + meta/ps2_exst.o \ + meta/ps2_svag.o \ + meta/ps2_mib.o \ + meta/ps2_mic.o \ + meta/raw.o \ + meta/ps2_vag.o \ + meta/psx_gms.o \ + meta/ps2_str.o \ + meta/ps2_ild.o \ + meta/ps2_pnb.o \ + meta/xbox_wavm.o \ + meta/xbox_xwav.o \ + meta/ea_header.o \ + meta/ngc_caf.o \ + meta/ps2_vpk.o \ + meta/genh.o \ + meta/ogg_vorbis_file.o \ + meta/ps2_bmdx.o \ + meta/aifc.o \ + meta/str_snds.o \ + meta/ws_aud.o \ + meta/ahx.o \ + meta/ivb.o \ + meta/svs.o \ + meta/riff.o \ + meta/pos.o \ + meta/nwa.o \ + meta/ps2_rws.o \ + meta/ps2_hgc1.o \ + meta/xss.o \ + meta/ps2_sl3.o \ + meta/ps2_aus.o \ + meta/fsb.o \ + meta/rsd.o \ + meta/rwx.o \ + meta/xwb.o \ + meta/ea_old.o \ + meta/ps2_xa30.o \ + meta/musc.o \ + meta/musx.o \ + meta/ps2_leg.o \ + meta/ps2_filp.o \ + meta/ps2_ikm.o \ + meta/ps2_sfs.o \ + meta/sat_dvi.o \ + meta/ps2_bg00.o \ + meta/dc_kcey.o \ + meta/ps2_rstm.o \ + meta/acm.o \ + meta/mus_acm.o \ + meta/ps2_kces.o \ + meta/ps2_dxh.o \ + meta/ps2_psh.o \ + meta/sli.o \ + meta/sfl.o \ + meta/pcm.o \ + meta/ps2_psw.o \ + meta/ps2_rkv.o \ + meta/ps2_vas.o \ + meta/ps2_tec.o \ + meta/ps2_enth.o \ + meta/sdt.o \ + meta/aix.o \ + meta/ngc_tydsp.o \ + meta/ngc_vjdsp.o \ + meta/xbox_wvs.o \ meta/xbox_ims.o \ - meta/xbox_stma.o \ - meta/de2.o - -OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) - -libvgmstream.a: $(OBJECTS) - $(AR) crs libvgmstream.a $(OBJECTS) - -vgmstream-deps: - $(CC) $(CFLAGS) -M -o vgmstream-deps - -clean: - rm -f $(OBJECTS) libvgmstream.a + meta/xbox_stma.o \ + meta/de2.o \ + meta/dc_str.o + +OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) + +libvgmstream.a: $(OBJECTS) + $(AR) crs libvgmstream.a $(OBJECTS) + +vgmstream-deps: + $(CC) $(CFLAGS) -M -o vgmstream-deps + +clean: + rm -f $(OBJECTS) libvgmstream.a diff --git a/src/coding/Makefile.unix.am b/src/coding/Makefile.unix.am index aee5315a..2896c38b 100644 --- a/src/coding/Makefile.unix.am +++ b/src/coding/Makefile.unix.am @@ -22,5 +22,6 @@ libcoding_la_SOURCES += mpeg_decoder.c libcoding_la_SOURCES += acm_decoder.c libcoding_la_SOURCES += nwa_decoder.c libcoding_la_SOURCES += msadpcm_decoder.c +libcoding_la_SOURCES += aica_decoder.c EXTRA_DIST = coding.h g72x_state.h diff --git a/src/coding/aica_decoder.c b/src/coding/aica_decoder.c new file mode 100644 index 00000000..d1134c79 --- /dev/null +++ b/src/coding/aica_decoder.c @@ -0,0 +1,50 @@ +#include "../util.h" +#include "coding.h" + +/* fixed point (.8) amount to scale the current step size by */ +/* part of the same series as used in MS ADPCM "ADPCMTable" */ +static const unsigned int scale_step[16] = +{ + 230, 230, 230, 230, 307, 409, 512, 614, + 230, 230, 230, 230, 307, 409, 512, 614 +}; + +/* expand an unsigned four bit delta to a wider signed range */ +static const int scale_delta[16] = +{ + 1, 3, 5, 7, 9, 11, 13, 15, + -1, -3, -5, -7, -9,-11,-13,-15 +}; + +/* Yamaha AICA ADPCM (as seen in Dreamcast) */ + +void decode_aica(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { + int i; + int32_t sample_count; + int32_t hist1 = stream->adpcm_history1_16; + unsigned long step_size = stream->adpcm_step_index; + + for (i=first_sample,sample_count=0; ioffset+i/2,stream->streamfile) >> + (i&1?4:0) + )&0xf; + + int32_t sample_delta = (int32_t)step_size * scale_delta[sample_nibble]; + int32_t new_sample; + + new_sample = hist1 + sample_delta/8; + + outbuf[sample_count] = clamp16(new_sample); + + hist1 = outbuf[sample_count]; + + step_size = (step_size * scale_step[sample_nibble])/0x100; + if (step_size < 0x7f) step_size = 0x7f; + if (step_size > 0x6000) step_size = 0x6000; + } + + stream->adpcm_history1_16 = hist1; + stream->adpcm_step_index = step_size; +} diff --git a/src/coding/coding.h b/src/coding/coding.h index 4a54fb3a..860feb88 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -68,4 +68,6 @@ void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do); void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do); +void decode_aica(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + #endif diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index f27e5af4..ef4ffc61 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -604,6 +604,10 @@ RelativePath=".\coding\adx_decoder.c" > + + diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index 157c7737..a304958d 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -92,5 +92,6 @@ libmeta_la_SOURCES += ngc_vjdsp.c libmeta_la_SOURCES += xbox_stma.c libmeta_la_SOURCES += xbox_ims.c libmeta_la_SOURCES += de2.c +libmeta_la_SOURCES += dc_str.c EXTRA_DIST = meta.h diff --git a/src/meta/dc_str.c b/src/meta/dc_str.c index 3d916e1a..6f852d52 100644 --- a/src/meta/dc_str.c +++ b/src/meta/dc_str.c @@ -29,7 +29,7 @@ VGMSTREAM * init_vgmstream_dc_str(STREAMFILE *streamFile) { vgmstream->channels = channel_count; start_offset = 0x800; vgmstream->sample_rate = read_32bitLE(0x04,streamFile); - vgmstream->coding_type = coding_DVI_IMA; + vgmstream->coding_type = coding_AICA; vgmstream->num_samples = read_32bitLE(0x14,streamFile); @@ -56,6 +56,7 @@ VGMSTREAM * init_vgmstream_dc_str(STREAMFILE *streamFile) { vgmstream->ch[i].offset=start_offset+ vgmstream->interleave_block_size*i; + vgmstream->ch[i].adpcm_step_index = 0x7f; /* AICA */ } } diff --git a/src/vgmstream.c b/src/vgmstream.c index 97686950..2eb96632 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -115,6 +115,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_xbox_stma, init_vgmstream_xbox_matx, init_vgmstream_de2, + init_vgmstream_dc_str, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) @@ -526,6 +527,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) { case coding_IMA: return 1; case coding_INT_DVI_IMA: + case coding_AICA: return 2; case coding_NGC_AFC: return 16; @@ -609,6 +611,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) { case coding_WS: return vgmstream->current_block_size; case coding_INT_DVI_IMA: + case coding_AICA: return 1; case coding_MSADPCM: return vgmstream->interleave_block_size; @@ -873,6 +876,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to samples_to_do); } break; + case coding_AICA: + for (chan=0;chanchannels;chan++) { + decode_aica(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, + vgmstream->channels,vgmstream->samples_into_block, + samples_to_do); + } + break; } } @@ -1178,6 +1188,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case coding_MSADPCM: snprintf(temp,TEMPSIZE,"Microsoft 4-bit ADPCM"); break; + case coding_AICA: + snprintf(temp,TEMPSIZE,"Yamaha AICA 4-bit ADPCM"); + break; default: snprintf(temp,TEMPSIZE,"CANNOT DECODE"); } @@ -1627,6 +1640,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_DE2: snprintf(temp,TEMPSIZE,"gurumin .de2 with embedded funky RIFF"); break; + case meta_DC_STR: + snprintf(temp,TEMPSIZE,"Sega Stream Asset Builder header"); + break; default: snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); } diff --git a/src/vgmstream.h b/src/vgmstream.h index 6af8a1b2..558b4625 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -88,7 +88,8 @@ typedef enum { coding_NWA4, coding_NWA5, - coding_MSADPCM /* Microsoft ADPCM */ + coding_MSADPCM, /* Microsoft ADPCM */ + coding_AICA, /* Yamaha AICA ADPCM */ } coding_t; /* The layout type specifies how the sound data is laid out in the file */