From eccd67d156859b00727d46c5b4fa292ca5702a7c Mon Sep 17 00:00:00 2001 From: NicknineTheEagle Date: Fri, 29 May 2020 19:28:32 +0300 Subject: [PATCH] Added Sega KAT format --- src/formats.c | 2 + src/libvgmstream.vcxproj | 1 + src/libvgmstream.vcxproj.filters | 3 ++ src/meta/kat.c | 82 ++++++++++++++++++++++++++++++++ src/meta/meta.h | 2 + src/vgmstream.c | 1 + src/vgmstream.h | 1 + 7 files changed, 92 insertions(+) create mode 100644 src/meta/kat.c diff --git a/src/formats.c b/src/formats.c index c5f83f84..31e7ca13 100644 --- a/src/formats.c +++ b/src/formats.c @@ -238,6 +238,7 @@ static const char* extension_list[] = { "joe", "jstm", + "kat", "kces", "kcey", //fake extension/header id for .pcm (renamed, to be removed) "khv", //fake extension/header id for .vas (renamed, to be removed) @@ -1296,6 +1297,7 @@ static const meta_info meta_info_list[] = { {meta_DIVA, "DIVA header"}, {meta_IMUSE, "LucasArts iMUSE header"}, {meta_KTSR, "Koei Tecmo KTSR header"}, + {meta_KAT, "Sega KAT header"}, }; void get_vgmstream_coding_description(VGMSTREAM *vgmstream, char *out, size_t out_size) { diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index d814bc14..5b9a64f0 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -191,6 +191,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 56c7e2ba..c142dc96 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1774,5 +1774,8 @@ meta\Source Files + + meta\Source Files + \ No newline at end of file diff --git a/src/meta/kat.c b/src/meta/kat.c new file mode 100644 index 00000000..6b68b9c1 --- /dev/null +++ b/src/meta/kat.c @@ -0,0 +1,82 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* .KAT - standard sound bank format used on Dreamcast */ +VGMSTREAM *init_vgmstream_kat(STREAMFILE *sf) { + VGMSTREAM *vgmstream = NULL; + uint32_t entry_offset, type, start_offset, data_size, sample_rate, channels, bit_depth, loop_start, loop_end; + int loop_flag; + int num_sounds, target_stream = sf->stream_index; + + /* checks */ + if (!check_extensions(sf, "kat")) + goto fail; + + num_sounds = read_u32le(0x00, sf); + + if (target_stream == 0) target_stream = 1; + if (target_stream < 0 || num_sounds == 0 || target_stream > num_sounds) + goto fail; + + entry_offset = 0x04 + (target_stream - 1) * 0x2c; + + type = read_u32le(entry_offset + 0x00, sf); + if (type != 0x01) /* only type 0x01 is supported, other types are MIDI, programs, etc */ + goto fail; + + bit_depth = read_u32le(entry_offset + 0x14, sf); + if (bit_depth != 4 && bit_depth != 8 && bit_depth != 16) + goto fail; + + start_offset = read_u32le(entry_offset + 0x04, sf); + data_size = read_u32le(entry_offset + 0x08, sf); + sample_rate = read_u32le(entry_offset + 0x0c, sf); + if (sample_rate > 48000) + goto fail; + + loop_flag = read_u32le(entry_offset + 0x10, sf); + loop_start = read_u32le(entry_offset + 0x1c, sf); + loop_end = read_u32le(entry_offset + 0x20, sf); + + channels = 1; /* mono only */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->meta_type = meta_KAT; + vgmstream->sample_rate = sample_rate; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + vgmstream->stream_size = data_size; + vgmstream->num_streams = num_sounds; + + switch (bit_depth) { + case 4: + vgmstream->coding_type = coding_AICA_int; + vgmstream->layout_type = layout_none; + vgmstream->num_samples = yamaha_bytes_to_samples(data_size, channels); + break; + case 8: + vgmstream->coding_type = coding_PCM8_U; + vgmstream->layout_type = layout_none; + vgmstream->num_samples = pcm_bytes_to_samples(data_size, channels, 8); + break; + case 16: + vgmstream->coding_type = coding_PCM16LE; + vgmstream->layout_type = layout_none; + vgmstream->num_samples = pcm_bytes_to_samples(data_size, channels, 16); + break; + default: + goto fail; + } + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/meta.h b/src/meta/meta.h index 5a501559..608ce2f4 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -902,4 +902,6 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf); VGMSTREAM* init_vgmstream_mups(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_kat(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/src/vgmstream.c b/src/vgmstream.c index e6daa9f0..40623714 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -499,6 +499,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = { #ifdef VGM_USE_VORBIS init_vgmstream_mups, #endif + init_vgmstream_kat, /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ diff --git a/src/vgmstream.h b/src/vgmstream.h index 6c5377b6..b88df9ee 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -731,6 +731,7 @@ typedef enum { meta_DIVA, meta_IMUSE, meta_KTSR, + meta_KAT, } meta_t; /* standard WAVEFORMATEXTENSIBLE speaker positions */