⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mace.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 2 页
字号:
    { 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 + -