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

📄 mhead.c

📁 DSP c64优化 ACT spraa14 mp3优化实例 与其优化应用报告配套
💻 C
字号:
/*____________________________________________________________________________
        
        FreeAmp - The Free MP3 Player

        MP3 Decoder originally Copyright (C) 1995-1997 Xing Technology
        Corp.  http://www.xingtech.com

        Portions Copyright (C) 1998-1999 EMusic.com

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        
____________________________________________________________________________*/

/*------------ mhead.c ----------------------------------------------
  mpeg audio
  extract info from mpeg header
  portable version (adapted from c:\eco\mhead.c

  add Layer III

  mods 6/18/97 re mux restart, 32 bit ints

  mod 5/7/98 parse mpeg 2.5

---------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
#include "itype.h"
#include "mhead.h"                /* mpeg header structure */

static int mp_br_table[2][16] =
{{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}};
static int mp_sr20_table[2][4] =
{{441, 480, 320, -999}, {882, 960, 640, -999}};

static int mp_br_tableL1[2][16] =
{{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},/* mpeg2 */
 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}};

static int mp_br_tableL3[2][16] =
{{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},      /* mpeg 2 */
 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}};



static int find_sync(unsigned char *buf, int n);
static int sync_scan(unsigned char *buf, int n, int i0);
static int sync_test(unsigned char *buf, int n, int isync, int padbytes);

/*--------------------------------------------------------------*/
int head_info(unsigned char *buf, unsigned int n, MPEG_HEAD * h)
{
   int framebytes;
   int mpeg25_flag;
  
   if (n > 10000)
      n = 10000;                /* limit scan for free format */



   h->sync = 0;
   //if ((buf[0] == 0xFF) && ((buf[1] & 0xF0) == 0xF0))
   if ((buf[0] == 0xFF) && ((buf[0+1] & 0xF0) == 0xF0))
   {
      mpeg25_flag = 0;                // mpeg 1 & 2

   }
   else if ((buf[0] == 0xFF) && ((buf[0+1] & 0xF0) == 0xE0))
   {
      mpeg25_flag = 1;                // mpeg 2.5

   }
   else
      return 0;                        // sync fail

   h->sync = 1;
   if (mpeg25_flag)
      h->sync = 2;                //low bit clear signals mpeg25 (as in 0xFFE)

   h->id = (buf[0+1] & 0x08) >> 3;
   h->option = (buf[0+1] & 0x06) >> 1;
   h->prot = (buf[0+1] & 0x01);

   h->br_index = (buf[0+2] & 0xf0) >> 4;
   h->sr_index = (buf[0+2] & 0x0c) >> 2;
   h->pad = (buf[0+2] & 0x02) >> 1;
   h->private_bit = (buf[0+2] & 0x01);
   h->mode = (buf[0+3] & 0xc0) >> 6;
   h->mode_ext = (buf[0+3] & 0x30) >> 4;
   h->cr = (buf[0+3] & 0x08) >> 3;
   h->original = (buf[0+3] & 0x04) >> 2;
   h->emphasis = (buf[0+3] & 0x03);

/* compute framebytes for Layer I, II, III */
   if (h->option < 1)
      return 0;
   if (h->option > 3)
      return 0;

   framebytes = 0;

   if (h->br_index > 0)
   {
      if (h->option == 3)
      {                                /* layer I */
         framebytes =
            (INT32)240 * mp_br_tableL1[h->id][h->br_index]
            / mp_sr20_table[h->id][h->sr_index];
         framebytes = 4 * framebytes;
      }
      else if (h->option == 2)
      {                                /* layer II */
         framebytes =
            (INT32)2880 * mp_br_table[h->id][h->br_index]
            / mp_sr20_table[h->id][h->sr_index];
      }
      else if (h->option == 1)
      {                                /* layer III */
         if (h->id)
         {                        // mpeg1

            framebytes =
               (INT32)2880 * mp_br_tableL3[h->id][h->br_index]
               / mp_sr20_table[h->id][h->sr_index];
         }
         else
         {                        // mpeg2

            if (mpeg25_flag)
            {                        // mpeg2.2

               framebytes =
                  (INT32)2880 * mp_br_tableL3[h->id][h->br_index]
                  / mp_sr20_table[h->id][h->sr_index];
            }
            else
            {
               framebytes =
                  (INT32)1440 * mp_br_tableL3[h->id][h->br_index]
                  / mp_sr20_table[h->id][h->sr_index];
            }
         }
      }
   }
   else
      framebytes = find_sync(buf, n);        /* free format */

  return framebytes;
}

int head_info3(unsigned char *buf, unsigned int n, MPEG_HEAD *h, INT32 *br, unsigned int *searchForward) {
        unsigned int pBuf = 0;
   while ((pBuf < n) && !((buf[pBuf] == 0xFF) && 
          ((buf[pBuf+1] & 0xF0) == 0xF0 || (buf[pBuf+1] & 0xF0) == 0xE0))) 
   {
                pBuf++;
   }

   if (pBuf == n) return 0;

   *searchForward = pBuf;
   return head_info2(&(buf[pBuf]),n,h,br);

}

