Update HCA decoder.

CQTexperiment
Chris Moeller 2016-06-29 22:11:18 -07:00
parent b47fe40fcd
commit cd3901f00d
3 changed files with 577 additions and 482 deletions

View File

@ -156,7 +156,7 @@ typedef struct clHCA{
unsigned int _ciph_key2; unsigned int _ciph_key2;
float _rva_volume; float _rva_volume;
unsigned int _comm_len; unsigned int _comm_len;
const char *_comm_comment; char *_comm_comment;
clATH _ath; clATH _ath;
clCipher _cipher; clCipher _cipher;
stChannel _channel[0x10]; stChannel _channel[0x10];
@ -180,6 +180,12 @@ static void clHCA_constructor(clHCA *hca,unsigned int ciphKey1,unsigned int ciph
clATH_constructor(&hca->_ath); clATH_constructor(&hca->_ath);
clCipher_constructor(&hca->_cipher); clCipher_constructor(&hca->_cipher);
hca->_validFile = 0; hca->_validFile = 0;
hca->_comm_comment = 0;
}
static void clHCA_destructor(clHCA *hca)
{
if(hca->_comm_comment){free(hca->_comm_comment);hca->_comm_comment=0;}
} }
//-------------------------------------------------- //--------------------------------------------------
@ -192,9 +198,7 @@ static int clHCA_CheckFile(void *data,unsigned int size){
//-------------------------------------------------- //--------------------------------------------------
// チェックサム // チェックサム
//-------------------------------------------------- //--------------------------------------------------
static unsigned short clHCA_CheckSum(const void *data,int size,unsigned short sum){ static const unsigned short clHCA_CheckSum_v[]={
const unsigned char *s, *e;
static const unsigned short v[]={
0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011,0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022, 0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011,0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022,
0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072,0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041, 0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072,0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041,
0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2,0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1, 0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2,0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1,
@ -212,10 +216,72 @@ static unsigned short clHCA_CheckSum(const void *data,int size,unsigned short su
0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252,0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261, 0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252,0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261,
0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231,0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202, 0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231,0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202,
}; };
for(s=(const unsigned char *)data,e=s+size;s<e;s++)sum=(sum<<8)^v[(sum>>8)^*s];
static unsigned short clHCA_CheckSum(const void *data,int size,unsigned short sum){
const unsigned char *s, *e;
for(s=(const unsigned char *)data,e=s+size;s<e;s++)sum=(sum<<8)^clHCA_CheckSum_v[(sum>>8)^*s];
return sum; return sum;
} }
//--------------------------------------------------
// データ
//--------------------------------------------------
void clData_constructor(clData *ds,const void *data,int size){
ds->_data=(const unsigned char *)data;
ds->_size=size*8;
ds->_bit=0;
}
static unsigned int clData_CheckBit(clData *ds,int bitSize){
unsigned int v=0;
if(ds->_bit+bitSize<=ds->_size){
unsigned int bitOffset=bitSize+(ds->_bit&7);
if((ds->_size-ds->_bit)>=32&&bitOffset>=25){
static const int mask[]={0xFFFFFFFF,0x7FFFFFFF,0x3FFFFFFF,0x1FFFFFFF,0x0FFFFFFF,0x07FFFFFF,0x03FFFFFF,0x01FFFFFF};
const unsigned int _bit=ds->_bit;
const unsigned char *data=&ds->_data[_bit>>3];
v=data[0];v=(v<<8)|data[1];v=(v<<8)|data[2];v=(v<<8)|data[3];
v&=mask[_bit&7];
v>>=32-(_bit&7)-bitSize;
}
else if((ds->_size-ds->_bit)>=24&&bitOffset>=17){
static const int mask[]={0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF,0x0FFFFF,0x07FFFF,0x03FFFF,0x01FFFF};
const unsigned int _bit=ds->_bit;
const unsigned char *data=&ds->_data[_bit>>3];
v=data[0];v=(v<<8)|data[1];v=(v<<8)|data[2];
v&=mask[_bit&7];
v>>=24-(_bit&7)-bitSize;
}
else if((ds->_size-ds->_bit)>=16&&bitOffset>=9){
static const int mask[]={0xFFFF,0x7FFF,0x3FFF,0x1FFF,0x0FFF,0x07FF,0x03FF,0x01FF};
const unsigned int _bit=ds->_bit;
const unsigned char *data=&ds->_data[_bit>>3];
v=data[0];v=(v<<8)|data[1];
v&=mask[_bit&7];
v>>=16-(_bit&7)-bitSize;
}
else{
static const int mask[]={0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01};
const unsigned int _bit=ds->_bit;
const unsigned char *data=&ds->_data[_bit>>3];
v=data[0];
v&=mask[_bit&7];
v>>=8-(_bit&7)-bitSize;
}
}
return v;
}
static unsigned int clData_GetBit(clData *ds,int bitSize){
unsigned int v=clData_CheckBit(ds,bitSize);
ds->_bit+=bitSize;
return v;
}
static void clData_AddBit(clData *ds,int bitSize){
ds->_bit+=bitSize;
}
//-------------------------------------------------- //--------------------------------------------------
// ヘッダ情報をコンソール出力 // ヘッダ情報をコンソール出力
//-------------------------------------------------- //--------------------------------------------------
@ -224,8 +290,8 @@ static int clHCA_PrintInfo(const char *filenameHCA){
FILE *fp; FILE *fp;
stHeader header; stHeader header;
unsigned char *data; unsigned char *data;
unsigned char *s;
unsigned int size; unsigned int size;
clData d;
// temporaries, so we don't need a state structure // temporaries, so we don't need a state structure
unsigned int _version; unsigned int _version;
@ -258,7 +324,7 @@ static int clHCA_PrintInfo(const char *filenameHCA){
unsigned int _ciph_key2; unsigned int _ciph_key2;
float _rva_volume; float _rva_volume;
unsigned int _comm_len; unsigned int _comm_len;
const char *_comm_comment; char *_comm_comment;
// チェック // チェック
if(!(filenameHCA))return -1; if(!(filenameHCA))return -1;
@ -278,7 +344,9 @@ static int clHCA_PrintInfo(const char *filenameHCA){
} }
// ヘッダ解析 // ヘッダ解析
header.dataOffset=get_be16(header.dataOffset); clData_constructor(&d, &header, sizeof(header));
clData_AddBit(&d, 32);
header.dataOffset=clData_CheckBit(&d, 16);
data=(unsigned char*) malloc(header.dataOffset); data=(unsigned char*) malloc(header.dataOffset);
if(!data){ if(!data){
printf("Error: メモリ不足です。\n"); printf("Error: メモリ不足です。\n");
@ -287,9 +355,10 @@ static int clHCA_PrintInfo(const char *filenameHCA){
fseek(fp,0,SEEK_SET); fseek(fp,0,SEEK_SET);
fread(data,header.dataOffset,1,fp); fread(data,header.dataOffset,1,fp);
s=(unsigned char *)data;
size=header.dataOffset; size=header.dataOffset;
clData_constructor(&d, data, size);
// サイズチェック // サイズチェック
if(size<sizeof(stHeader)){ if(size<sizeof(stHeader)){
printf("Error: ヘッダのサイズが小さすぎます。\n"); printf("Error: ヘッダのサイズが小さすぎます。\n");
@ -297,27 +366,27 @@ static int clHCA_PrintInfo(const char *filenameHCA){
} }
// HCA // HCA
if(size>=sizeof(stHeader) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00414348){ if(size>=sizeof(stHeader) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='HCA\0'){
stHeader *hca=(stHeader *)s;s+=sizeof(stHeader); clData_AddBit(&d,32);
_version=get_be16(hca->version); _version=clData_GetBit(&d,16);
_dataOffset=get_be16(hca->dataOffset); _dataOffset=clData_GetBit(&d,16);
printf("コーデック: HCA\n"); printf("コーデック: HCA\n");
printf("バージョン: %d.%d\n",_version>>8,_version&0xFF); printf("バージョン: %d.%d\n",_version>>8,_version&0xFF);
//if(size<_dataOffset)return -1; //if(size<_dataOffset)return -1;
if(clHCA_CheckSum(hca,_dataOffset,0))printf("※ ヘッダが破損しています。改変してる場合もこの警告が出ます。\n"); if(clHCA_CheckSum(data,_dataOffset,0))printf("※ ヘッダが破損しています。改変してる場合もこの警告が出ます。\n");
size-=sizeof(stHeader); size-=(16+16+32)/8;
}else{ }else{
printf("※ HCAチャンクがありません。再生に必要な情報です。\n"); printf("※ HCAチャンクがありません。再生に必要な情報です。\n");
} }
// fmt // fmt
if(size>=sizeof(stFormat) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00746D66){ if(size>=sizeof(stFormat) && (clData_CheckBit(&d, 32)&0x7F7F7F7F)=='fmt\0'){
stFormat *fmt=(stFormat *)s;s+=sizeof(stFormat);size-=sizeof(stFormat); clData_AddBit(&d,32);
_channelCount=fmt->channelCount; _channelCount=clData_GetBit(&d,8);
_samplingRate=get_be24(fmt->samplingRate); _samplingRate=clData_GetBit(&d,24);
_blockCount=get_be32(fmt->blockCount); _blockCount=clData_GetBit(&d,32);
_fmt_r01=get_be16(fmt->r01); _fmt_r01=clData_GetBit(&d,16);
_fmt_r02=get_be16(fmt->r02); _fmt_r02=clData_GetBit(&d,16);
switch(_channelCount){ switch(_channelCount){
case 1:printf("チャンネル数: モノラル (1チャンネル)\n");break; case 1:printf("チャンネル数: モノラル (1チャンネル)\n");break;
case 2:printf("チャンネル数: ステレオ (2チャンネル)\n");break; case 2:printf("チャンネル数: ステレオ (2チャンネル)\n");break;
@ -333,22 +402,24 @@ static int clHCA_PrintInfo(const char *filenameHCA){
printf("ブロック数: %d\n",_blockCount); printf("ブロック数: %d\n",_blockCount);
printf("先頭無音ブロック数: %d\n",(_fmt_r01-0x80)/0x400); printf("先頭無音ブロック数: %d\n",(_fmt_r01-0x80)/0x400);
printf("末尾無音サンプル数?: %d\n",_fmt_r02); printf("末尾無音サンプル数?: %d\n",_fmt_r02);
size-=(16+16+32+24+8+32)/8;
}else{ }else{
printf("※ fmtチャンクがありません。再生に必要な情報です。\n"); printf("※ fmtチャンクがありません。再生に必要な情報です。\n");
} }
// comp // comp
if(size>=sizeof(stCompress) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x706D6F63){ if(size>=sizeof(stCompress) && (clData_CheckBit(&d, 32)&0x7F7F7F7F)=='comp'){
stCompress *comp=(stCompress *)s;s+=sizeof(stCompress);size-=sizeof(stCompress); clData_AddBit(&d,32);
_blockSize=get_be16(comp->blockSize); _blockSize=clData_GetBit(&d,16);
_comp_r01=comp->r01; _comp_r01=clData_GetBit(&d,8);
_comp_r02=comp->r02; _comp_r02=clData_GetBit(&d,8);
_comp_r03=comp->r03; _comp_r03=clData_GetBit(&d,8);
_comp_r04=comp->r04; _comp_r04=clData_GetBit(&d,8);
_comp_r05=comp->r05; _comp_r05=clData_GetBit(&d,8);
_comp_r06=comp->r06; _comp_r06=clData_GetBit(&d,8);
_comp_r07=comp->r07; _comp_r07=clData_GetBit(&d,8);
_comp_r08=comp->r08; _comp_r08=clData_GetBit(&d,8);
clData_AddBit(&d,8+8);
printf("ビットレート: CBR (固定ビットレート)\n"); printf("ビットレート: CBR (固定ビットレート)\n");
printf("ブロックサイズ: 0x%04X\n",_blockSize); printf("ブロックサイズ: 0x%04X\n",_blockSize);
if(!(_blockSize>=8&&_blockSize<=0xFFFF)){ if(!(_blockSize>=8&&_blockSize<=0xFFFF)){
@ -368,18 +439,23 @@ static int clHCA_PrintInfo(const char *filenameHCA){
printf("comp6: %d\n",_comp_r06); printf("comp6: %d\n",_comp_r06);
printf("comp7: %d\n",_comp_r07); printf("comp7: %d\n",_comp_r07);
printf("comp8: %d\n",_comp_r08); printf("comp8: %d\n",_comp_r08);
size-=(32+16+8*8)/8;
} }
// dec // dec
else if(size>=sizeof(stDecode) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00636564){ else if(size>=sizeof(stDecode) && (clData_CheckBit(&d, 32)&0x7F7F7F7F)=='dec\0'){
stDecode *dec=(stDecode *)s;s+=sizeof(stDecode);size-=sizeof(stDecode); unsigned char count1,count2,enableCount2;
_blockSize=get_be16(dec->blockSize); clData_AddBit(&d, 32);
_comp_r01=dec->r01; _blockSize=clData_GetBit(&d,16);
_comp_r02=dec->r02; _comp_r01=clData_GetBit(&d,8);
_comp_r03=dec->r04; _comp_r02=clData_GetBit(&d,8);
_comp_r04=dec->r03; count1=clData_GetBit(&d,8);
_comp_r05=dec->count1+1; count2=clData_GetBit(&d,8);
_comp_r06=((dec->enableCount2)?dec->count2:dec->count1)+1; _comp_r03=clData_GetBit(&d,4);
_comp_r04=clData_GetBit(&d,4);
enableCount2=clData_GetBit(&d,8);
_comp_r05=count1+1;
_comp_r06=((enableCount2)?count2:count1)+1;
_comp_r07=_comp_r05-_comp_r06; _comp_r07=_comp_r05-_comp_r06;
_comp_r08=0; _comp_r08=0;
printf("ビットレート: CBR (固定ビットレート)\n"); printf("ビットレート: CBR (固定ビットレート)\n");
@ -400,15 +476,16 @@ static int clHCA_PrintInfo(const char *filenameHCA){
printf("dec5: %d\n",_comp_r05); printf("dec5: %d\n",_comp_r05);
printf("dec6: %d\n",_comp_r06); printf("dec6: %d\n",_comp_r06);
printf("dec7: %d\n",_comp_r07); printf("dec7: %d\n",_comp_r07);
size-=(8+4+4+8+8+8+8+16+32)/8;
}else{ }else{
printf("※ compチャンクまたはdecチャンクがありません。再生に必要な情報です。\n"); printf("※ compチャンクまたはdecチャンクがありません。再生に必要な情報です。\n");
} }
// vbr // vbr
if(size>=sizeof(stVBR) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00726276){ if(size>=sizeof(stVBR) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='vbr\0'){
stVBR *vbr=(stVBR *)s;s+=sizeof(stVBR);size-=sizeof(stVBR); clData_AddBit(&d, 32);
_vbr_r01=get_be16(vbr->r01); _vbr_r01=clData_GetBit(&d,16);
_vbr_r02=get_be16(vbr->r02); _vbr_r02=clData_GetBit(&d,16);
printf("ビットレート: VBR (可変ビットレート) ※v2.0で廃止されています。\n"); printf("ビットレート: VBR (可変ビットレート) ※v2.0で廃止されています。\n");
if(!(_blockSize==0)){ if(!(_blockSize==0)){
printf("※ compまたはdecチャンクですでにCBRが指定されています。\n"); printf("※ compまたはdecチャンクですでにCBRが指定されています。\n");
@ -418,16 +495,18 @@ static int clHCA_PrintInfo(const char *filenameHCA){
printf("※ vbr1の範囲は0〜511(0x1FF)です。\n"); printf("※ vbr1の範囲は0〜511(0x1FF)です。\n");
} }
printf("vbr2: %d\n",_vbr_r02); printf("vbr2: %d\n",_vbr_r02);
size-=(16+16+32)/8;
}else{ }else{
_vbr_r01=0; _vbr_r01=0;
_vbr_r02=0; _vbr_r02=0;
} }
// ath // ath
if(size>=6 && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00687461){ if(size>=6 && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='ath\0'){
stATH *ath=(stATH *)s;s+=6;size-=6;//s+=sizeof(stATH); clData_AddBit(&d,32);
_ath_type=ath->type; _ath_type=clData_GetBit(&d,16);
printf("ATHタイプ:%d ※v2.0から廃止されています。\n",_ath_type); printf("ATHタイプ:%d ※v2.0から廃止されています。\n",_ath_type);
size-=(16+32)/8;
}else{ }else{
if(_version<0x200){ if(_version<0x200){
printf("ATHタイプ:1 ※v2.0から廃止されています。\n"); printf("ATHタイプ:1 ※v2.0から廃止されています。\n");
@ -435,12 +514,12 @@ static int clHCA_PrintInfo(const char *filenameHCA){
} }
// loop // loop
if(size>=sizeof(stLoop) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x706F6F6C){ if(size>=sizeof(stLoop) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='loop'){
stLoop *loop=(stLoop *)s;s+=sizeof(stLoop);size-=sizeof(stLoop); clData_AddBit(&d, 32);
_loopStart=get_be32(loop->loopStart); _loopStart=clData_GetBit(&d,32);
_loopEnd=get_be32(loop->loopEnd); _loopEnd=clData_GetBit(&d,32);
_loop_r01=get_be16(loop->r01); _loop_r01=clData_GetBit(&d,16);
_loop_r02=get_be16(loop->r02); _loop_r02=clData_GetBit(&d,16);
printf("ループ開始ブロック: %d\n",_loopStart); printf("ループ開始ブロック: %d\n",_loopStart);
printf("ループ終了ブロック: %d\n",_loopEnd); printf("ループ終了ブロック: %d\n",_loopEnd);
if(!(_loopStart>=0&&_loopStart<=_loopEnd&&_loopEnd<_blockCount)){ if(!(_loopStart>=0&&_loopStart<=_loopEnd&&_loopEnd<_blockCount)){
@ -448,12 +527,13 @@ static int clHCA_PrintInfo(const char *filenameHCA){
} }
printf("ループ情報1: %d\n",_loop_r01); printf("ループ情報1: %d\n",_loop_r01);
printf("ループ情報2: %d\n",_loop_r02); printf("ループ情報2: %d\n",_loop_r02);
size-=(16+16+32+32+32)/8;
} }
hca-> // ciph // ciph
if(size>=6 && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x68706963){ if(size>=6 && (clData_CheckBit(&d, 32)&0x7F7F7F7F)=='ciph'){
stCipher *ciph=(stCipher *)s;s+=6;size-=6;//s+=sizeof(stCipher); clData_AddBit(&d,32);
_ciph_type=get_be16(ciph->type); _ciph_type=clData_GetBit(&d,16);
switch(_ciph_type){ switch(_ciph_type){
case 0:printf("暗号化タイプ: なし\n");break; case 0:printf("暗号化タイプ: なし\n");break;
case 1:printf("暗号化タイプ: 鍵無し暗号化\n");break; case 1:printf("暗号化タイプ: 鍵無し暗号化\n");break;
@ -463,21 +543,29 @@ hca-> // ciph
if(!(_ciph_type==0||_ciph_type==1||_ciph_type==0x38)){ if(!(_ciph_type==0||_ciph_type==1||_ciph_type==0x38)){
printf("※ この暗号化タイプは、v2.0現在再生できません。\n"); printf("※ この暗号化タイプは、v2.0現在再生できません。\n");
} }
size-=6;
} }
// rva // rva
if(size>=sizeof(stRVA) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00617672){ if(size>=sizeof(stRVA) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='rva\0'){
stRVA *rva=(stRVA *)s;s+=sizeof(stRVA);size-=sizeof(stRVA); union { unsigned int i; float f; } v;
_rva_volume=get_bef32(rva->volume); clData_AddBit(&d,32);
v.i=clData_GetBit(&d,32);
_rva_volume=v.f;
printf("相対ボリューム調節: %g倍\n",_rva_volume); printf("相対ボリューム調節: %g倍\n",_rva_volume);
size-=(32+32)/8;
} }
// comm // comm
if(size>=5 && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x6D6D6F63){ if(size>=5 && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='comm'){
stComment *comm=(stComment *)s;s+=5;size-=5;//s+=sizeof(stComment); int i;
_comm_len=comm->len; clData_AddBit(&d,32);
_comm_comment=(const char *)s; _comm_len=clData_GetBit(&d,8);
_comm_comment=malloc(_comm_len+1);
for(i=0;i<_comm_len;++i)_comm_comment[i]=clData_GetBit(&d,8);
_comm_comment[i]='\0';
printf("コメント: %s\n",_comm_comment); printf("コメント: %s\n",_comm_comment);
free(_comm_comment);
} }
free(data); free(data);
@ -668,10 +756,11 @@ int clHCA_DecodeToWavefile_Decode(clHCA *hca,void *fp1,void *fp2,unsigned int ad
//-------------------------------------------------- //--------------------------------------------------
int clHCA_isOurFile0(const void *data){ int clHCA_isOurFile0(const void *data){
const unsigned char *s=(const unsigned char*)data; clData d;
if((get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00414348){ clData_constructor(&d, data, 8);
const stHeader *hca=(const stHeader *)s; if((clData_CheckBit(&d,32)&0x7F7F7F7F)=='HCA\0'){
return get_be16(hca->dataOffset); clData_AddBit(&d,32+16);
return clData_CheckBit(&d,16);
} }
return -1; return -1;
} }
@ -696,6 +785,7 @@ int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info){
info->loopEnabled=hca->_loopFlg; info->loopEnabled=hca->_loopFlg;
info->loopStart=hca->_loopStart; info->loopStart=hca->_loopStart;
info->loopEnd=hca->_loopEnd; info->loopEnd=hca->_loopEnd;
info->comment=hca->_comm_comment;
return 0; return 0;
} }
@ -729,6 +819,11 @@ void clHCA_clear(clHCA *hca,unsigned int ciphKey1,unsigned int ciphKey2){
clHCA_constructor(hca,ciphKey1,ciphKey2); clHCA_constructor(hca,ciphKey1,ciphKey2);
} }
void clHCA_done(clHCA *hca)
{
clHCA_destructor(hca);
}
clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2){ clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2){
clHCA *hca = (clHCA *) malloc(clHCA_sizeof()); clHCA *hca = (clHCA *) malloc(clHCA_sizeof());
if (hca){ if (hca){
@ -738,8 +833,11 @@ clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2){
} }
void clHCA_delete(clHCA *hca){ void clHCA_delete(clHCA *hca){
if (hca){
clHCA_destructor(hca);
free(hca); free(hca);
} }
}
//-------------------------------------------------- //--------------------------------------------------
// ATH // ATH
@ -769,10 +867,7 @@ void clATH_Init0(clATH *ath){
memset(ath->_table,0,sizeof(ath->_table)); memset(ath->_table,0,sizeof(ath->_table));
} }
void clATH_Init1(clATH *ath, unsigned int key){ static const unsigned char clATH_list[]={
unsigned int i, v;
unsigned char *_table=ath->_table;
static const unsigned char list[]={
0x78,0x5F,0x56,0x51,0x4E,0x4C,0x4B,0x49,0x48,0x48,0x47,0x46,0x46,0x45,0x45,0x45, 0x78,0x5F,0x56,0x51,0x4E,0x4C,0x4B,0x49,0x48,0x48,0x47,0x46,0x46,0x45,0x45,0x45,
0x44,0x44,0x44,0x44,0x43,0x43,0x43,0x43,0x43,0x43,0x42,0x42,0x42,0x42,0x42,0x42, 0x44,0x44,0x44,0x44,0x43,0x43,0x43,0x43,0x43,0x43,0x42,0x42,0x42,0x42,0x42,0x42,
0x42,0x42,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x40,0x40,0x40,0x40, 0x42,0x42,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x40,0x40,0x40,0x40,
@ -815,13 +910,17 @@ void clATH_Init1(clATH *ath, unsigned int key){
0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xED,0xEE, 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,
0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFF,0xFF, 0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFF,0xFF,
}; };
void clATH_Init1(clATH *ath, unsigned int key){
unsigned int i, v;
unsigned char *_table=ath->_table;
for(i=0,v=0;i<0x80;i++,v+=key){ for(i=0,v=0;i<0x80;i++,v+=key){
unsigned int index=v>>13; unsigned int index=v>>13;
if(index>=0x28E){ if(index>=0x28E){
memset(&_table[i],0xFF,0x80-i); memset(&_table[i],0xFF,0x80-i);
break; break;
} }
_table[i]=list[index]; _table[i]=clATH_list[index];
} }
} }
@ -936,38 +1035,6 @@ void clCipher_Init56_CreateTable(unsigned char *r,unsigned char key){
} }
} }
//--------------------------------------------------
// データ
//--------------------------------------------------
void clData_constructor(clData *ds,const void *data,int size){
ds->_data=(const unsigned char *)data;
ds->_size=size*8-16;
ds->_bit=0;
}
static int clData_CheckBit(clData *ds,int bitSize){
int v=0;
if(ds->_bit+bitSize<=ds->_size){
static const int mask[]={0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF,0x0FFFFF,0x07FFFF,0x03FFFF,0x01FFFF};
const unsigned int _bit=ds->_bit;
const unsigned char *data=&ds->_data[_bit>>3];
v=data[0];v=(v<<8)|data[1];v=(v<<8)|data[2];
v&=mask[_bit&7];
v>>=24-(_bit&7)-bitSize;
}
return v;
}
static int clData_GetBit(clData *ds,int bitSize){
int v=clData_CheckBit(ds,bitSize);
ds->_bit+=bitSize;
return v;
}
static void clData_AddBit(clData *ds,int bitSize){
ds->_bit+=bitSize;
}
//-------------------------------------------------- //--------------------------------------------------
// デコード // デコード
//-------------------------------------------------- //--------------------------------------------------
@ -984,22 +1051,22 @@ int clHCA_Decode(clHCA *hca,void *data,unsigned int size,unsigned int address){
// ヘッダ // ヘッダ
if(address==0){ if(address==0){
const unsigned char *s;
char r[0x10]; char r[0x10];
unsigned int i, b; unsigned int i, b;
clData d;
hca->_validFile = 0; hca->_validFile = 0;
s=(const unsigned char *)data; clData_constructor(&d, data, size);
// サイズチェック // サイズチェック
if(size<sizeof(stHeader))return -1; if(size<sizeof(stHeader))return -1;
// HCA // HCA
if((get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00414348){ if((clData_CheckBit(&d,32)&0x7F7F7F7F)=='HCA\0'){
const stHeader *h=(const stHeader *)s;s+=sizeof(stHeader); clData_AddBit(&d,32);
hca->_version=get_be16(h->version); hca->_version=clData_GetBit(&d,16);
hca->_dataOffset=get_be16(h->dataOffset); hca->_dataOffset=clData_GetBit(&d,16);
//if(!(_version<=0x200&&_version>0x101))return -1; // バージョンチェック(無効) //if(!(_version<=0x200&&_version>0x101))return -1; // バージョンチェック(無効)
if(size<hca->_dataOffset)return -1; if(size<hca->_dataOffset)return -1;
//if(clHCA_CheckSum(hca,_dataOffset,0))return -1; // ヘッダの破損チェック(ヘッダ改変を有効にするため破損チェック無効) //if(clHCA_CheckSum(hca,_dataOffset,0))return -1; // ヘッダの破損チェック(ヘッダ改変を有効にするため破損チェック無効)
@ -1009,59 +1076,67 @@ int clHCA_Decode(clHCA *hca,void *data,unsigned int size,unsigned int address){
} }
// fmt // fmt
if(size>=sizeof(stFormat) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00746D66){ if(size>=sizeof(stFormat) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='fmt\0'){
const stFormat *fmt=(const stFormat *)s;s+=sizeof(stFormat);size-=sizeof(stFormat); clData_AddBit(&d,32);
hca->_channelCount=fmt->channelCount; hca->_channelCount=clData_GetBit(&d,8);
hca->_samplingRate=get_be24(fmt->samplingRate); hca->_samplingRate=clData_GetBit(&d,24);
hca->_blockCount=get_be32(fmt->blockCount); hca->_blockCount=clData_GetBit(&d,32);
hca->_fmt_r01=get_be16(fmt->r01); hca->_fmt_r01=clData_GetBit(&d,16);
hca->_fmt_r02=get_be16(fmt->r02); hca->_fmt_r02=clData_GetBit(&d,16);
if(!(hca->_channelCount>=1&&hca->_channelCount<=16))return -1; if(!(hca->_channelCount>=1&&hca->_channelCount<=16))return -1;
if(!(hca->_samplingRate>=1&&hca->_samplingRate<=0x7FFFFF))return -1; if(!(hca->_samplingRate>=1&&hca->_samplingRate<=0x7FFFFF))return -1;
size-=sizeof(stFormat);
}else{ }else{
return -1; return -1;
} }
// comp // comp
if(size>=sizeof(stCompress) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x706D6F63){ if(size>=sizeof(stCompress) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='comp'){
const stCompress *comp=(const stCompress *)s;s+=sizeof(stCompress);size-=sizeof(stCompress); clData_AddBit(&d,32);
hca->_blockSize=get_be16(comp->blockSize); hca->_blockSize=clData_GetBit(&d,16);
hca->_comp_r01=comp->r01; hca->_comp_r01=clData_GetBit(&d,8);
hca->_comp_r02=comp->r02; hca->_comp_r02=clData_GetBit(&d,8);
hca->_comp_r03=comp->r03; hca->_comp_r03=clData_GetBit(&d,8);
hca->_comp_r04=comp->r04; hca->_comp_r04=clData_GetBit(&d,8);
hca->_comp_r05=comp->r05; hca->_comp_r05=clData_GetBit(&d,8);
hca->_comp_r06=comp->r06; hca->_comp_r06=clData_GetBit(&d,8);
hca->_comp_r07=comp->r07; hca->_comp_r07=clData_GetBit(&d,8);
hca->_comp_r08=comp->r08; hca->_comp_r08=clData_GetBit(&d,8);
clData_AddBit(&d,8+8);
if(!((hca->_blockSize>=8&&hca->_blockSize<=0xFFFF)||(hca->_blockSize==0)))return -1; if(!((hca->_blockSize>=8&&hca->_blockSize<=0xFFFF)||(hca->_blockSize==0)))return -1;
if(!(/*hca->_comp_r01>=0&&*/hca->_comp_r01<=hca->_comp_r02&&hca->_comp_r02<=0x1F))return -1; if(!(/*hca->_comp_r01>=0&&*/hca->_comp_r01<=hca->_comp_r02&&hca->_comp_r02<=0x1F))return -1;
size-=sizeof(stCompress);
} }
// dec // dec
else if(size>=sizeof(stDecode) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00636564){ else if(size>=sizeof(stDecode) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='dec\0'){
const stDecode *dec=(const stDecode *)s;s+=sizeof(stDecode);size-=sizeof(stDecode); unsigned char count1,count2,enableCount2;
hca->_blockSize=get_be16(dec->blockSize); clData_AddBit(&d,32);
hca->_comp_r01=dec->r01; hca->_blockSize=clData_GetBit(&d,16);
hca->_comp_r02=dec->r02; hca->_comp_r01=clData_GetBit(&d,8);
hca->_comp_r03=dec->r04; hca->_comp_r02=clData_GetBit(&d,8);
hca->_comp_r04=dec->r03; count1=clData_GetBit(&d,8);
hca->_comp_r05=dec->count1+1; count2=clData_GetBit(&d,8);
hca->_comp_r06=((dec->enableCount2)?dec->count2:dec->count1)+1; hca->_comp_r03=clData_GetBit(&d,4);
hca->_comp_r04=clData_GetBit(&d,4);
enableCount2=clData_GetBit(&d,8);
hca->_comp_r05=count1+1;
hca->_comp_r06=((enableCount2)?count2:count1)+1;
hca->_comp_r07=hca->_comp_r05-hca->_comp_r06; hca->_comp_r07=hca->_comp_r05-hca->_comp_r06;
hca->_comp_r08=0; hca->_comp_r08=0;
if(!((hca->_blockSize>=8&&hca->_blockSize<=0xFFFF)||(hca->_blockSize==0)))return -1; if(!((hca->_blockSize>=8&&hca->_blockSize<=0xFFFF)||(hca->_blockSize==0)))return -1;
if(!(/*hca->_comp_r01>=0&&*/hca->_comp_r01<=hca->_comp_r02&&hca->_comp_r02<=0x1F))return -1; if(!(/*hca->_comp_r01>=0&&*/hca->_comp_r01<=hca->_comp_r02&&hca->_comp_r02<=0x1F))return -1;
if(!hca->_comp_r03)hca->_comp_r03=1; if(!hca->_comp_r03)hca->_comp_r03=1;
size-=sizeof(stDecode);
}else{ }else{
return -1; return -1;
} }
// vbr // vbr
if(size>=sizeof(stVBR) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00726276){ if(size>=sizeof(stVBR) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='vbr\0'){
const stVBR *vbr=(const stVBR *)s;s+=sizeof(stVBR);size-=sizeof(stVBR); clData_AddBit(&d,32);
hca->_vbr_r01=get_be16(vbr->r01); hca->_vbr_r01=clData_GetBit(&d,16);
hca->_vbr_r02=get_be16(vbr->r02); hca->_vbr_r02=clData_GetBit(&d,16);
if(!(hca->_blockSize==0&&/*hca->_vbr_r01>=0&&*/hca->_vbr_r01<=0x1FF))return -1; if(!(hca->_blockSize==0&&/*hca->_vbr_r01>=0&&*/hca->_vbr_r01<=0x1FF))return -1;
}else{ }else{
hca->_vbr_r01=0; hca->_vbr_r01=0;
@ -1069,22 +1144,23 @@ int clHCA_Decode(clHCA *hca,void *data,unsigned int size,unsigned int address){
} }
// ath // ath
if(size>=6 && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00687461){ if(size>=6 && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='ath\0'){
const stATH *ath=(const stATH *)s;s+=6;size-=6;//s+=sizeof(stATH); clData_AddBit(&d,32);
hca->_ath_type=ath->type; hca->_ath_type=clData_GetBit(&d,16);
}else{ }else{
hca->_ath_type=(hca->_version<0x200)?1:0;//v1.3ではデフォルト値が1になってたが、v2.0からATHテーブルが廃止されてるみたいなので0に hca->_ath_type=(hca->_version<0x200)?1:0;//v1.3ではデフォルト値が1になってたが、v2.0からATHテーブルが廃止されてるみたいなので0に
} }
// loop // loop
if(size>=sizeof(stLoop) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x706F6F6C){ if(size>=sizeof(stLoop) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='loop'){
const stLoop *loop=(const stLoop *)s;s+=sizeof(stLoop);size-=sizeof(stLoop); clData_AddBit(&d,32);
hca->_loopStart=get_be32(loop->loopStart); hca->_loopStart=clData_GetBit(&d,32);
hca->_loopEnd=get_be32(loop->loopEnd); hca->_loopEnd=clData_GetBit(&d,32);
hca->_loop_r01=get_be16(loop->r01); hca->_loop_r01=clData_GetBit(&d,16);
hca->_loop_r02=get_be16(loop->r02); hca->_loop_r02=clData_GetBit(&d,16);
hca->_loopFlg=1; hca->_loopFlg=1;
if(!(/*hca->_loopStart>=0&&*/hca->_loopStart<=hca->_loopEnd&&hca->_loopEnd<hca->_blockCount))return -1; if(!(/*hca->_loopStart>=0&&*/hca->_loopStart<=hca->_loopEnd&&hca->_loopEnd<hca->_blockCount))return -1;
size-=sizeof(stLoop);
}else{ }else{
hca->_loopStart=0; hca->_loopStart=0;
hca->_loopEnd=0; hca->_loopEnd=0;
@ -1094,29 +1170,40 @@ int clHCA_Decode(clHCA *hca,void *data,unsigned int size,unsigned int address){
} }
// ciph // ciph
if(size>=6 && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x68706963){ if(size>=6 && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='ciph'){
const stCipher *ciph=(const stCipher *)s;s+=6;size-=6;//s+=sizeof(stCipher); clData_AddBit(&d,32);
hca->_ciph_type=get_be16(ciph->type); hca->_ciph_type=clData_GetBit(&d,16);
if(!(hca->_ciph_type==0||hca->_ciph_type==1||hca->_ciph_type==0x38))return -1; if(!(hca->_ciph_type==0||hca->_ciph_type==1||hca->_ciph_type==0x38))return -1;
size-=6;
}else{ }else{
hca->_ciph_type=0; hca->_ciph_type=0;
} }
// rva // rva
if(size>=sizeof(stRVA) && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x00617672){ if(size>=sizeof(stRVA) && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='rva\0'){
const stRVA *rva=(const stRVA *)s;s+=sizeof(stRVA);size-=sizeof(stRVA); union { unsigned int i; float f; } v;
hca->_rva_volume=get_bef32(rva->volume); clData_AddBit(&d,32);
v.i=clData_GetBit(&d,32);
hca->_rva_volume=v.f;
size-=sizeof(stRVA);
}else{ }else{
hca->_rva_volume=1; hca->_rva_volume=1;
} }
// comm // comm
if(size>=5 && (get_le32(*(unsigned int *)s)&0x7F7F7F7F)==0x6D6D6F63){ if(size>=5 && (clData_CheckBit(&d,32)&0x7F7F7F7F)=='comm'){
const stComment *comm=(const stComment *)s;s+=5;size-=5;//s+=sizeof(stComment); void * newmem;
hca->_comm_len=comm->len; int i;
clData_AddBit(&d,32);
hca->_comm_len=clData_GetBit(&d,8);
if(hca->_comm_len>size)return -1; if(hca->_comm_len>size)return -1;
hca->_comm_comment=(char *)s; newmem=realloc(hca->_comm_comment,hca->_comm_len+1);
s+=hca->_comm_len;size-=hca->_comm_len; if(!newmem)return -1;
hca->_comm_comment=(char *)newmem;
for(i=0;i<hca->_comm_len;++i)
((char *)newmem)[i]=clData_GetBit(&d,8);
((char *)newmem)[i]='\0';
size-=5+hca->_comm_len;
}else{ }else{
hca->_comm_len=0; hca->_comm_len=0;
hca->_comm_comment=NULL; hca->_comm_comment=NULL;
@ -1192,8 +1279,7 @@ int clHCA_Decode(clHCA *hca,void *data,unsigned int size,unsigned int address){
// デコード第一段階 // デコード第一段階
// ベースデータの読み込み // ベースデータの読み込み
//-------------------------------------------------- //--------------------------------------------------
void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const unsigned char *ath){ static const unsigned char stChannel_Decode1_scalelist[]={
static const unsigned char scalelist[]={
// v2.0 // v2.0
0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0D,0x0D, 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0D,0x0D,
0x0D,0x0D,0x0D,0x0D,0x0C,0x0C,0x0C,0x0C, 0x0D,0x0D,0x0D,0x0D,0x0C,0x0C,0x0C,0x0C,
@ -1213,7 +1299,7 @@ void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const uns
//0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02, //0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02,
//0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01, //0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
}; };
static const unsigned int valueInt[]={ static const unsigned int stChannel_Decode1_valueInt[]={
0x342A8D26,0x34633F89,0x3497657D,0x34C9B9BE,0x35066491,0x353311C4,0x356E9910,0x359EF532, 0x342A8D26,0x34633F89,0x3497657D,0x34C9B9BE,0x35066491,0x353311C4,0x356E9910,0x359EF532,
0x35D3CCF1,0x360D1ADF,0x363C034A,0x367A83B3,0x36A6E595,0x36DE60F5,0x371426FF,0x3745672A, 0x35D3CCF1,0x360D1ADF,0x363C034A,0x367A83B3,0x36A6E595,0x36DE60F5,0x371426FF,0x3745672A,
0x37838359,0x37AF3B79,0x37E97C38,0x381B8D3A,0x384F4319,0x388A14D5,0x38B7FBF0,0x38F5257D, 0x37838359,0x37AF3B79,0x37E97C38,0x381B8D3A,0x384F4319,0x388A14D5,0x38B7FBF0,0x38F5257D,
@ -1223,12 +1309,14 @@ void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const uns
0x3E1C6573,0x3E506334,0x3E8AD4C6,0x3EB8FBAF,0x3EF67A41,0x3F243516,0x3F5ACB94,0x3F91C3D3, 0x3E1C6573,0x3E506334,0x3E8AD4C6,0x3EB8FBAF,0x3EF67A41,0x3F243516,0x3F5ACB94,0x3F91C3D3,
0x3FC238D2,0x400164D2,0x402C6897,0x4065B907,0x40990B88,0x40CBEC15,0x4107DB35,0x413504F3, 0x3FC238D2,0x400164D2,0x402C6897,0x4065B907,0x40990B88,0x40CBEC15,0x4107DB35,0x413504F3,
}; };
static const unsigned int scaleInt[]={ static const unsigned int stChannel_Decode1_scaleInt[]={
0x00000000,0x3F2AAAAB,0x3ECCCCCD,0x3E924925,0x3E638E39,0x3E3A2E8C,0x3E1D89D9,0x3E088889, 0x00000000,0x3F2AAAAB,0x3ECCCCCD,0x3E924925,0x3E638E39,0x3E3A2E8C,0x3E1D89D9,0x3E088889,
0x3D842108,0x3D020821,0x3C810204,0x3C008081,0x3B804020,0x3B002008,0x3A801002,0x3A000801, 0x3D842108,0x3D020821,0x3C810204,0x3C008081,0x3B804020,0x3B002008,0x3A801002,0x3A000801,
}; };
static const float *valueFloat=(const float *)valueInt; static const float *stChannel_Decode1_valueFloat=(const float *)stChannel_Decode1_valueInt;
static const float *scaleFloat=(const float *)scaleInt; static const float *stChannel_Decode1_scaleFloat=(const float *)stChannel_Decode1_scaleInt;
void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const unsigned char *ath){
unsigned int i; unsigned int i;
const unsigned int count=ch->count; const unsigned int count=ch->count;
char *value=ch->value; char *value=ch->value;
@ -1262,23 +1350,22 @@ void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const uns
v=ath[i]+((b+i)>>8)-((v*5)>>1)+1; v=ath[i]+((b+i)>>8)-((v*5)>>1)+1;
if(v<0)v=15; if(v<0)v=15;
else if(v>=0x39)v=1; else if(v>=0x39)v=1;
else v=scalelist[v]; else v=stChannel_Decode1_scalelist[v];
} }
scale[i]=v; scale[i]=v;
} }
memset(&scale[count],0,0x80-count); memset(&scale[count],0,0x80-count);
for(i=0;i<count;i++)base[i]=valueFloat[value[i]]*scaleFloat[scale[i]]; for(i=0;i<count;i++)base[i]=stChannel_Decode1_valueFloat[value[i]]*stChannel_Decode1_scaleFloat[scale[i]];
} }
//-------------------------------------------------- //--------------------------------------------------
// デコード第二段階 // デコード第二段階
// ブロックデータの読み込み // ブロックデータの読み込み
//-------------------------------------------------- //--------------------------------------------------
void stChannel_Decode2(stChannel *ch,clData *data){ static const char stChannel_Decode2_list1[]={
static const char list1[]={
0,2,3,3,4,4,4,4,5,6,7,8,9,10,11,12, 0,2,3,3,4,4,4,4,5,6,7,8,9,10,11,12,
}; };
static const char list2[]={ static const char stChannel_Decode2_list2[]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
2,2,2,2,2,2,3,3,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,3,3,0,0,0,0,0,0,0,0,
@ -1288,7 +1375,7 @@ void stChannel_Decode2(stChannel *ch,clData *data){
3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4, 3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,
3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
}; };
static const float list3[]={ static const float stChannel_Decode2_list3[]={
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0, +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+1,-1,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0, +0,+0,+1,-1,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+1,+1,-1,-1,+2,-2,+0,+0,+0,+0,+0,+0,+0,+0, +0,+0,+1,+1,-1,-1,+2,-2,+0,+0,+0,+0,+0,+0,+0,+0,
@ -1298,6 +1385,8 @@ void stChannel_Decode2(stChannel *ch,clData *data){
+0,+0,+1,+1,-1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6, +0,+0,+1,+1,-1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6,
+0,+0,+1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6,+7,-7, +0,+0,+1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6,+7,-7,
}; };
void stChannel_Decode2(stChannel *ch,clData *data){
unsigned int i; unsigned int i;
const unsigned int count=ch->count; const unsigned int count=ch->count;
const char *scale=ch->scale; const char *scale=ch->scale;
@ -1306,12 +1395,12 @@ void stChannel_Decode2(stChannel *ch,clData *data){
for(i=0;i<count;i++){ for(i=0;i<count;i++){
float f; float f;
int s=scale[i]; int s=scale[i];
int bitSize=list1[s]; int bitSize=stChannel_Decode2_list1[s];
int v=clData_GetBit(data,bitSize); int v=clData_GetBit(data,bitSize);
if(s<8){ if(s<8){
v+=s<<4; v+=s<<4;
clData_AddBit(data,list2[v]-bitSize); clData_AddBit(data,stChannel_Decode2_list2[v]-bitSize);
f=list3[v]; f=stChannel_Decode2_list3[v];
}else{ }else{
v=(1-((v&1)<<1))*(v>>1); v=(1-((v&1)<<1))*(v>>1);
if(!v)clData_AddBit(data,-1); if(!v)clData_AddBit(data,-1);
@ -1326,9 +1415,7 @@ void stChannel_Decode2(stChannel *ch,clData *data){
// デコード第三段階 // デコード第三段階
// ブロックデータ修正その1 ※v2.0から追加 // ブロックデータ修正その1 ※v2.0から追加
//-------------------------------------------------- //--------------------------------------------------
void stChannel_Decode3(stChannel *ch,unsigned int a,unsigned int b,unsigned int c,unsigned int d){ static const unsigned int stChannel_Decode3_listInt[2][0x40]={
if(ch->type!=2&&b){
static const unsigned int listInt[2][0x40]={
{ {
0x00000000,0x00000000,0x32A0B051,0x32D61B5E,0x330EA43A,0x333E0F68,0x337D3E0C,0x33A8B6D5, 0x00000000,0x00000000,0x32A0B051,0x32D61B5E,0x330EA43A,0x333E0F68,0x337D3E0C,0x33A8B6D5,
0x33E0CCDF,0x3415C3FF,0x34478D75,0x3484F1F6,0x34B123F6,0x34EC0719,0x351D3EDA,0x355184DF, 0x33E0CCDF,0x3415C3FF,0x34478D75,0x3484F1F6,0x34B123F6,0x34EC0719,0x351D3EDA,0x355184DF,
@ -1349,14 +1436,17 @@ void stChannel_Decode3(stChannel *ch,unsigned int a,unsigned int b,unsigned int
0x4B11C3D3,0x4B4238D2,0x4B8164D2,0x4BAC6897,0x4BE5B907,0x4C190B88,0x4C4BEC15,0x00000000, 0x4B11C3D3,0x4B4238D2,0x4B8164D2,0x4BAC6897,0x4BE5B907,0x4C190B88,0x4C4BEC15,0x00000000,
} }
}; };
static const float *listFloat=(float *)listInt[1]; static const float *stChannel_Decode3_listFloat=(float *)stChannel_Decode3_listInt[1];
void stChannel_Decode3(stChannel *ch,unsigned int a,unsigned int b,unsigned int c,unsigned int d){
if(ch->type!=2&&b){
unsigned int i, j, k, l; unsigned int i, j, k, l;
const char *value=ch->value; const char *value=ch->value;
const char *value3=ch->value3; const char *value3=ch->value3;
float *block=ch->block; float *block=ch->block;
for(i=0,k=c,l=c-1;i<a;i++){ for(i=0,k=c,l=c-1;i<a;i++){
for(j=0;j<b&&k<d;j++,l--){ for(j=0;j<b&&k<d;j++,l--){
block[k++]=listFloat[value3[i]-value[l]]*block[l]; block[k++]=stChannel_Decode3_listFloat[value3[i]-value[l]]*block[l];
} }
} }
block[0x80-1]=0; block[0x80-1]=0;
@ -1367,9 +1457,7 @@ void stChannel_Decode3(stChannel *ch,unsigned int a,unsigned int b,unsigned int
// デコード第四段階 // デコード第四段階
// ブロックデータ修正その2 // ブロックデータ修正その2
//-------------------------------------------------- //--------------------------------------------------
void stChannel_Decode4(stChannel *ch,int index,unsigned int a,unsigned int b,unsigned int c){ static const unsigned int stChannel_Decode4_listInt[]={
if(ch->type==1&&c){
static const unsigned int listInt[]={
// v2.0 // v2.0
0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000, 0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000,
0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000, 0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000,
@ -1386,7 +1474,10 @@ void stChannel_Decode4(stChannel *ch,int index,unsigned int a,unsigned int b,uns
//0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000, //0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000,
//0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000, //0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000,
}; };
float f1=((float *)listInt)[ch[1].value2[index]];
void stChannel_Decode4(stChannel *ch,int index,unsigned int a,unsigned int b,unsigned int c){
if(ch->type==1&&c){
float f1=((float *)stChannel_Decode4_listInt)[ch[1].value2[index]];
float f2=f1-2.0f; float f2=f1-2.0f;
float *s=&ch->block[b]; float *s=&ch->block[b];
float *d=&ch[1].block[b]; float *d=&ch[1].block[b];
@ -1403,8 +1494,7 @@ void stChannel_Decode4(stChannel *ch,int index,unsigned int a,unsigned int b,uns
// デコード第五段階 // デコード第五段階
// 波形データを生成 // 波形データを生成
//-------------------------------------------------- //--------------------------------------------------
void stChannel_Decode5(stChannel *ch,int index){ static const unsigned int stChannel_Decode5_list1Int[7][0x40]={
static const unsigned int list1Int[7][0x40]={
{ {
0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,
0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,
@ -1470,7 +1560,7 @@ void stChannel_Decode5(stChannel *ch,int index){
0x3F44E3F5,0x3F42DE29,0x3F40D0DA,0x3F3EBC1B,0x3F3CA003,0x3F3A7CA4,0x3F385216,0x3F36206C, 0x3F44E3F5,0x3F42DE29,0x3F40D0DA,0x3F3EBC1B,0x3F3CA003,0x3F3A7CA4,0x3F385216,0x3F36206C,
} }
}; };
static const unsigned int list2Int[7][0x40]={ static const unsigned int stChannel_Decode5_list2Int[7][0x40]={
{ {
0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,
0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,
@ -1536,7 +1626,7 @@ void stChannel_Decode5(stChannel *ch,int index){
0xBF239DA9,0xBF26050A,0xBF286605,0xBF2AC082,0xBF2D1469,0xBF2F61A5,0xBF31A81D,0xBF33E7BC, 0xBF239DA9,0xBF26050A,0xBF286605,0xBF2AC082,0xBF2D1469,0xBF2F61A5,0xBF31A81D,0xBF33E7BC,
} }
}; };
static const unsigned int list3Int[2][0x40]={ static const unsigned int stChannel_Decode5_list3Int[2][0x40]={
{ {
0x3A3504F0,0x3B0183B8,0x3B70C538,0x3BBB9268,0x3C04A809,0x3C308200,0x3C61284C,0x3C8B3F17, 0x3A3504F0,0x3B0183B8,0x3B70C538,0x3BBB9268,0x3C04A809,0x3C308200,0x3C61284C,0x3C8B3F17,
0x3CA83992,0x3CC77FBD,0x3CE91110,0x3D0677CD,0x3D198FC4,0x3D2DD35C,0x3D434643,0x3D59ECC1, 0x3CA83992,0x3CC77FBD,0x3CE91110,0x3D0677CD,0x3D198FC4,0x3D2DD35C,0x3D434643,0x3D59ECC1,
@ -1557,6 +1647,8 @@ void stChannel_Decode5(stChannel *ch,int index){
0xBF7FF688,0xBF7FF9D0,0xBF7FFC32,0xBF7FFDDA,0xBF7FFEED,0xBF7FFF8F,0xBF7FFFDF,0xBF7FFFFC, 0xBF7FF688,0xBF7FF9D0,0xBF7FFC32,0xBF7FFDDA,0xBF7FFEED,0xBF7FFF8F,0xBF7FFFDF,0xBF7FFFFC,
} }
}; };
void stChannel_Decode5(stChannel *ch,int index){
const float *s, *s1, *s2; const float *s, *s1, *s2;
float *d; float *d;
unsigned int i, count1, count2, j, k; unsigned int i, count1, count2, j, k;
@ -1579,8 +1671,8 @@ void stChannel_Decode5(stChannel *ch,int index){
} }
s=ch->wav1;d=ch->block; s=ch->wav1;d=ch->block;
for(i=0,count1=0x40,count2=1;i<7;i++,count1>>=1,count2<<=1){ for(i=0,count1=0x40,count2=1;i<7;i++,count1>>=1,count2<<=1){
const float *list1Float=(const float *)list1Int[i]; const float *list1Float=(const float *)stChannel_Decode5_list1Int[i];
const float *list2Float=(const float *)list2Int[i]; const float *list2Float=(const float *)stChannel_Decode5_list2Int[i];
s1=s; s1=s;
s2=&s1[count2]; s2=&s1[count2];
float *d1=d; float *d1=d;
@ -1604,7 +1696,7 @@ void stChannel_Decode5(stChannel *ch,int index){
} }
d=ch->wav2; d=ch->wav2;
for(i=0;i<0x80;i++)*(d++)=*(s++); for(i=0;i<0x80;i++)*(d++)=*(s++);
s=(const float *)list3Int;d=ch->wave[index]; s=(const float *)stChannel_Decode5_list3Int;d=ch->wave[index];
s1=&ch->wav2[0x40];s2=ch->wav3; s1=&ch->wav2[0x40];s2=ch->wav3;
for(int i=0;i<0x40;i++)*(d++)=*(s1++)**(s++)+*(s2++); for(int i=0;i<0x40;i++)*(d++)=*(s1++)**(s++)+*(s2++);
for(int i=0;i<0x40;i++)*(d++)=*(s++)**(--s1)-*(s2++); for(int i=0;i<0x40;i++)*(d++)=*(s++)**(--s1)-*(s2++);

View File

@ -20,6 +20,7 @@ typedef struct clHCA clHCA;
/* In case you wish to allocate the structure on your own. */ /* In case you wish to allocate the structure on your own. */
int clHCA_sizeof(); int clHCA_sizeof();
void clHCA_clear(clHCA *, unsigned int ciphKey1, unsigned int ciphKey2); void clHCA_clear(clHCA *, unsigned int ciphKey1, unsigned int ciphKey2);
void clHCA_done(clHCA *);
/* Or you could let the library allocate it. */ /* Or you could let the library allocate it. */
clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2); clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2);
@ -50,6 +51,7 @@ typedef struct clHCA_stInfo {
unsigned int loopEnabled; unsigned int loopEnabled;
unsigned int loopStart; unsigned int loopStart;
unsigned int loopEnd; unsigned int loopEnd;
const char *comment;
} clHCA_stInfo; } clHCA_stInfo;
/* Retrieve information relevant for decoding and playback with this function. /* Retrieve information relevant for decoding and playback with this function.
@ -63,4 +65,3 @@ int clHCA_getInfo(clHCA *, clHCA_stInfo *out);
#endif #endif
#endif #endif

View File

@ -635,6 +635,8 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
if (vgmstream->coding_type==coding_CRI_HCA) { if (vgmstream->coding_type==coding_CRI_HCA) {
hca_codec_data *data = (hca_codec_data *) vgmstream->codec_data; hca_codec_data *data = (hca_codec_data *) vgmstream->codec_data;
if (vgmstream->codec_data) { if (vgmstream->codec_data) {
clHCA *hca = (clHCA *)(data + 1);
clHCA_done(hca);
if (data->streamfile) close_streamfile(data->streamfile); if (data->streamfile) close_streamfile(data->streamfile);
free(vgmstream->codec_data); free(vgmstream->codec_data);
vgmstream->codec_data = NULL; vgmstream->codec_data = NULL;