📄 rpxx.cpp
字号:
// $Revision: 1.1.1.1 $
#include "wavestream.h"
#include "rpxx.h"
#define fOSC 5068800.0
/* fS = fOSC / TA / TB / 2 */
/* if (iA <= 9) TA = 9 */
/* else TA = iA */
#define NO_SAMPLE_RATE 41
uint RP20fS[NO_SAMPLE_RATE] = {
4340, 4735, 4883, 5208, 5580, 5788, 6010, 6510,
6945, 7102, 7441, 7813, 8013, 8681, 9470, 9765,
10417, 11160, 11575, 12019, 13021, 13890, 14205, 14882,
15625, 16027, 17361, 18940, 19531, 20835, 22321, 23150,
24038, 26042, 28409, 29764, 31250, 34723, 39623, 41670,
44643
};
uint RP8fS[19][3] = {
0x1203FA, 0, 3472, 0x2203FA, 0, 3721, 0x3203FA, 0, 4007,
0x4203FA, 0, 4341, 0x5203FA, 1, 4735, 0x6203FA, 3, 5209,
0x7203FA, 5, 5787, 0x8203FA, 7, 6510, 0x1203FC, 8, 6945,
0x2203FC, 10, 7441, 0x3203FC, 12, 8013, 0x4203FC, 13, 8681,
0x5203FC, 14, 9470, 0x6203FC, 16, 10417, 0x7203FC, 18, 11575,
0x8203FC, 20, 13022, 0x1203F8, 21, 13890, 0x2203F8, 23, 14822,
0x3203F8, 25, 16027
};
word RP14fS[][3] = {
4855, 9, 58, 4873, 13, 40, 4892, 14, 37, 4902, 11, 47,
4911, 12, 43, 4940, 9, 57, 4969, 10, 51, 4998, 13, 39,
5008, 11, 46, 5028, 9, 56, 5068, 10, 50, 5120, 9, 55,
5130, 13, 38, 5151, 12, 41, 5172, 14, 35, 5214, 9, 54,
5236, 11, 44, 5269, 13, 37, 5280, 12, 40, 5313, 9, 53,
5324, 14, 34, 5358, 11, 43, 5392, 10, 47, 5415, 13, 36,
5485, 11, 42, 5509, 10, 46, 5521, 9, 51, 5557, 12, 38,
5570, 13, 35, 5619, 11, 41, 5632, 9, 50, 5657, 14, 32,
5708, 12, 37, 5733, 13, 34, 5746, 9, 49, 5760, 11, 40,
5839, 14, 31, 5866, 12, 36, 5893, 10, 43, 5907, 11, 39,
5991, 9, 47, 6034, 14, 30, 6063, 11, 38, 6092, 13, 32,
6121, 9, 46, 6181, 10, 41, 6211, 12, 34, 6227, 11, 37,
6242, 14, 29, 6257, 9, 45, 6288, 13, 31, 6336, 10, 40,
6400, 12, 33, 6465, 14, 28, 6498, 13, 30, 6548, 9, 43,
6582, 11, 35, 6600, 12, 32, 6669, 10, 38, 6704, 9, 42,
6704, 14, 27, 6722, 13, 29, 6776, 11, 34, 6812, 12, 31,
6849, 10, 37, 6868, 9, 41, 6962, 14, 26, 6981, 11, 33,
7040, 12, 30, 7200, 11, 32, 7220, 9, 39, 7241, 10, 35,
7282, 12, 29, 7410, 9, 38, 7432, 11, 31, 7454, 10, 34,
7498, 13, 26, 7542, 14, 24, 7610, 9, 37, 7680, 10, 33,
7798, 13, 25, 7822, 9, 36, 7870, 14, 23, 7920, 10, 32,
7944, 11, 29, 8045, 9, 35, 8123, 12, 26, 8175, 10, 31,
8228, 11, 28, 8282, 9, 34, 8448, 12, 25, 8476, 13, 23,
8533, 11, 27, 8620, 14, 21, 8739, 10, 29, 8800, 12, 24,
8861, 11, 26, 9051, 10, 28, 9083, 9, 31, 9182, 12, 23,
9216, 11, 25, 9283, 13, 21, 9386, 10, 27, 9527, 14, 19,
9600, 12, 22, 9710, 9, 29, 9747, 10, 26, 10017, 11, 23,
10057, 12, 21, 10137, 10, 25, 10260, 13, 19, 10429, 9, 27,
10472, 11, 22, 10560, 12, 20, 10648, 14, 17, 10830, 9, 26,
10971, 11, 21, 11019, 10, 23, 11115, 12, 19, 11264, 9, 25,
11314, 14, 16, 11467, 13, 17, 11520, 10, 22, 11733, 12, 18,
12068, 10, 21, 12126, 11, 19, 12184, 13, 16, 12243, 9, 23,
12423, 12, 17, 12672, 10, 20, 12800, 11, 18, 12996, 13, 15,
13200, 12, 16, 13338, 10, 19, 13409, 9, 21, 13552, 11, 17,
14080, 12, 15, 14400, 11, 16, 14821, 9, 19, 14908, 10, 17,
15360, 11, 15, 15644, 9, 18, 15840, 10, 16, 16564, 9, 17,
16896, 10, 15, 17600, 9, 16, 18773, 9, 15
};
/*
short slope[2][8][8] = {
{
0, 1, 2, 3, 4, 5, 7, 9,
1, 2, 3, 4, 5, 7, 9, 13,
2, 3, 5, 8, 12, 17, 23, 30,
3, 6, 11, 18, 27, 38, 51, 66,
4, 9, 14, 24, 34, 44, 64, 84,
5, 11, 17, 29, 41, 53, 77, 101,
6, 13, 20, 34, 48, 62, 90, 118,
7, 15, 23, 39, 55, 71, 103, 125
},
{
0, 1, 2, 4, 6, 8, 12, 16,
1, 3, 5, 9, 13, 17, 25, 33,
2, 5, 8, 14, 20, 26, 38, 50,
3, 7, 11, 19, 27, 35, 41, 67,
4, 9, 14, 24, 34, 44, 64, 84,
5, 11, 17, 29, 41, 53, 77, 111,
6, 13, 20, 34, 48, 62, 90, 118,
7, 15, 23, 39, 55, 71, 103, 125
}
};
short steps[2][8][8] = {
{
0, 0, 0, 0, 0, 0, 1, 1,
0, 0, 1, 1, 1, 1, 2, 2,
1, 1, 2, 2, 2, 2, 3, 3,
2, 2, 2, 3, 3, 4, 4, 5,
3, 3, 3, 4, 4, 5, 5, 6,
4, 4, 5, 5, 5, 5, 6, 7,
5, 5, 6, 6, 6, 6, 7, 7,
6, 6, 7, 7, 7, 7, 7, 7
},
{
00, 00, 00, 00, 02, 02, 03, 04,
00, 00, 01, 01, 03, 03, 04, 05,
01, 01, 02, 02, 04, 04, 05, 06,
02, 02, 03, 03, 05, 05, 06, 07,
03, 03, 04, 04, 06, 06, 07, 07,
04, 04, 05, 05, 07, 07, 07, 07,
05, 05, 06, 06, 07, 07, 07, 07,
06, 06, 07, 07, 07, 07, 07, 07
}
};
*/
uint flength(FILE *stream)
{
long pos,end;
pos = ftell(stream);
fseek(stream,0,SEEK_END);
end = ftell(stream);
fseek(stream,pos,SEEK_SET);
return end;
}
int crpxx::start_read()
{
uint i;
int TA,TB;
info->ch = 1;
info->read_write = 0; // read
info->types = 1; // LSB first
::fseek(info->pf,0,SEEK_SET);
::fread((void*)&head,1,48,info->pf);
// Check file Sunplus RP8 8 bits format
if(strcmp(head.name,"SUNPLUS SPEECH")!=0) {
info->fs = 8013;
for (i = 0; i < 19; i++) {
if (*(unsigned long*)(head.name) == RP8fS[i][0]) {
info->fs = RP8fS[i][2]; break;
};
}
info->bits = 8;
info->offset = 0x80;
adpcm = 0;
} else {
info->bits = (head.bits > 8) ? 16 : 8;
info->offset = (head.bits > 8) ? 0x8000 : 0x80;
if(head.Class == 0){
info->fs = RP20fS[head.ifS];
} else {
TB = head.TB;
TA = head.iA;
if(TA <= 9) TA = 9;
info->fs = (int)(fOSC /(TA*TB*2));
};
adpcm = 1;
switch(info->types) {
case 0x00 : // SUNPLUS PCM DATA
adpcm = 0;
break;
case 0x10 : // ADPCM64 without end code
endcode = 0; table = 0; hardlimit = 1;
break;
case 0x11 : // ADPCM64 with end code
endcode = 1; table = 0; hardlimit = 1;
break;
case 0x12 : // ADPCM64 without end code and no hardlimit
endcode = 0; table = 0; hardlimit = 0;
break;
case 0x13 : // ADPCM64 with end code and no hardlimit
endcode = 1; table = 0; hardlimit = 0;
break;
case 0x19 : // ADPCM66 without end code
endcode = 0; table = 1; hardlimit = 1;
break;
case 0x1A : // ADPCM66 with end code
endcode = 1; table = 1; hardlimit = 1;
break;
case 0x1B : // ADPCM66 without end code and no hardlimit
endcode = 0; table = 1; hardlimit = 0;
break;
case 0x1C : // ADPCM66 with end code and no hardlimit
endcode = 1; table = 1; hardlimit = 0;
default : break;
}
};
// Set length of data
info->length = ::flength(info->pf)-0x30;
if(info->bits > 8) info->length /= 2;
return 0;
}
int crpxx::start_write(uint format)
{
int i,index;
double err,merr;
head.ifC = 1;
head.ifS = 12;
merr = 44100.;
index = 0;
for(i=0;i<sizeof(RP14fS)/6;i++) {
err = (double)(info->fs-RP14fS[i][0]);
err *= (err < 0.) ? -1. : 1.;
if(err < merr) {
merr = err;
head.ifS = i;
};
};
head.Class = 1;
head.iA = (char)RP14fS[head.ifS][1];
head.TB = (char)RP14fS[head.ifS][2];
head.mark = 0x00FF00FF;
strcpy(head.name, "SUNPLUS SPEECH");
head.type=0;
head.bits = info->bits;
head.inp_vol = 0;
head.checksuml = 0;
head.checksumh = 0;
::fwrite((void*)&head,48,1,info->pf);
return 0;
}
void crpxx::end_read()
{
}
void crpxx::end_write()
{
}
int crpxx::read(void* buffer,int samples)
{
if(info->decode == 0) return cwavefile::read(buffer,samples);
else {
if( adpcm == 0 ) {
return cwavefile::read(buffer,samples);
} else {
// decode adpcm to buffer
return cwavefile::read(buffer,samples);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -