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

📄 parse.c

📁 杜比AC-3编码解码器(参考程序)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
 *    parse.c
 *
 *	Copyright (C) Aaron Holtzman - May 1999
 *
 *  This file is part of ac3dec, a free Dolby AC-3 stream decoder.
 *	
 *  ac3dec 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, or (at your option)
 *  any later version.
 *   
 *  ac3dec 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 GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"


#include "bitstream.h"
#include "stats.h"
#include "debug.h"
#include "crc.h"
#include "parse.h"

/* Misc LUT */
static const uint_16 nfchans[8] = {2,1,2,3,3,4,4,5};

struct frmsize_s
{
	uint_16 bit_rate;
	uint_16 frm_size[3];
};

static const struct frmsize_s frmsizecod_tbl[64] = 
{
	{ 32  ,{64   ,69   ,96   } },
	{ 32  ,{64   ,70   ,96   } },
	{ 40  ,{80   ,87   ,120  } },
	{ 40  ,{80   ,88   ,120  } },
	{ 48  ,{96   ,104  ,144  } },
	{ 48  ,{96   ,105  ,144  } },
	{ 56  ,{112  ,121  ,168  } },
	{ 56  ,{112  ,122  ,168  } },
	{ 64  ,{128  ,139  ,192  } },
	{ 64  ,{128  ,140  ,192  } },
	{ 80  ,{160  ,174  ,240  } },
	{ 80  ,{160  ,175  ,240  } },
	{ 96  ,{192  ,208  ,288  } },
	{ 96  ,{192  ,209  ,288  } },
	{ 112 ,{224  ,243  ,336  } },
	{ 112 ,{224  ,244  ,336  } },
	{ 128 ,{256  ,278  ,384  } },
	{ 128 ,{256  ,279  ,384  } },
	{ 160 ,{320  ,348  ,480  } },
	{ 160 ,{320  ,349  ,480  } },
	{ 192 ,{384  ,417  ,576  } },
	{ 192 ,{384  ,418  ,576  } },
	{ 224 ,{448  ,487  ,672  } },
	{ 224 ,{448  ,488  ,672  } },
	{ 256 ,{512  ,557  ,768  } },
	{ 256 ,{512  ,558  ,768  } },
	{ 320 ,{640  ,696  ,960  } },
	{ 320 ,{640  ,697  ,960  } },
	{ 384 ,{768  ,835  ,1152 } },
	{ 384 ,{768  ,836  ,1152 } },
	{ 448 ,{896  ,975  ,1344 } },
	{ 448 ,{896  ,976  ,1344 } },
	{ 512 ,{1024 ,1114 ,1536 } },
	{ 512 ,{1024 ,1115 ,1536 } },
	{ 576 ,{1152 ,1253 ,1728 } },
	{ 576 ,{1152 ,1254 ,1728 } },
	{ 640 ,{1280 ,1393 ,1920 } },
	{ 640 ,{1280 ,1394 ,1920 } }
};

/* Parse a syncinfo structure, minus the sync word */
void
parse_syncinfo(syncinfo_t *syncinfo)
{
	uint_32 tmp = 0;
	uint_16 sync_word = 0;
	uint_32 time_out = 1<<16;

	// 
	// Find a ac3 sync frame. Time out if we read 64k without finding
	// one.
	// 
	while(time_out--)
	{
		sync_word = (sync_word << 8) + bitstream_get_byte();

		if(sync_word == 0x0b77)
			break;
	}

	//
	// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
	// in order to determine how big the frame is
	//
	tmp = (tmp << 8) + bitstream_get_byte();
	tmp = (tmp << 8) + bitstream_get_byte();
	tmp = (tmp << 8) + bitstream_get_byte();

	// Get the sampling rate 
	syncinfo->fscod  = (tmp >> 6) & 0x3;

	if(syncinfo->fscod == 3)
	{
		//invalid sampling rate code
		error_flag = 1;	
		return;
	}
	else if(syncinfo->fscod == 2)
		syncinfo->sampling_rate = 32000;
	else if(syncinfo->fscod == 1)
		syncinfo->sampling_rate = 44100;
	else
		syncinfo->sampling_rate = 48000;

	// Get the frame size code 
	syncinfo->frmsizecod = tmp & 0x3f;

	// Calculate the frame size and bitrate
	syncinfo->frame_size = 
		frmsizecod_tbl[syncinfo->frmsizecod].frm_size[syncinfo->fscod];
	syncinfo->bit_rate = frmsizecod_tbl[syncinfo->frmsizecod].bit_rate;


	// Buffer the entire syncframe 
	bitstream_buffer_frame(syncinfo->frame_size * 2 - 5);

	// Check the crc over the entire frame 
	crc_init();

	crc_process_byte(tmp>>16);
	crc_process_byte((tmp>>8) & 0xff);
	crc_process_byte(tmp & 0xff);
	crc_process_frame(bitstream_get_buffer_start(),syncinfo->frame_size * 2 - 5);

	if(!crc_validate())
	{
		error_flag = 1;
		fprintf(stderr,"** CRC failed - skipping frame **\n");
		return;
	}

	stats_print_syncinfo(syncinfo);
}