/*--------------------------------------------------------------*/
int head_info2(unsigned char *buf, unsigned int n, MPEG_HEAD * h, INT32 *br)
{
   int framebytes;

/*---  return br (in bits/sec) in addition to frame bytes ---*/

   *br = 0;
/*-- assume fail --*/
   framebytes = head_info(buf, n, h);

   if (framebytes == 0)
      return 0; 

   if (h->option == 1)
   {                                /* layer III */
      if (h->br_index > 0)
         *br = (INT32)1000 * mp_br_tableL3[h->id][h->br_index];
      else
      {
         if (h->id)                // mpeg1

            *br = (INT32)1000 * framebytes * mp_sr20_table[h->id][h->sr_index] / (144 * 20);
         else
         {                        // mpeg2

            if ((h->sync & 1) == 0)        //  flags mpeg25

               *br = (INT32)500 * framebytes * mp_sr20_table[h->id][h->sr_index] / (72 * 20);
            else
               *br = (INT32)1000 * framebytes * mp_sr20_table[h->id][h->sr_index] / (72 * 20);
         }
      }
   }
   if (h->option == 2)
   {                                /* layer II */
      if (h->br_index > 0)
         *br = (INT32)1000 * mp_br_table[h->id][h->br_index];
      else
         *br = (INT32)1000 * framebytes * mp_sr20_table[h->id][h->sr_index]
            / (144 * 20);
   }
   if (h->option == 3)
   {                                /* layer I */
      if (h->br_index > 0)
         *br = (INT32)1000 * mp_br_tableL1[h->id][h->br_index];
      else
         *br = (INT32)1000 * framebytes * mp_sr20_table[h->id][h->sr_index]
            / (48 * 20);
   }


   return framebytes;
}

/*--------------------------------------------------------------*/
static int compare(unsigned char *buf, unsigned char *buf2)
{
   if (buf[0] != buf2[0])
      return 0;
   if (buf[1] != buf2[1])
      return 0;
   return 1;
}

/*----------------------------------------------------------*/
/*-- does not scan for initial sync, initial sync assumed --*/
static int find_sync(unsigned char *buf, int n)
{
   int i0, isync, nmatch, pad;
   int padbytes, option;

/* mod 4/12/95 i0 change from 72, allows as low as 8kbits for mpeg1 */
   i0 = 24;
   padbytes = 1;
   option = (buf[1] & 0x06) >> 1;
   if (option == 3)
   {
      padbytes = 4;
      i0 = 24;                        /* for shorter layer I frames */
   }

   pad = (buf[2] & 0x02) >> 1;

   n -= 3;                        /*  need 3 bytes of header  */

   while (i0 < 2000)
   {
      isync = sync_scan(buf, n, i0);
      i0 = isync + 1;
      isync -= pad;
      if (isync <= 0)
         return 0;
      nmatch = sync_test(buf, n, isync, padbytes);
      if (nmatch > 0)
         return isync;
   }

   return 0;
}

/*------------------------------------------------------*/
/*---- scan for next sync, assume start is valid -------*/
/*---- return number bytes to next sync ----------------*/
static int sync_scan(unsigned char *buf, int n, int i0)
{
   int i;

   for (i = i0; i < n; i++)
      if (compare(buf, buf + i))
         return i;

   return 0;
}

/*------------------------------------------------------*/
/*- test consecutative syncs, input isync without pad --*/
static int sync_test(unsigned char *buf, int n, int isync, int padbytes)
{
   int i, nmatch, pad;

   nmatch = 0;
   for (i = 0;;)
   {
      pad = padbytes * ((buf[i + 2] & 0x02) >> 1);
      i += (pad + isync);
      if (i > n)
         break;
      if (!compare(buf, buf + i))
         return -nmatch;
      nmatch++;
   }
   return nmatch;
}

/* ***********************************************************
* THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
* REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, 
* INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
* FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR 
* COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE. 
* TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET 
* POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY 
* INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR 
* YOUR USE OF THE PROGRAM.
*
* IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 
* CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY 
* THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED 
* OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT 
* OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM. 
* EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF 
* REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS 
* OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF 
* USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S 
* AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF 
* YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS 
* (U.S.$500).
*
* Unless otherwise stated, the Program written and copyrighted 
* by Texas Instruments is distributed as "freeware".  You may, 
* only under TI's copyright in the Program, use and modify the 
* Program without any charge or restriction.  You may 
* distribute to third parties, provided that you transfer a 
* copy of this license to the third party and the third party 
* agrees to these terms by its first use of the Program. You 
* must reproduce the copyright notice and any other legend of 
* ownership on each copy or partial copy, of the Program.
*
* You acknowledge and agree that the Program contains 
* copyrighted material, trade secrets and other TI proprietary 
* information and is protected by copyright laws, 
* international copyright treaties, and trade secret laws, as 
* well as other intellectual property laws.  To protect TI's 
* rights in the Program, you agree not to decompile, reverse 
* engineer, disassemble or otherwise translate any object code 
* versions of the Program to a human-readable form.  You agree 
* that in no event will you alter, remove or destroy any 
* copyright notice included in the Program.  TI reserves all 
* rights not specifically granted under this license. Except 
* as specifically provided herein, nothing in this agreement 
* shall be construed as conferring by implication, estoppel, 
* or otherwise, upon you, any license or other right under any 
* TI patents, copyrights or trade secrets.
*
* You may not use the Program in non-TI devices.
* ********************************************************* */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -