2016-06-28 09:20:37 +02:00
|
|
|
#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) {
|
2016-12-04 14:12:23 +01:00
|
|
|
unsigned int ciphKey1;
|
|
|
|
unsigned int ciphKey2;
|
2016-07-01 00:34:40 +02:00
|
|
|
|
|
|
|
char filename[PATH_LIMIT];
|
2016-06-28 09:20:37 +02:00
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
VGMSTREAM * vgmstream = NULL;
|
2016-06-28 09:20:37 +02:00
|
|
|
|
|
|
|
hca_codec_data * hca_file = ( hca_codec_data * ) calloc(1, sizeof(hca_codec_data) + clHCA_sizeof());
|
2016-07-01 00:34:40 +02:00
|
|
|
void * hca_data = NULL;
|
|
|
|
clHCA * hca;
|
|
|
|
|
|
|
|
uint8_t header[8];
|
|
|
|
|
|
|
|
int header_size;
|
|
|
|
|
2016-06-28 09:20:37 +02:00
|
|
|
if ( !hca_file ) goto fail;
|
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
if ( size < 8 ) goto fail;
|
|
|
|
|
|
|
|
hca_file->streamfile = streamFile;
|
|
|
|
hca_file->start = start;
|
|
|
|
hca_file->size = size;
|
2016-06-28 09:20:37 +02:00
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
if ( read_streamfile( header, start, 8, streamFile) != 8 ) goto fail;
|
|
|
|
|
|
|
|
header_size = clHCA_isOurFile0( header );
|
2016-06-28 09:20:37 +02:00
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
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);
|
|
|
|
|
2016-12-04 14:12:23 +01:00
|
|
|
/* try to find key in external file */
|
|
|
|
{
|
|
|
|
uint8_t keybuf[8];
|
|
|
|
|
|
|
|
if ( read_key_file(keybuf, 8, streamFile) ) {
|
|
|
|
ciphKey2 = get_32bitBE(keybuf+0);
|
|
|
|
ciphKey1 = get_32bitBE(keybuf+4);
|
|
|
|
} else {
|
|
|
|
/* PSO2 */
|
|
|
|
ciphKey2=0xCC554639;
|
|
|
|
ciphKey1=0x30DBE1AB;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
clHCA_clear(hca, ciphKey1, ciphKey2);
|
2016-06-28 09:20:37 +02:00
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
if (clHCA_Decode(hca, hca_data, header_size, 0) < 0) goto fail;
|
|
|
|
|
|
|
|
free( hca_data );
|
|
|
|
hca_data = NULL;
|
2016-06-28 09:20:37 +02:00
|
|
|
|
2016-07-01 00:34:40 +02:00
|
|
|
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;
|
2016-06-28 09:20:37 +02:00
|
|
|
|
|
|
|
vgmstream = allocate_vgmstream( hca_file->info.channelCount, 1 );
|
|
|
|
if (!vgmstream) goto fail;
|
|
|
|
|
|
|
|
vgmstream->loop_flag = hca_file->info.loopEnabled;
|
2016-07-01 00:34:40 +02:00
|
|
|
vgmstream->loop_start_sample = hca_file->info.loopStart * clHCA_samplesPerBlock;
|
|
|
|
vgmstream->loop_end_sample = hca_file->info.loopEnd * clHCA_samplesPerBlock;
|
2016-06-28 09:20:37 +02:00
|
|
|
|
|
|
|
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:
|
2016-07-01 00:34:40 +02:00
|
|
|
if ( hca_data ) {
|
|
|
|
free( hca_data );
|
|
|
|
}
|
2016-06-28 09:20:37 +02:00
|
|
|
if ( hca_file ) {
|
|
|
|
free( hca_file );
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|