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

📄 tag.c

📁 linux下MPEG播放器
💻 C
字号:
/* * madplay - MPEG audio decoder and player * Copyright (C) 2000-2004 Robert Leslie * * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * $Id: tag.c,v 1.1 2004/02/17 02:26:43 rob Exp $ */# ifdef HAVE_CONFIG_H#  include "config.h"# endif# include "global.h"# include <mad.h># include "crc.h"# include "tag.h"# define XING_MAGIC	(('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')# define INFO_MAGIC	(('I' << 24) | ('n' << 16) | ('f' << 8) | 'o')# define LAME_MAGIC	(('L' << 24) | ('A' << 16) | ('M' << 8) | 'E')/* * NAME:	tag->init() * DESCRIPTION:	initialize tag structure */void tag_init(struct tag *tag){  tag->flags      = 0;  tag->encoder[0] = 0;}/* * NAME:	parse_xing() * DESCRIPTION:	parse a Xing VBR tag */staticint parse_xing(struct tag_xing *xing,	       struct mad_bitptr *ptr, unsigned int *bitlen){  if (*bitlen < 32)    goto fail;  xing->flags = mad_bit_read(ptr, 32);  *bitlen -= 32;  if (xing->flags & TAG_XING_FRAMES) {    if (*bitlen < 32)      goto fail;    xing->frames = mad_bit_read(ptr, 32);    *bitlen -= 32;  }  if (xing->flags & TAG_XING_BYTES) {    if (*bitlen < 32)      goto fail;    xing->bytes = mad_bit_read(ptr, 32);    *bitlen -= 32;  }  if (xing->flags & TAG_XING_TOC) {    int i;    if (*bitlen < 800)      goto fail;    for (i = 0; i < 100; ++i)      xing->toc[i] = mad_bit_read(ptr, 8);    *bitlen -= 800;  }  if (xing->flags & TAG_XING_SCALE) {    if (*bitlen < 32)      goto fail;    xing->scale = mad_bit_read(ptr, 32);    *bitlen -= 32;  }  return 0; fail:  xing->flags = 0;  return -1;}/* * NAME:	tag->parse_rgain() * DESCRIPTION:	parse a 16-bit Replay Gain field */void tag_parse_rgain(struct tag_rgain *rgain, struct mad_bitptr *ptr){  int negative;  rgain->name       = mad_bit_read(ptr, 3);  rgain->originator = mad_bit_read(ptr, 3);  negative          = mad_bit_read(ptr, 1);  rgain->adjustment = mad_bit_read(ptr, 9);  if (negative)    rgain->adjustment = -rgain->adjustment;}/* * NAME:	parse_lame() * DESCRIPTION:	parse a LAME tag */staticint parse_lame(struct tag_lame *lame,	       struct mad_bitptr *ptr, unsigned int *bitlen,	       unsigned short crc){  struct mad_bitptr save = *ptr;  if (*bitlen < 36 * 8)    goto fail;  /* bytes $9A-$A4: Encoder short VersionString */  mad_bit_skip(ptr, 9 * 8);  /* byte $A5: Info Tag revision + VBR method */  lame->revision = mad_bit_read(ptr, 4);  if (lame->revision == 15)    goto fail;  lame->vbr_method = mad_bit_read(ptr, 4);  /* byte $A6: Lowpass filter value (Hz) */  lame->lowpass_filter = mad_bit_read(ptr, 8) * 100;  /* bytes $A7-$AA: 32 bit "Peak signal amplitude" */  lame->peak = mad_bit_read(ptr, 32) << 5;  /* bytes $AB-$AC: 16 bit "Radio Replay Gain" */  tag_parse_rgain(&lame->replay_gain[0], ptr);  /* bytes $AD-$AE: 16 bit "Audiophile Replay Gain" */  tag_parse_rgain(&lame->replay_gain[1], ptr);  /* byte $AF: Encoding flags + ATH Type */  lame->flags    = mad_bit_read(ptr, 4);  lame->ath_type = mad_bit_read(ptr, 4);  /* byte $B0: if ABR {specified bitrate} else {minimal bitrate} */  lame->bitrate = mad_bit_read(ptr, 8);  /* bytes $B1-$B3: Encoder delays */  lame->start_delay = mad_bit_read(ptr, 12);  lame->end_padding = mad_bit_read(ptr, 12);  /* byte $B4: Misc */  lame->source_samplerate = mad_bit_read(ptr, 2);  if (mad_bit_read(ptr, 1))    lame->flags |= TAG_LAME_UNWISE;  lame->stereo_mode   = mad_bit_read(ptr, 3);  lame->noise_shaping = mad_bit_read(ptr, 2);  /* byte $B5: MP3 Gain */  lame->gain = mad_bit_read(ptr, 8);  /* bytes $B6-B7: Preset and surround info */  mad_bit_skip(ptr, 2);  lame->surround = mad_bit_read(ptr,  3);  lame->preset   = mad_bit_read(ptr, 11);  /* bytes $B8-$BB: MusicLength */  lame->music_length = mad_bit_read(ptr, 32);  /* bytes $BC-$BD: MusicCRC */  lame->music_crc = mad_bit_read(ptr, 16);  /* bytes $BE-$BF: CRC-16 of Info Tag */  if (mad_bit_read(ptr, 16) != crc)    goto fail;  *bitlen -= 36 * 8;  return 0; fail:  *ptr = save;  return -1;}/* * NAME:	tag->parse() * DESCRIPTION:	parse Xing/LAME tag(s) */int tag_parse(struct tag *tag, struct mad_stream const *stream){  struct mad_bitptr ptr = stream->anc_ptr;  struct mad_bitptr start = ptr;  unsigned int bitlen = stream->anc_bitlen;  unsigned long magic;  int i;  if (bitlen < 32)    return -1;  magic = mad_bit_read(&ptr, 32);  bitlen -= 32;  if (magic != XING_MAGIC &&      magic != INFO_MAGIC &&      magic != LAME_MAGIC) {    /*     * Due to an unfortunate historical accident, a Xing VBR tag may be     * misplaced in a stream with CRC protection. We check for this by     * assuming the tag began two octets prior and the high bits of the     * following flags field are always zero.     */    if (magic != ((XING_MAGIC << 16) & 0xffffffffL) &&	magic != ((INFO_MAGIC << 16) & 0xffffffffL))      return -1;    magic >>= 16;    /* backtrack the bit pointer */    ptr = start;    mad_bit_skip(&ptr, 16);    bitlen += 16;  }  if ((magic & 0x0000ffffL) == (XING_MAGIC & 0x0000ffffL))    tag->flags |= TAG_VBR;  /* Xing tag */  if (magic == LAME_MAGIC) {    ptr = start;    bitlen += 32;  }  else if (parse_xing(&tag->xing, &ptr, &bitlen) == 0)    tag->flags |= TAG_XING;  /* encoder string */  if (bitlen >= 20 * 8) {    start = ptr;    for (i = 0; i < 20; ++i) {      tag->encoder[i] = mad_bit_read(&ptr, 8);      if (tag->encoder[i] == 0)	break;      /* keep only printable ASCII chars */      if (tag->encoder[i] < 0x20 || tag->encoder[i] >= 0x7f) {	tag->encoder[i] = 0;	break;      }    }    tag->encoder[20] = 0;    ptr = start;  }  /* LAME tag */  if (stream->next_frame - stream->this_frame >= 192 &&      parse_lame(&tag->lame, &ptr, &bitlen,		 crc_compute(stream->this_frame, 190, 0x0000)) == 0) {    tag->flags |= TAG_LAME;    tag->encoder[9] = 0;  }  else {    for (i = 0; i < 20; ++i) {      if (tag->encoder[i] == 0)	break;      /* stop at padding chars */      if (tag->encoder[i] == 0x55) {	tag->encoder[i] = 0;	break;      }    }  }  return 0;}

⌨️ 快捷键说明

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