/*
 * This routine fills a bsi struct from the AC3 stream
 */

void
parse_bsi(bsi_t *bsi)
{
	uint_32 i;

	/* Check the AC-3 version number */
	bsi->bsid = bitstream_get(5);

	/* Get the audio service provided by the steram */
	bsi->bsmod = bitstream_get(3);

	/* Get the audio coding mode (ie how many channels)*/
	bsi->acmod = bitstream_get(3);
	/* Predecode the number of full bandwidth channels as we use this
	 * number a lot */
	bsi->nfchans = nfchans[bsi->acmod];

	/* If it is in use, get the centre channel mix level */
	if ((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
		bsi->cmixlev = bitstream_get(2);

	/* If it is in use, get the surround channel mix level */
	if (bsi->acmod & 0x4)
		bsi->surmixlev = bitstream_get(2);

	/* Get the dolby surround mode if in 2/0 mode */
	if(bsi->acmod == 0x2)
		bsi->dsurmod= bitstream_get(2);

	/* Is the low frequency effects channel on? */
	bsi->lfeon = bitstream_get(1);

	/* Get the dialogue normalization level */
	bsi->dialnorm = bitstream_get(5);

	/* Does compression gain exist? */
	bsi->compre = bitstream_get(1);
	if (bsi->compre)
	{
		/* Get compression gain */
		bsi->compr = bitstream_get(8);
	}

	/* Does language code exist? */
	bsi->langcode = bitstream_get(1);
	if (bsi->langcode)
	{
		/* Get langauge code */
		bsi->langcod = bitstream_get(8);
	}

	/* Does audio production info exist? */
	bsi->audprodie = bitstream_get(1);
	if (bsi->audprodie)
	{
		/* Get mix level */
		bsi->mixlevel = bitstream_get(5);

		/* Get room type */
		bsi->roomtyp = bitstream_get(2);
	}

	/* If we're in dual mono mode then get some extra info */
	if (bsi->acmod ==0)
	{
		/* Get the dialogue normalization level two */
		bsi->dialnorm2 = bitstream_get(5);

		/* Does compression gain two exist? */
		bsi->compr2e = bitstream_get(1);
		if (bsi->compr2e)
		{
			/* Get compression gain two */
			bsi->compr2 = bitstream_get(8);
		}

		/* Does language code two exist? */
		bsi->langcod2e = bitstream_get(1);
		if (bsi->langcod2e)
		{
			/* Get langauge code two */
			bsi->langcod2 = bitstream_get(8);
		}

		/* Does audio production info two exist? */
		bsi->audprodi2e = bitstream_get(1);
		if (bsi->audprodi2e)
		{
			/* Get mix level two */
			bsi->mixlevel2 = bitstream_get(5);

			/* Get room type two */
			bsi->roomtyp2 = bitstream_get(2);
		}
	}

	/* Get the copyright bit */
	bsi->copyrightb = bitstream_get(1);

	/* Get the original bit */
	bsi->origbs = bitstream_get(1);
	
	/* Does timecode one exist? */
	bsi->timecod1e = bitstream_get(1);

	if(bsi->timecod1e)
		bsi->timecod1 = bitstream_get(14);

	/* Does timecode two exist? */
	bsi->timecod2e = bitstream_get(1);

	if(bsi->timecod2e)
		bsi->timecod2 = bitstream_get(14);

	/* Does addition info exist? */
	bsi->addbsie = bitstream_get(1);

	if(bsi->addbsie)
	{
		/* Get how much info is there */
		bsi->addbsil = bitstream_get(6);

		/* Get the additional info */
		for(i=0;i<(bsi->addbsil + 1);i++)
			bsi->addbsi[i] = bitstream_get(8);
	}

	stats_print_bsi(bsi);
}

/* More pain inducing parsing */
void
parse_audblk(bsi_t *bsi,audblk_t *audblk)
{
	int i,j;

	for (i=0;i < bsi->nfchans; i++)
	{
		/* Is this channel an interleaved 256 + 256 block ? */
		audblk->blksw[i] = bitstream_get(1);
	}

	for (i=0;i < bsi->nfchans; i++)
	{
		/* Should we dither this channel? */
		audblk->dithflag[i] = bitstream_get(1);
	}

	/* Does dynamic range control exist? */
	audblk->dynrnge = bitstream_get(1);
	if (audblk->dynrnge)
	{
		/* Get dynamic range info */
		audblk->dynrng = bitstream_get(8);

⌨️ 快捷键说明

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