mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-14 10:37:38 +01:00
Add HCA support.
This commit is contained in:
parent
f55a23f2e0
commit
33563f4e7c
66
ext_includes/clHCA.h
Normal file
66
ext_includes/clHCA.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef _clHCA_H
|
||||||
|
#define _clHCA_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum { clHCA_samplesPerBlock = 0x80 * 8 };
|
||||||
|
|
||||||
|
/* Must pass at least 8 bytes of data to this function. Returns -1 on non-match, or
|
||||||
|
* positive byte count on success. */
|
||||||
|
int clHCA_isOurFile0(const void *data);
|
||||||
|
|
||||||
|
/* Must pass a full header block for success. Returns 0 on success, -1 on failure. */
|
||||||
|
int clHCA_isOurFile1(const void *data, unsigned int size);
|
||||||
|
|
||||||
|
/* The opaque state structure. */
|
||||||
|
typedef struct clHCA clHCA;
|
||||||
|
|
||||||
|
/* In case you wish to allocate the structure on your own. */
|
||||||
|
int clHCA_sizeof();
|
||||||
|
void clHCA_clear(clHCA *, unsigned int ciphKey1, unsigned int ciphKey2);
|
||||||
|
|
||||||
|
/* Or you could let the library allocate it. */
|
||||||
|
clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2);
|
||||||
|
void clHCA_delete(clHCA *);
|
||||||
|
|
||||||
|
/* Requires a pre-allocated data structure.
|
||||||
|
* Before any decoding may be performed, the header block must be passed in.
|
||||||
|
* The recommended way of doing this is to detect the header length with
|
||||||
|
* clHCA_isOurFile0, validate the header with clHCA_isOurFile1, then pass
|
||||||
|
* it to this function, with the address of 0.
|
||||||
|
* Subsequent decodes with non-zero address are assumed to be sample blocks,
|
||||||
|
* and should be of the blockSize returned by the clHCA_getInfo function.
|
||||||
|
* Returns 0 on success, -1 on failure. */
|
||||||
|
int clHCA_Decode(clHCA *, void *data, unsigned int size, unsigned int address);
|
||||||
|
|
||||||
|
/* This is the simplest decode function, for signed and clipped 16 bit samples.
|
||||||
|
* May be called after clHCA_Decode, and will return the same data until the next
|
||||||
|
* block of sample data is passed to clHCA_Decode. */
|
||||||
|
void clHCA_DecodeSamples16(clHCA *, signed short * outSamples);
|
||||||
|
|
||||||
|
typedef struct clHCA_stInfo {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned int dataOffset;
|
||||||
|
unsigned int samplingRate;
|
||||||
|
unsigned int channelCount;
|
||||||
|
unsigned int blockSize;
|
||||||
|
unsigned int blockCount;
|
||||||
|
unsigned int loopEnabled;
|
||||||
|
unsigned int loopStart;
|
||||||
|
unsigned int loopEnd;
|
||||||
|
} clHCA_stInfo;
|
||||||
|
|
||||||
|
/* Retrieve information relevant for decoding and playback with this function.
|
||||||
|
* Must be called after successfully decoding a header block with clHCA_Decode,
|
||||||
|
* or else it will fail.
|
||||||
|
* Returns 0 on success, -1 on failure. */
|
||||||
|
int clHCA_getInfo(clHCA *, clHCA_stInfo *out);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
1605
ext_libs/clHCA.c
Normal file
1605
ext_libs/clHCA.c
Normal file
File diff suppressed because it is too large
Load Diff
10
src/Makefile
10
src/Makefile
@ -23,7 +23,8 @@ CODING_OBJS=coding/adx_decoder.o \
|
|||||||
coding/lsf_decoder.o \
|
coding/lsf_decoder.o \
|
||||||
coding/mtaf_decoder.o \
|
coding/mtaf_decoder.o \
|
||||||
coding/at3_decoder.o \
|
coding/at3_decoder.o \
|
||||||
coding/g719_decoder.o
|
coding/g719_decoder.o \
|
||||||
|
coding/hca_decoder.o
|
||||||
|
|
||||||
LAYOUT_OBJS=layout/ast_blocked.o \
|
LAYOUT_OBJS=layout/ast_blocked.o \
|
||||||
layout/blocked.o \
|
layout/blocked.o \
|
||||||
@ -300,9 +301,12 @@ META_OBJS=meta/adx_header.o \
|
|||||||
meta/bfwav.o \
|
meta/bfwav.o \
|
||||||
meta/g1l.o \
|
meta/g1l.o \
|
||||||
meta/mca.o \
|
meta/mca.o \
|
||||||
meta/btsnd.o
|
meta/btsnd.o \
|
||||||
|
meta/hca.o
|
||||||
|
|
||||||
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)
|
EXT_LIBS = ../ext_libs/clHCA.o
|
||||||
|
|
||||||
|
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) $(EXT_LIBS)
|
||||||
|
|
||||||
libvgmstream.a: $(OBJECTS)
|
libvgmstream.a: $(OBJECTS)
|
||||||
$(AR) crs libvgmstream.a $(OBJECTS)
|
$(AR) crs libvgmstream.a $(OBJECTS)
|
||||||
|
@ -4,7 +4,7 @@ AM_CFLAGS = -Wall @CFLAGS@ -I$(top_builddir) -I$(top_srcdir)
|
|||||||
AM_MAKEFLAGS=-f Makefile.unix
|
AM_MAKEFLAGS=-f Makefile.unix
|
||||||
|
|
||||||
libvgmstream_la_LDFLAGS = coding/libcoding.la layout/liblayout.la meta/libmeta.la
|
libvgmstream_la_LDFLAGS = coding/libcoding.la layout/liblayout.la meta/libmeta.la
|
||||||
libvgmstream_la_SOURCES = vgmstream.c util.c streamfile.c
|
libvgmstream_la_SOURCES = vgmstream.c util.c streamfile.c ../ext_libs/clHCA.c
|
||||||
|
|
||||||
SUBDIRS = coding layout meta
|
SUBDIRS = coding layout meta
|
||||||
|
|
||||||
|
@ -30,5 +30,6 @@ libcoding_la_SOURCES += g7221_decoder.c
|
|||||||
libcoding_la_SOURCES += lsf_decoder.c
|
libcoding_la_SOURCES += lsf_decoder.c
|
||||||
libcoding_la_SOURCES += mtaf_decoder.c
|
libcoding_la_SOURCES += mtaf_decoder.c
|
||||||
libcoding_la_SOURCES += g719_decoder.c
|
libcoding_la_SOURCES += g719_decoder.c
|
||||||
|
libcoding_la_SOURCES += hca_decoder.c
|
||||||
|
|
||||||
EXTRA_DIST = coding.h g72x_state.h
|
EXTRA_DIST = coding.h g72x_state.h clHCA.h
|
||||||
|
82
src/coding/hca_decoder.c
Normal file
82
src/coding/hca_decoder.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels) {
|
||||||
|
int samples_done = 0;
|
||||||
|
|
||||||
|
int32_t samples_remain = clHCA_samplesPerBlock - data->sample_ptr;
|
||||||
|
|
||||||
|
void *hca_data = NULL;
|
||||||
|
|
||||||
|
clHCA *hca;
|
||||||
|
|
||||||
|
if ( data->samples_discard ) {
|
||||||
|
if ( samples_remain <= data->samples_discard ) {
|
||||||
|
data->samples_discard -= samples_remain;
|
||||||
|
samples_remain = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
samples_remain -= data->samples_discard;
|
||||||
|
data->sample_ptr += data->samples_discard;
|
||||||
|
data->samples_discard = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( samples_remain > samples_to_do ) samples_remain = samples_to_do;
|
||||||
|
|
||||||
|
memcpy( outbuf, data->sample_buffer + data->sample_ptr * data->info.channelCount, samples_remain * data->info.channelCount * sizeof(sample) );
|
||||||
|
|
||||||
|
outbuf += samples_remain * data->info.channelCount;
|
||||||
|
|
||||||
|
data->sample_ptr += samples_remain;
|
||||||
|
|
||||||
|
samples_done += samples_remain;
|
||||||
|
|
||||||
|
hca_data = malloc( data->info.blockSize );
|
||||||
|
|
||||||
|
if ( !hca_data ) return;
|
||||||
|
|
||||||
|
hca = (clHCA *)(data + 1);
|
||||||
|
|
||||||
|
while ( samples_done < samples_to_do ) {
|
||||||
|
const unsigned int blockSize = data->info.blockSize;
|
||||||
|
const unsigned int channelCount = data->info.channelCount;
|
||||||
|
const unsigned int address = data->info.dataOffset + data->curblock * blockSize;
|
||||||
|
|
||||||
|
if (data->curblock >= data->info.blockCount) {
|
||||||
|
memset(outbuf, 0, (samples_to_do - samples_done) * channelCount * sizeof(sample));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( read_streamfile((uint8_t*) hca_data, data->start + address, blockSize, data->streamfile) != blockSize )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( clHCA_Decode( hca, hca_data, blockSize, address ) < 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
++data->curblock;
|
||||||
|
|
||||||
|
clHCA_DecodeSamples16( hca, data->sample_buffer );
|
||||||
|
|
||||||
|
samples_remain = clHCA_samplesPerBlock;
|
||||||
|
data->sample_ptr = 0;
|
||||||
|
if ( data->samples_discard ) {
|
||||||
|
if ( samples_remain <= data->samples_discard ) {
|
||||||
|
data->samples_discard -= samples_remain;
|
||||||
|
samples_remain = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
samples_remain -= data->samples_discard;
|
||||||
|
data->sample_ptr = data->samples_discard;
|
||||||
|
data->samples_discard = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( samples_remain > samples_to_do - samples_done ) samples_remain = samples_to_do - samples_done;
|
||||||
|
memcpy( outbuf, data->sample_buffer, samples_remain * channelCount * sizeof(sample) );
|
||||||
|
samples_done += samples_remain;
|
||||||
|
outbuf += samples_remain * channelCount;
|
||||||
|
data->sample_ptr = samples_remain;
|
||||||
|
}
|
||||||
|
|
||||||
|
free( hca_data );
|
||||||
|
}
|
@ -380,6 +380,10 @@
|
|||||||
RelativePath=".\meta\halpst.c"
|
RelativePath=".\meta\halpst.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\meta\hca.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\his.c"
|
RelativePath=".\meta\his.c"
|
||||||
>
|
>
|
||||||
@ -1230,6 +1234,10 @@
|
|||||||
RelativePath=".\coding\g7221_decoder.c"
|
RelativePath=".\coding\g7221_decoder.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\coding\hca_decoder.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\coding\ima_decoder.c"
|
RelativePath=".\coding\ima_decoder.c"
|
||||||
>
|
>
|
||||||
@ -1302,6 +1310,10 @@
|
|||||||
RelativePath=".\coding\xa_decoder.c"
|
RelativePath=".\coding\xa_decoder.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext_libs\clHCA.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
@ -183,6 +183,7 @@
|
|||||||
<ClCompile Include="meta\gh3_bar.c" />
|
<ClCompile Include="meta\gh3_bar.c" />
|
||||||
<ClCompile Include="meta\gsp_gsb.c" />
|
<ClCompile Include="meta\gsp_gsb.c" />
|
||||||
<ClCompile Include="meta\halpst.c" />
|
<ClCompile Include="meta\halpst.c" />
|
||||||
|
<ClCompile Include="meta\hca.c" />
|
||||||
<ClCompile Include="meta\his.c" />
|
<ClCompile Include="meta\his.c" />
|
||||||
<ClCompile Include="meta\idsp.c" />
|
<ClCompile Include="meta\idsp.c" />
|
||||||
<ClCompile Include="meta\ish_isd.c" />
|
<ClCompile Include="meta\ish_isd.c" />
|
||||||
@ -362,6 +363,7 @@
|
|||||||
<ClCompile Include="coding\g719_decoder.c" />
|
<ClCompile Include="coding\g719_decoder.c" />
|
||||||
<ClCompile Include="coding\g721_decoder.c" />
|
<ClCompile Include="coding\g721_decoder.c" />
|
||||||
<ClCompile Include="coding\g7221_decoder.c" />
|
<ClCompile Include="coding\g7221_decoder.c" />
|
||||||
|
<ClCompile Include="coding\hca_decoder.c" />
|
||||||
<ClCompile Include="coding\ima_decoder.c" />
|
<ClCompile Include="coding\ima_decoder.c" />
|
||||||
<ClCompile Include="coding\l5_555_decoder.c" />
|
<ClCompile Include="coding\l5_555_decoder.c" />
|
||||||
<ClCompile Include="coding\mpeg_decoder.c" />
|
<ClCompile Include="coding\mpeg_decoder.c" />
|
||||||
@ -406,6 +408,7 @@
|
|||||||
<ClCompile Include="layout\wsi_blocked.c" />
|
<ClCompile Include="layout\wsi_blocked.c" />
|
||||||
<ClCompile Include="layout\xa_blocked.c" />
|
<ClCompile Include="layout\xa_blocked.c" />
|
||||||
<ClCompile Include="layout\xvas_block.c" />
|
<ClCompile Include="layout\xvas_block.c" />
|
||||||
|
<ClCompile Include="..\ext_libs\clHCA.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -36,6 +36,15 @@
|
|||||||
<Filter Include="layout\Source Files">
|
<Filter Include="layout\Source Files">
|
||||||
<UniqueIdentifier>{e729b7b3-e13c-4cf9-9ded-428c209b6f62}</UniqueIdentifier>
|
<UniqueIdentifier>{e729b7b3-e13c-4cf9-9ded-428c209b6f62}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="ext_libs">
|
||||||
|
<UniqueIdentifier>{48DB0DEF-3694-40E0-9FF6-8A736E6C3A62}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="ext_libs\Source Files">
|
||||||
|
<UniqueIdentifier>{78A32BD9-0DB4-4164-A7E6-41506B78392E}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="ext_libs\Header Files">
|
||||||
|
<UniqueIdentifier>{20824073-8817-41CF-8A21-D54294A56050}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="streamfile.h">
|
<ClInclude Include="streamfile.h">
|
||||||
@ -68,6 +77,9 @@
|
|||||||
<ClInclude Include="layout\layout.h">
|
<ClInclude Include="layout\layout.h">
|
||||||
<Filter>layout\Header Files</Filter>
|
<Filter>layout\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\ext_includes\clHCA.h">
|
||||||
|
<Filter>ext_libs\Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="streamfile.c">
|
<ClCompile Include="streamfile.c">
|
||||||
@ -202,6 +214,9 @@
|
|||||||
<ClCompile Include="meta\halpst.c">
|
<ClCompile Include="meta\halpst.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="meta\hca.c">
|
||||||
|
<Filter>meta\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="meta\his.c">
|
<ClCompile Include="meta\his.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -721,6 +736,9 @@
|
|||||||
<ClCompile Include="coding\g7221_decoder.c">
|
<ClCompile Include="coding\g7221_decoder.c">
|
||||||
<Filter>coding\Source Files</Filter>
|
<Filter>coding\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="coding\hca_decoder.c">
|
||||||
|
<Filter>coding\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="coding\ima_decoder.c">
|
<ClCompile Include="coding\ima_decoder.c">
|
||||||
<Filter>coding\Source Files</Filter>
|
<Filter>coding\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -982,5 +1000,8 @@
|
|||||||
<ClCompile Include="coding\g719_decoder.c">
|
<ClCompile Include="coding\g719_decoder.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\ext_libs\clHCA.c">
|
||||||
|
<Filter>ext_libs\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -244,5 +244,6 @@ libmeta_la_SOURCES += g1l.c
|
|||||||
libmeta_la_SOURCES += ps2_vbk.c
|
libmeta_la_SOURCES += ps2_vbk.c
|
||||||
libmeta_la_SOURCES += mca.c
|
libmeta_la_SOURCES += mca.c
|
||||||
libmeta_la_SOURCES += btsnd.c
|
libmeta_la_SOURCES += btsnd.c
|
||||||
|
libmeta_la_SOURCES += hca.c
|
||||||
|
|
||||||
EXTRA_DIST = meta.h
|
EXTRA_DIST = meta.h
|
||||||
|
98
src/meta/hca.c
Normal file
98
src/meta/hca.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "../vgmstream.h"
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile) {
|
||||||
|
return init_vgmstream_hca_offset( streamFile, 0, streamFile->get_size(streamFile) );
|
||||||
|
}
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
|
||||||
|
/* These I don't know about... */
|
||||||
|
static const unsigned int ciphKey1=0x30DBE1AB;
|
||||||
|
static const unsigned int ciphKey2=0xCC554639;
|
||||||
|
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
|
hca_codec_data * hca_file = ( hca_codec_data * ) calloc(1, sizeof(hca_codec_data) + clHCA_sizeof());
|
||||||
|
void * hca_data = NULL;
|
||||||
|
clHCA * hca;
|
||||||
|
|
||||||
|
uint8_t header[8];
|
||||||
|
|
||||||
|
int header_size;
|
||||||
|
|
||||||
|
if ( !hca_file ) goto fail;
|
||||||
|
|
||||||
|
if ( size < 8 ) goto fail;
|
||||||
|
|
||||||
|
hca_file->streamfile = streamFile;
|
||||||
|
hca_file->start = start;
|
||||||
|
hca_file->size = size;
|
||||||
|
|
||||||
|
if ( read_streamfile( header, start, 8, streamFile) != 8 ) goto fail;
|
||||||
|
|
||||||
|
header_size = clHCA_isOurFile0( header );
|
||||||
|
|
||||||
|
if ( header_size < 0 ) goto fail;
|
||||||
|
|
||||||
|
hca_data = malloc( header_size );
|
||||||
|
|
||||||
|
if ( !hca_data ) goto fail;
|
||||||
|
|
||||||
|
memcpy( hca_data, header, 8 );
|
||||||
|
|
||||||
|
if ( read_streamfile( ((uint8_t*)hca_data) + 8, start + 8, header_size - 8, streamFile ) != header_size - 8 ) goto fail;
|
||||||
|
|
||||||
|
if ( clHCA_isOurFile1( hca_data, header_size ) < 0 ) goto fail;
|
||||||
|
|
||||||
|
hca = (clHCA *)(hca_file + 1);
|
||||||
|
|
||||||
|
clHCA_clear(hca, ciphKey1, ciphKey2);
|
||||||
|
|
||||||
|
if (clHCA_Decode(hca, hca_data, header_size, 0) < 0) goto fail;
|
||||||
|
|
||||||
|
if (clHCA_getInfo(hca, &hca_file->info) < 0) goto fail;
|
||||||
|
|
||||||
|
hca_file->sample_ptr = clHCA_samplesPerBlock;
|
||||||
|
hca_file->samples_discard = 0;
|
||||||
|
|
||||||
|
streamFile->get_name( streamFile, filename, sizeof(filename) );
|
||||||
|
|
||||||
|
hca_file->streamfile = streamFile->open(streamFile, filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
if (!hca_file->streamfile) goto fail;
|
||||||
|
|
||||||
|
vgmstream = allocate_vgmstream( hca_file->info.channelCount, 1 );
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
free( hca_data );
|
||||||
|
|
||||||
|
vgmstream->loop_flag = hca_file->info.loopEnabled;
|
||||||
|
vgmstream->loop_start_sample = hca_file->info.loopStart * clHCA_samplesPerBlock;
|
||||||
|
vgmstream->loop_end_sample = hca_file->info.loopEnd * clHCA_samplesPerBlock;
|
||||||
|
|
||||||
|
vgmstream->codec_data = hca_file;
|
||||||
|
|
||||||
|
vgmstream->channels = hca_file->info.channelCount;
|
||||||
|
vgmstream->sample_rate = hca_file->info.samplingRate;
|
||||||
|
|
||||||
|
vgmstream->num_samples = hca_file->info.blockCount * clHCA_samplesPerBlock;
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_CRI_HCA;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
vgmstream->meta_type = meta_HCA;
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if ( hca_data ) {
|
||||||
|
free( hca_data );
|
||||||
|
}
|
||||||
|
if ( hca_file ) {
|
||||||
|
free( hca_file );
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -111,6 +111,10 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE * streamFile);
|
||||||
|
|
||||||
|
@ -338,6 +338,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
|||||||
init_vgmstream_bcstm,
|
init_vgmstream_bcstm,
|
||||||
init_vgmstream_3ds_idsp,
|
init_vgmstream_3ds_idsp,
|
||||||
init_vgmstream_g1l,
|
init_vgmstream_g1l,
|
||||||
|
init_vgmstream_hca,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
||||||
@ -432,6 +433,13 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
|
|||||||
ov_pcm_seek(ogg_vorbis_file, 0);
|
ov_pcm_seek(ogg_vorbis_file, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
||||||
|
hca_codec_data *data = vgmstream->codec_data;
|
||||||
|
clHCA *hca = (clHCA *)(data + 1);
|
||||||
|
data->curblock = 0;
|
||||||
|
data->sample_ptr = clHCA_samplesPerBlock;
|
||||||
|
data->samples_discard = 0;
|
||||||
|
}
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = vgmstream->codec_data;
|
mp4_aac_codec_data *data = vgmstream->codec_data;
|
||||||
@ -623,6 +631,12 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
||||||
|
if (vgmstream->codec_data) {
|
||||||
|
free(vgmstream->codec_data);
|
||||||
|
vgmstream->codec_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
@ -1018,6 +1032,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
|||||||
return 54;
|
return 54;
|
||||||
case coding_MTAF:
|
case coding_MTAF:
|
||||||
return 0x80*2;
|
return 0x80*2;
|
||||||
|
case coding_CRI_HCA:
|
||||||
|
return clHCA_samplesPerBlock;
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
case coding_MP4_AAC:
|
case coding_MP4_AAC:
|
||||||
return ((mp4_aac_codec_data*)vgmstream->codec_data)->samples_per_frame;
|
return ((mp4_aac_codec_data*)vgmstream->codec_data)->samples_per_frame;
|
||||||
@ -1399,6 +1415,11 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
|||||||
vgmstream->channels);
|
vgmstream->channels);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case coding_CRI_HCA:
|
||||||
|
decode_hca(vgmstream->codec_data,
|
||||||
|
buffer+samples_written*vgmstream->channels,samples_to_do,
|
||||||
|
vgmstream->channels);
|
||||||
|
break;
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
case coding_MP4_AAC:
|
case coding_MP4_AAC:
|
||||||
decode_mp4_aac(vgmstream->codec_data,
|
decode_mp4_aac(vgmstream->codec_data,
|
||||||
@ -1685,6 +1706,12 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
|
|||||||
ov_pcm_seek_lap(ogg_vorbis_file, vgmstream->loop_sample);
|
ov_pcm_seek_lap(ogg_vorbis_file, vgmstream->loop_sample);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
||||||
|
hca_codec_data *data = (hca_codec_data *)(vgmstream->codec_data);
|
||||||
|
data->curblock = data->info.loopStart;
|
||||||
|
data->sample_ptr = clHCA_samplesPerBlock;
|
||||||
|
data->samples_discard = 0;
|
||||||
|
}
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = (mp4_aac_codec_data *)(vgmstream->codec_data);
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *)(vgmstream->codec_data);
|
||||||
@ -1832,6 +1859,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
|||||||
case coding_CRI_ADX_enc_9:
|
case coding_CRI_ADX_enc_9:
|
||||||
snprintf(temp,TEMPSIZE,"encrypted (type 9) CRI ADX 4-bit ADPCM");
|
snprintf(temp,TEMPSIZE,"encrypted (type 9) CRI ADX 4-bit ADPCM");
|
||||||
break;
|
break;
|
||||||
|
case coding_CRI_HCA:
|
||||||
|
snprintf(temp,TEMPSIZE,"CRI HCA");
|
||||||
|
break;
|
||||||
case coding_NDS_IMA:
|
case coding_NDS_IMA:
|
||||||
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
|
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
|
||||||
break;
|
break;
|
||||||
@ -3314,7 +3344,7 @@ fail:
|
|||||||
static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
||||||
{
|
{
|
||||||
if (vgmstream->layout_type==layout_scd_int) {
|
if (vgmstream->layout_type==layout_scd_int) {
|
||||||
scd_int_codec_data *data = vgmstream->codec_data;
|
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
|
||||||
if (data) {
|
if (data) {
|
||||||
return data->substream_count;
|
return data->substream_count;
|
||||||
}
|
}
|
||||||
@ -3324,7 +3354,7 @@ static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
|||||||
}
|
}
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
||||||
ogg_vorbis_codec_data *data = vgmstream->codec_data;
|
ogg_vorbis_codec_data *data = (ogg_vorbis_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -3334,9 +3364,19 @@ static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
||||||
|
hca_codec_data *data = (hca_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = vgmstream->codec_data;
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
||||||
if (data) {
|
if (data) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3351,19 +3391,24 @@ static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
|||||||
static STREAMFILE * get_vgmstream_streamfile(VGMSTREAM * vgmstream, int channel)
|
static STREAMFILE * get_vgmstream_streamfile(VGMSTREAM * vgmstream, int channel)
|
||||||
{
|
{
|
||||||
if (vgmstream->layout_type==layout_scd_int) {
|
if (vgmstream->layout_type==layout_scd_int) {
|
||||||
scd_int_codec_data *data = vgmstream->codec_data;
|
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
|
||||||
return data->intfiles[channel];
|
return data->intfiles[channel];
|
||||||
}
|
}
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
||||||
ogg_vorbis_codec_data *data = vgmstream->codec_data;
|
ogg_vorbis_codec_data *data = (ogg_vorbis_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
return data->ov_streamfile.streamfile;
|
return data->ov_streamfile.streamfile;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
||||||
|
hca_codec_data *data = (hca_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
|
return data->streamfile;
|
||||||
|
}
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = vgmstream->codec_data;
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
||||||
return data->if_file.streamfile;
|
return data->if_file.streamfile;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,6 +46,8 @@ enum { PATH_LIMIT = 32768 };
|
|||||||
#include "maiatrac3plus.h"
|
#include "maiatrac3plus.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "clHCA.h"
|
||||||
|
|
||||||
#include "coding/acm_decoder.h"
|
#include "coding/acm_decoder.h"
|
||||||
#include "coding/nwa_decoder.h"
|
#include "coding/nwa_decoder.h"
|
||||||
|
|
||||||
@ -150,6 +152,8 @@ typedef enum {
|
|||||||
coding_LSF, /* lsf ADPCM */
|
coding_LSF, /* lsf ADPCM */
|
||||||
coding_MTAF, /* Konami IMA-derived MTAF ADPCM */
|
coding_MTAF, /* Konami IMA-derived MTAF ADPCM */
|
||||||
|
|
||||||
|
coding_CRI_HCA, /* CRI High Compression Audio */
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
coding_MP4_AAC,
|
coding_MP4_AAC,
|
||||||
#endif
|
#endif
|
||||||
@ -581,6 +585,7 @@ typedef enum {
|
|||||||
meta_G1L, // Tecmo Koei G1L
|
meta_G1L, // Tecmo Koei G1L
|
||||||
meta_MCA, // Capcom MCA "MADP"
|
meta_MCA, // Capcom MCA "MADP"
|
||||||
meta_XB3D_ADX, // Xenoblade Chronicles 3D ADX
|
meta_XB3D_ADX, // Xenoblade Chronicles 3D ADX
|
||||||
|
meta_HCA,
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
meta_MP4,
|
meta_MP4,
|
||||||
#endif
|
#endif
|
||||||
@ -814,6 +819,17 @@ typedef struct {
|
|||||||
STREAMFILE **intfiles;
|
STREAMFILE **intfiles;
|
||||||
} scd_int_codec_data;
|
} scd_int_codec_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
STREAMFILE *streamfile;
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t size;
|
||||||
|
clHCA_stInfo info;
|
||||||
|
unsigned int curblock;
|
||||||
|
unsigned int sample_ptr, samples_discard;
|
||||||
|
signed short sample_buffer[clHCA_samplesPerBlock * 16];
|
||||||
|
// clHCA exists here
|
||||||
|
} hca_codec_data;
|
||||||
|
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
STREAMFILE *streamfile;
|
STREAMFILE *streamfile;
|
||||||
|
Loading…
Reference in New Issue
Block a user