📄 mace.c
字号:
{ 0x2BD0, 0x7FFF, 0x8000, 0xD42F, 0, 0, 0, 0 }, { 0x2DC5, 0x7FFF, 0x8000, 0xD23A, 0, 0, 0, 0 },
{ 0x2FD0, 0x7FFF, 0x8000, 0xD02F, 0, 0, 0, 0 }, { 0x31F2, 0x7FFF, 0x8000, 0xCE0D, 0, 0, 0, 0 },
{ 0x342C, 0x7FFF, 0x8000, 0xCBD3, 0, 0, 0, 0 }, { 0x3681, 0x7FFF, 0x8000, 0xC97E, 0, 0, 0, 0 },
{ 0x38F0, 0x7FFF, 0x8000, 0xC70F, 0, 0, 0, 0 }, { 0x3B7A, 0x7FFF, 0x8000, 0xC485, 0, 0, 0, 0 },
{ 0x3E22, 0x7FFF, 0x8000, 0xC1DD, 0, 0, 0, 0 }, { 0x40E7, 0x7FFF, 0x8000, 0xBF18, 0, 0, 0, 0 },
};
/* end of constants */
typedef struct MACEContext {
short index, lev, factor, prev2, previous, level;
short *outPtr;
} MACEContext;
/* /// "chomp3()" */
static void chomp3(MACEContext *ctx,
uint8_t val,
const uint16_t tab1[],
const uint16_t tab2[][8],
uint32_t numChannels)
{
short current;
current=(short)tab2[(ctx->index & 0x7f0) >> 4][val];
if (current+ctx->lev > 32767) current=32767;
else if (current+ctx->lev < -32768) current=-32767;
else current+=ctx->lev;
ctx->lev=current-(current >> 3);
// *ctx->outPtr++=current >> 8;
*ctx->outPtr=current;
ctx->outPtr+=numChannels;
if ( ( ctx->index += tab1[val]-(ctx->index>>5) ) < 0 ) ctx->index = 0;
}
/* \\\ */
/* /// "Exp1to3()" */
static void Exp1to3(MACEContext *ctx,
uint8_t *inBuffer,
void *outBuffer,
uint32_t cnt,
uint32_t numChannels,
uint32_t whichChannel)
{
uint8_t pkt;
/*
if (inState) {
ctx->index=inState[0];
ctx->lev=inState[1];
} else
*/
ctx->index=ctx->lev=0;
inBuffer+=(whichChannel-1)*2;
ctx->outPtr=outBuffer;
while (cnt>0) {
pkt=inBuffer[0];
chomp3(ctx, pkt & 7, MACEtab1, MACEtab2, numChannels);
chomp3(ctx,(pkt >> 3) & 3, MACEtab3, MACEtab4, numChannels);
chomp3(ctx, pkt >> 5 , MACEtab1, MACEtab2, numChannels);
pkt=inBuffer[1];
chomp3(ctx, pkt & 7, MACEtab1, MACEtab2, numChannels);
chomp3(ctx,(pkt >> 3) & 3, MACEtab3, MACEtab4, numChannels);
chomp3(ctx, pkt >> 5 , MACEtab1, MACEtab2, numChannels);
inBuffer+=numChannels*2;
--cnt;
}
/*
if (outState) {
outState[0]=ctx->index;
outState[1]=ctx->lev;
}
*/
}
/* \\\ */
/* /// "chomp6()" */
static void chomp6(MACEContext *ctx,
uint8_t val,
const uint16_t tab1[],
const uint16_t tab2[][8],
uint32_t numChannels)
{
short current;
current=(short)tab2[(ctx->index & 0x7f0) >> 4][val];
if ((ctx->previous^current)>=0) {
if (ctx->factor+506>32767) ctx->factor=32767;
else ctx->factor+=506;
} else {
if (ctx->factor-314<-32768) ctx->factor=-32767;
else ctx->factor-=314;
}
if (current+ctx->level>32767) current=32767;
else if (current+ctx->level<-32768) current=-32767;
else current+=ctx->level;
ctx->level=((current*ctx->factor) >> 15);
current>>=1;
// *ctx->outPtr++=(ctx->previous+ctx->prev2-((ctx->prev2-current) >> 2)) >> 8;
// *ctx->outPtr++=(ctx->previous+current+((ctx->prev2-current) >> 2)) >> 8;
*ctx->outPtr=(ctx->previous+ctx->prev2-((ctx->prev2-current) >> 2));
ctx->outPtr+=numChannels;
*ctx->outPtr=(ctx->previous+current+((ctx->prev2-current) >> 2));
ctx->outPtr+=numChannels;
ctx->prev2=ctx->previous;
ctx->previous=current;
if( ( ctx->index += tab1[val]-(ctx->index>>5) ) < 0 ) ctx->index = 0;
}
/* \\\ */
/* /// "Exp1to6()" */
static void Exp1to6(MACEContext *ctx,
uint8_t *inBuffer,
void *outBuffer,
uint32_t cnt,
uint32_t numChannels,
uint32_t whichChannel)
{
uint8_t pkt;
/*
if (inState) {
ctx->previous=inState[0];
ctx->prev2=inState[1];
ctx->index=inState[2];
ctx->level=inState[3];
ctx->factor=inState[4];
} else
*/
ctx->previous=ctx->prev2=ctx->index=ctx->level=ctx->factor=0;
inBuffer+=(whichChannel-1);
ctx->outPtr=outBuffer;
while (cnt>0) {
pkt=*inBuffer;
chomp6(ctx, pkt >> 5 , MACEtab1, MACEtab2, numChannels);
chomp6(ctx,(pkt >> 3) & 3, MACEtab3, MACEtab4, numChannels);
chomp6(ctx, pkt & 7, MACEtab1, MACEtab2, numChannels);
inBuffer+=numChannels;
--cnt;
}
/*
if (outState) {
outState[0]=ctx->previous;
outState[1]=ctx->prev2;
outState[2]=ctx->index;
outState[3]=ctx->level;
outState[4]=ctx->factor;
}
*/
}
/* \\\ */
static int mace_decode_init(AVCodecContext * avctx)
{
if (avctx->channels > 2)
return -1;
return 0;
}
static int mace_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
short *samples;
MACEContext *c = avctx->priv_data;
samples = (short *)data;
switch (avctx->codec->id) {
case CODEC_ID_MACE3:
#ifdef DEBUG
puts("mace_decode_frame[3]()");
#endif
Exp1to3(c, buf, samples, buf_size / 2 / avctx->channels, avctx->channels, 1);
if (avctx->channels == 2)
Exp1to3(c, buf, samples+1, buf_size / 2 / 2, 2, 2);
*data_size = 2 * 3 * buf_size;
break;
case CODEC_ID_MACE6:
#ifdef DEBUG
puts("mace_decode_frame[6]()");
#endif
Exp1to6(c, buf, samples, buf_size / avctx->channels, avctx->channels, 1);
if (avctx->channels == 2)
Exp1to6(c, buf, samples+1, buf_size / 2, 2, 2);
*data_size = 2 * 6 * buf_size;
break;
default:
return -1;
}
return buf_size;
}
AVCodec mace3_decoder = {
"mace3",
CODEC_TYPE_AUDIO,
CODEC_ID_MACE3,
sizeof(MACEContext),
mace_decode_init,
NULL,
NULL,
mace_decode_frame,
};
AVCodec mace6_decoder = {
"mace6",
CODEC_TYPE_AUDIO,
CODEC_ID_MACE6,
sizeof(MACEContext),
mace_decode_init,
NULL,
NULL,
mace_decode_frame,
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -