Skip to content

Commit

Permalink
Merge pull request vgmstream#1475 from vgmstream/utk-misc
Browse files Browse the repository at this point in the history
- Improve .dsp validations
- Remove fake .2pfs extension (use .sap)
- Add .move extension [Pop 'n Music 7 (PS2)]
- Fix minor UTK issues
- Add .cbx [Lego series (multi)]
- cleanup
  • Loading branch information
bnnm authored Jan 20, 2024
2 parents 836f0ee + 0c44042 commit 4e89ab3
Show file tree
Hide file tree
Showing 36 changed files with 21,303 additions and 21,142 deletions.
12 changes: 2 additions & 10 deletions cli/tools/vrts.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,16 +530,12 @@ def _detect_cli(self):

def _get_performance_args(self, cli):
args = [cli, '-O'] #flag to not write files
if self._args.looping:
if not self._args.looping:
args.append('-i')
args.extend(self._files.filenames)
return args

def _performance(self):
flag_looping = ''
if self._args.looping:
flag_looping = '-i'

# pases all files at once, as it's faster than 1 by 1 (that has to init program every time)
if self._args.performance_new:
self._p.info("testing new performance")
Expand Down Expand Up @@ -587,7 +583,7 @@ def _get_fuzzy_count(self, stdout):

def _get_compare_args(self, cli, outwav, filename):
args = [cli, '-o', outwav] #flag to not write files
if self._args.looping:
if not self._args.looping:
args.append('-i')
args.append(filename)
return args
Expand All @@ -596,10 +592,6 @@ def _compare(self):
ts_st = time.time()
self._p.info("comparing files")

flag_looping = ''
if self._args.looping:
flag_looping = '-i'

total_ok = 0
total_ko = 0
for filename in self._files.filenames:
Expand Down
46 changes: 24 additions & 22 deletions doc/FORMATS.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,9 @@ different internally (encrypted, different versions, etc) and not always can be
- InterPlay MUS ACM header [*MUS_ACM*]
- *mus_acm*: `.mus`
- Subfiles: *acm ogg_vorbis*
- **ps2_kces.c**
- Konami KCES Header [*PS2_KCES*]
- *ps2_kces*: `.kces`
- **vig_kces.c**
- Konami .VIG Header [*VIG_KCES*]
- *vig_kces*: `.vig`
- Codecs: PSX
- **hxd.c**
- Tecmo HXD Header [*HXD*]
Expand Down Expand Up @@ -587,13 +587,13 @@ different internally (encrypted, different versions, etc) and not always can be
- Alfa System .STS header [*STS*]
- *sts*: `.sts`
- Codecs: NGC_DSP
- **ps2_p2bt.c**
- Pop'n'Music 7 Header [*PS2_P2BT*]
- *ps2_p2bt*: `.p2bt`
- **p2bt_move_visa.c**
- Konami P2BT/MOVE/VISA header [*P2BT_MOVE_VISA*]
- *p2bt_move_visa*: `.p2bt .move .vis`
- Codecs: PSX
- **ps2_gbts.c**
- Pop'n'Music 9 Header [*PS2_GBTS*]
- *ps2_gbts*: `.gbts`
- **gbts.c**
- Konami GBTS header [*GBTS*]
- *gbts*: `.gbts`
- Codecs: PSX
- **wii_sng.c**
- SNG DSP Header [*WII_SNG*]
Expand Down Expand Up @@ -652,7 +652,8 @@ different internally (encrypted, different versions, etc) and not always can be
- *vgs_ps*: `.vgs`
- Codecs: PSX
- **redspark.c**
- RedSpark Header [*REDSPARK*]
- RedSpark header [*REDSPARK*]
- *redspark*: `.rsd`
- Codecs: NGC_DSP
- **ps2_sps.c**
- Ape Escape 2 SPS Header [*PS2_SPS*]
Expand Down Expand Up @@ -831,7 +832,7 @@ different internally (encrypted, different versions, etc) and not always can be
- Square Enix SCD header [*SQEX_SCD*]
- *sqex_scd*: `.scd`
- Subfiles: *ogg_vorbis_config*
- Codecs: OGG PCM16LE PSX MPEG MSADPCM NGC_DSP XMA ATRAC3 ATRAC9
- Codecs: OGG PCM16BE PCM16LE PSX MPEG MSADPCM NGC_DSP XMA ATRAC3 ATRAC9
- **ngc_nst_dsp.c**
- Animaniacs NST header [*NGC_NST_DSP*]
- *ngc_nst_dsp*: `.dsp`
Expand Down Expand Up @@ -881,10 +882,10 @@ different internally (encrypted, different versions, etc) and not always can be
- Mattel Hyperscan KVAG [*HYPERSCAN_KVAG*]
- *hyperscan_kvag*: `.bvg`
- Codecs: DVI_IMA
- **ios_psnd.c**
- PSND Header [*IOS_PSND*]
- *ios_psnd*: `.psnd`
- Codecs: PCM16LE
- **psnd.c**
- Polarbit PSND header [*PSND*]
- *psnd*: `.psn`
- Codecs: PCM16LE DVI_IMA
- **adp_wildfire.c**
- Wildfire ADP! header [*ADP_WILDFIRE*]
- *adp_wildfire*: `.adp`
Expand Down Expand Up @@ -927,9 +928,9 @@ different internally (encrypted, different versions, etc) and not always can be
- Namco IVAG header [*IVAG*]
- *ivag*: `.ivag`
- Codecs: PSX
- **ps2_2pfs.c**
- Konami 2PFS header [*PS2_2PFS*]
- *ps2_2pfs*: `.sap .2pfs`
- **2pfs.c**
- Konami 2PFS header [*2PFS*]
- *2pfs*: `.sap`
- Codecs: PSX
- **xnb.c**
- Microsoft XNA Game Studio header [*XNB*]
Expand Down Expand Up @@ -1339,10 +1340,6 @@ different internally (encrypted, different versions, etc) and not always can be
- High Voltage SVG header [*SVG*]
- *svg*: `.svg`
- Codecs: PSX
- **vis.c**
- Konami VIS header [*VIS*]
- *vis*: `.vis`
- Codecs: PSX
- **vai.c**
- Asobo Studio .VAI header [*VAI*]
- *vai*: `.vai`
Expand Down Expand Up @@ -1590,6 +1587,7 @@ different internally (encrypted, different versions, etc) and not always can be
- Koei Tecmo WaveBank header [*KWB*]
- *kwb*: `.wbd .wb2 .sed + .wbh .whd .wh2`
- *xws*: `.xws`
- *snd_koei*: `.snd`
- *koei_wavebank*
- Subfiles: *msf dsp_apex*
- Codecs: PCM16LE MSADPCM NGC_DSP XMA2 ATRAC9
Expand Down Expand Up @@ -1814,6 +1812,10 @@ different internally (encrypted, different versions, etc) and not always can be
- Ubisoft GWB+GWD header [*GWB_GWD*]
- *gwb_gwd*: `.gwb + .gwd`
- Codecs: NGC_DSP
- **cbx.c**
- Traveller's Tales CBX header [*CBX*]
- *cbx*: `.cbx`
- Codecs: EA_MT
- **scd_pcm.c**
- Lunar: Eternal Blue .PCM header [*SCD_PCM*]
- *scd_pcm*: `.pcm`
Expand Down
6 changes: 6 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ file(GLOB BASE_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/base/*.h")
file(GLOB BASE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/base/*.c")
file(GLOB CODING_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/coding/*.h")
file(GLOB CODING_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/coding/*.c")
file(GLOB CLIBS_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/coding/libs/*.h")
file(GLOB CLIBS_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/coding/libs/*.c")
file(GLOB LAYOUT_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/layout/*.h")
file(GLOB LAYOUT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/layout/*.c")
file(GLOB META_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/meta/*.h")
Expand All @@ -16,13 +18,15 @@ file(GLOB MAIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
# Setup source groups, mainly for Visual Studio
source_group("Header Files\\base" FILES ${BASE_HEADERS})
source_group("Header Files\\coding" FILES ${CODING_HEADERS})
source_group("Header Files\\coding\\libs" FILES ${CLIBS_HEADERS})
source_group("Header Files\\layout" FILES ${LAYOUT_HEADERS})
source_group("Header Files\\meta" FILES ${META_HEADERS})
source_group("Header Files\\util" FILES ${UTIL_HEADERS})
source_group("Header Files\\ext" FILES ${EXT_HEADERS})

source_group("Source Files\\base" FILES ${BASE_SOURCES})
source_group("Source Files\\coding" FILES ${CODING_SOURCES})
source_group("Source Files\\coding\\libs" FILES ${CLIBS_SOURCES})
source_group("Source Files\\layout" FILES ${LAYOUT_SOURCES})
source_group("Source Files\\meta" FILES ${META_SOURCES})
source_group("Source Files\\util" FILES ${UTIL_SOURCES})
Expand All @@ -32,6 +36,8 @@ set(libvgmstream_sources
${BASE_SOURCES}
${CODING_HEADERS}
${CODING_SOURCES}
${CLIBS_HEADERS}
${CLIBS_SOURCES}
${LAYOUT_HEADERS}
${LAYOUT_SOURCES}
${META_HEADERS}
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
OBJECTS =

#SRCS = $(wildcard **/*.c) #GNUMake 3.81?
SRCS = $(wildcard *.c) $(wildcard */*.c)
SRCS = $(wildcard *.c) $(wildcard */*.c) $(wildcard */*/*.c)
OBJECTS = $(patsubst %.c,%.o,$(SRCS))


Expand Down
3 changes: 2 additions & 1 deletion src/coding/coding.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,9 @@ STREAMFILE* compresswave_get_streamfile(compresswave_codec_data* data);
/* ea_mt_decoder*/
typedef struct ea_mt_codec_data ea_mt_codec_data;

ea_mt_codec_data* init_ea_mt(int channels, int type);
ea_mt_codec_data* init_ea_mt(int channels, int pcm_blocks);
ea_mt_codec_data* init_ea_mt_loops(int channels, int pcm_blocks, int loop_sample, off_t* loop_offsets);
ea_mt_codec_data* init_ea_mt_cbx(int channels);
void decode_ea_mt(VGMSTREAM* vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
void reset_ea_mt(VGMSTREAM* vgmstream);
void flush_ea_mt(VGMSTREAM* vgmstream);
Expand Down
67 changes: 31 additions & 36 deletions src/coding/ea_mt_decoder.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
#include "coding.h"
#include "libs/utkdec.h"

#include "ea_mt_decoder_utk.h"
/* Decodes EA MicroTalk */

/* Decodes EA MicroTalk (speech codec) using utkencode lib (slightly modified for vgmstream).
* EA separates MT10:1 and MT5:1 (bigger frames), but apparently are the same
* with different encoding parameters. Later revisions may have PCM blocks (rare).
*
* Decoder by Andrew D'Addesio: https://github.com/daddesio/utkencode
* Info: http://wiki.niotso.org/UTK
*/


//#define UTK_MAKE_U32(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
#define UTK_ROUND(x) ((x) >= 0.0f ? ((x)+0.5f) : ((x)-0.5f))
#define UTK_MIN(x,y) ((x)<(y)?(x):(y))
#define UTK_MAX(x,y) ((x)>(y)?(x):(y))
Expand All @@ -26,38 +17,45 @@ struct ea_mt_codec_data {
off_t loop_offset;
int loop_sample;

int pcm_blocks;
int samples_filled;
int samples_used;
int samples_done;
int samples_discard;
void* utk_context;
void* ctx;
};

static size_t ea_mt_read_callback(void *dest, int size, void *arg);
static ea_mt_codec_data* init_ea_mt_internal(utk_type_t type, int channels, int loop_sample, off_t* loop_offsets);


ea_mt_codec_data* init_ea_mt(int channels, int pcm_blocks) {
return init_ea_mt_loops(channels, pcm_blocks, 0, NULL);
}

ea_mt_codec_data* init_ea_mt_loops(int channels, int pcm_blocks, int loop_sample, off_t *loop_offsets) {
return init_ea_mt_internal(pcm_blocks ? UTK_EA_PCM : UTK_EA, channels, loop_sample, loop_offsets);
}

ea_mt_codec_data* init_ea_mt_cbx(int channels) {
return init_ea_mt_internal(UTK_CBX, channels, 0, NULL);
}

static ea_mt_codec_data* init_ea_mt_internal(utk_type_t type, int channels, int loop_sample, off_t* loop_offsets) {
ea_mt_codec_data* data = NULL;
int i;

data = calloc(channels, sizeof(ea_mt_codec_data)); /* one decoder per channel */
if (!data) goto fail;

for (i = 0; i < channels; i++) {
data[i].utk_context = calloc(1, sizeof(UTKContext));
if (!data[i].utk_context) goto fail;
utk_init(data[i].utk_context);
data[i].ctx = utk_init(type);
if (!data[i].ctx) goto fail;

data[i].pcm_blocks = pcm_blocks;
data[i].loop_sample = loop_sample;
if (loop_offsets)
data[i].loop_offset = loop_offsets[i];

utk_set_callback(data[i].utk_context, data[i].buffer, UTK_BUFFER_SIZE, &data[i], &ea_mt_read_callback);
utk_set_callback(data[i].ctx, data[i].buffer, UTK_BUFFER_SIZE, &data[i], &ea_mt_read_callback);
}

return data;
Expand All @@ -71,10 +69,9 @@ void decode_ea_mt(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, in
int i;
ea_mt_codec_data* data = vgmstream->codec_data;
ea_mt_codec_data* ch_data = &data[channel];
UTKContext* ctx = ch_data->utk_context;
int samples_done = 0;


float* fbuf = utk_get_samples(ch_data->ctx);
while (samples_done < samples_to_do) {

if (ch_data->samples_filled) {
Expand All @@ -98,7 +95,7 @@ void decode_ea_mt(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, in
samples_to_get = samples_to_do - samples_done;

for (i = ch_data->samples_used; i < ch_data->samples_used + samples_to_get; i++) {
int pcm = UTK_ROUND(ctx->decompressed_frame[i]);
int pcm = UTK_ROUND(fbuf[i]);
outbuf[0] = (int16_t)UTK_CLAMP(pcm, -32768, 32767);
outbuf += channelspacing;
}
Expand All @@ -119,19 +116,20 @@ void decode_ea_mt(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, in

/* offset is usually at loop_offset here, but not always (ex. loop_sample < 432) */
ch_data->offset = ch_data->loop_offset;
utk_set_ptr(ctx, 0, 0); /* reset the buffer reader */
utk_reset(ctx); /* decoder init (all fields must be reset, for some edge cases) */
utk_set_buffer(ch_data->ctx, 0, 0); /* reset the buffer reader */
utk_reset(ch_data->ctx); /* decoder init (all fields must be reset, for some edge cases) */
}
}
else {
/* new frame */
if (ch_data->pcm_blocks)
utk_rev3_decode_frame(ctx);
else
utk_decode_frame(ctx);
int samples = utk_decode_frame(ch_data->ctx);
if (samples < 0) {
VGM_LOG("wrong decode: %i\n", samples);
samples = 432;
}

ch_data->samples_used = 0;
ch_data->samples_filled = 432;
ch_data->samples_filled = samples;
}
}
}
Expand All @@ -143,23 +141,20 @@ static void flush_ea_mt_offsets(VGMSTREAM* vgmstream, int is_start, int samples_
if (!data) return;


/* EA-MT frames are VBR (not byte-aligned?), so utk_decoder reads new buffer data automatically.
/* EA-MT frames are VBR and not byte-aligned, so utk_decoder reads new buffer data automatically.
* When decoding starts or a SCHl block changes, flush_ea_mt must be called to reset the state.
* A bit hacky but would need some restructuring otherwise. */

for (i = 0; i < vgmstream->channels; i++) {
UTKContext* ctx = data[i].utk_context;

data[i].streamfile = vgmstream->ch[i].streamfile; /* maybe should keep its own STREAMFILE? */
data[i].streamfile = vgmstream->ch[i].streamfile;
if (is_start)
data[i].offset = vgmstream->ch[i].channel_start_offset;
else
data[i].offset = vgmstream->ch[i].offset;
utk_set_ptr(ctx, 0, 0); /* reset the buffer reader */
utk_set_buffer(data[i].ctx, 0, 0); /* reset the buffer reader */

if (is_start) {
utk_reset(ctx);
ctx->parsed_header = 0;
utk_reset(data[i].ctx);
data[i].samples_done = 0;
}

Expand Down Expand Up @@ -187,7 +182,7 @@ void free_ea_mt(ea_mt_codec_data* data, int channels) {
return;

for (i = 0; i < channels; i++) {
free(data[i].utk_context);
utk_free(data[i].ctx);
}
free(data);
}
Expand Down
Loading

0 comments on commit 4e89ab3

Please sign in to comment.