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

📄 ttadec.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ttadec.c * * Description:	 TTAv1 decoder library for HW players * Developed by: Alexander Djourik <ald@true-audio.com> *               Pavel Zhilin <pzh@true-audio.com> * * Copyright (c) 2004 True Audio Software. All rights reserved. * *//* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the True Audio Software nor the names of its *    contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <stdlib.h>#include <string.h>#include "ttalib.h"#include "ttadec.h"#include "filter.h"/******************* static variables and structures *******************/static unsigned char isobuffers[ISO_BUFFERS_SIZE + 4];static unsigned char *iso_buffers_end = isobuffers + ISO_BUFFERS_SIZE;static unsigned int pcm_buffer_size;static decoder	tta[MAX_NCH];	// decoder statestatic int	cache[MAX_NCH];	// decoder cachetta_info *ttainfo;		// currently playing file infostatic unsigned int fframes;	// number of frames in filestatic unsigned int framelen;	// the frame length in samplesstatic unsigned int lastlen;	// the length of the last frame in samplesstatic unsigned int data_pos;	// currently playing frame indexstatic unsigned int data_cur;	// the playing position in framestatic int maxvalue;		// output data max valuestatic unsigned int *seek_table;	// the playing position tablestatic unsigned int st_state;	//seek table statusstatic unsigned int frame_crc32;static unsigned int bit_count;static unsigned int bit_cache;static unsigned char *bitpos;static int read_id3_tags (tta_info *info);/************************* crc32 functions *****************************/#define UPDATE_CRC32(x, crc) crc = \	(((crc>>8) & 0x00FFFFFF) ^ crc32_table[(crc^x) & 0xFF])static unsigned int crc32 (unsigned char *buffer, unsigned int len) {	unsigned int i;	unsigned int crc = 0xFFFFFFFF;	for (i = 0; i < len; i++) UPDATE_CRC32(buffer[i], crc);	return (crc ^ 0xFFFFFFFF);}/************************* bit operations ******************************/#define GET_BINARY(value, bits) \	while (bit_count < bits) { \		if (bitpos == iso_buffers_end) { \			if (!ttainfo->Reader->Read(ttainfo->Reader, isobuffers, \			    ISO_BUFFERS_SIZE)) { \			    ttainfo->STATE = READ_ERROR; \			    return -1; } \			bitpos = isobuffers; } \		UPDATE_CRC32(*bitpos, frame_crc32); \		bit_cache |= *bitpos << bit_count; \		bit_count += 8; \		bitpos++; } \	value = bit_cache & bit_mask[bits]; \	bit_cache >>= bits; \	bit_count -= bits; \	bit_cache &= bit_mask[bit_count];#define GET_UNARY(value) \	value = 0; \	while (!(bit_cache ^ bit_mask[bit_count])) { \		if (bitpos == iso_buffers_end) { \			if (!ttainfo->Reader->Read(ttainfo->Reader, isobuffers, \			    ISO_BUFFERS_SIZE)) { \			    ttainfo->STATE = READ_ERROR; \			    return -1; } \			bitpos = isobuffers; } \		value += bit_count; \		bit_cache = *bitpos++; \		UPDATE_CRC32(bit_cache, frame_crc32); \		bit_count = 8; } \	while (bit_cache & 1) { \		value++; \		bit_cache >>= 1; \		bit_count--; } \	bit_cache >>= 1; \	bit_count--;static void init_buffer_read() {	frame_crc32 = 0xFFFFFFFFUL;	bit_count = bit_cache = 0;	bitpos = iso_buffers_end;}static int done_buffer_read() {	unsigned int crc32, rbytes;	frame_crc32 ^= 0xFFFFFFFFUL;	rbytes = iso_buffers_end - bitpos;	if (rbytes < sizeof(int)) {	    memcpy(isobuffers, bitpos, 4);	    if (!ttainfo->Reader->Read(ttainfo->Reader, isobuffers + rbytes,		ISO_BUFFERS_SIZE - rbytes))		return -1;	    bitpos = isobuffers;	}	memcpy(&crc32, bitpos, 4);	crc32 = ENDSWAP_INT32(crc32);	bitpos += sizeof(int);    	if (crc32 != frame_crc32) return -1;	bit_cache = bit_count = 0;	frame_crc32 = 0xFFFFFFFFUL;	return 0;}/************************* decoder functions ****************************/const char *get_error_str (int error) {	switch (error) {	case NO_ERROR:      return "No errors found";	case OPEN_ERROR:    return "Can't open file";	case FORMAT_ERROR:  return "Not supported file format";	case FILE_ERROR:    return "File is corrupted";	case READ_ERROR:    return "Can't read from file";	case MEMORY_ERROR:  return "Insufficient memory available";	default:            return "Unknown error code";	}}int open_tta_file (tta_info *info, unsigned int data_offset) {	unsigned int checksum;	unsigned int datasize;	unsigned int origsize;	tta_hdr ttahdr;	// clear the memory	//memset (info, 0, sizeof(tta_info));	// get file size	info->Reader->Seek(info->Reader, 0, SEEK_END);	info->FILESIZE = info->Reader->FilePos;	info->Reader->Seek(info->Reader, 0, SEEK_SET);	// read id3 tags	if (!data_offset) {//		if ((data_offset = skip_id3_tag (info)) < 0) {		if ((data_offset = read_id3_tags (info)) < 0) {		    return -1;		}	} else info->Reader->Seek(info->Reader, data_offset, SEEK_SET);	// read TTA header	if (info->Reader->Read(info->Reader, &ttahdr, sizeof (ttahdr)) == 0) {		info->STATE = READ_ERROR;		return -1;	}	// check for TTA3 signature	if (ENDSWAP_INT32(ttahdr.TTAid) != TTA1_SIGN) {				info->STATE = FORMAT_ERROR;		return -1;	}	ttahdr.CRC32 = ENDSWAP_INT32(ttahdr.CRC32);	checksum = crc32((unsigned char *) &ttahdr,	sizeof(tta_hdr) - sizeof(int));	if (checksum != ttahdr.CRC32) {		info->STATE = FILE_ERROR;		return -1;	}	ttahdr.AudioFormat = ENDSWAP_INT16(ttahdr.AudioFormat);	ttahdr.NumChannels = ENDSWAP_INT16(ttahdr.NumChannels);	ttahdr.BitsPerSample = ENDSWAP_INT16(ttahdr.BitsPerSample);	ttahdr.SampleRate = ENDSWAP_INT32(ttahdr.SampleRate);	ttahdr.DataLength = ENDSWAP_INT32(ttahdr.DataLength);	// check for player supported formats	if (ttahdr.AudioFormat != WAVE_FORMAT_PCM ||		ttahdr.NumChannels > MAX_NCH ||		ttahdr.BitsPerSample > MAX_BPS ||(		ttahdr.SampleRate != 16000 &&		ttahdr.SampleRate != 22050 &&		ttahdr.SampleRate != 24000 &&		ttahdr.SampleRate != 32000 &&		ttahdr.SampleRate != 44100 &&		ttahdr.SampleRate != 48000 &&		ttahdr.SampleRate != 64000 &&		ttahdr.SampleRate != 88200 &&		ttahdr.SampleRate != 96000)) {		info->STATE = FORMAT_ERROR;		return -1;	}	// fill the File Info	info->NCH = ttahdr.NumChannels;	info->BPS = ttahdr.BitsPerSample;	info->BSIZE = (ttahdr.BitsPerSample + 7)/8;	info->FORMAT = ttahdr.AudioFormat;	info->SAMPLERATE = ttahdr.SampleRate;	info->DATALENGTH = ttahdr.DataLength;	info->FRAMELEN = (int) (FRAME_TIME * ttahdr.SampleRate);	info->LENGTH = ttahdr.DataLength / ttahdr.SampleRate;	info->DATAPOS = data_offset;        datasize = info->FILESIZE - info->DATAPOS;        origsize = info->DATALENGTH * info->BSIZE * info->NCH;	info->COMPRESS = (double) datasize / origsize;	info->BITRATE = (int) (info->COMPRESS * info->SAMPLERATE *		info->NCH * info->BPS / 1000);	return 0;}static void rice_init(adapt *rice, unsigned int k0, unsigned int k1) {	rice->k0 = k0;	rice->k1 = k1;	rice->sum0 = shift_16[k0];	rice->sum1 = shift_16[k1];}static void decoder_init(decoder *tta, int nch, int byte_size) {	int shift = flt_set[byte_size - 1];	int i;	for (i = 0; i < nch; i++) {		filter_init(&tta[i].fst, shift);		rice_init(&tta[i].rice, 10, 10);		tta[i].last = 0;	}}static void seek_table_init (unsigned int *seek_table,	unsigned int len, unsigned int data_offset) {	unsigned int *st, frame_len;	for (st = seek_table; st < (seek_table + len); st++) {		frame_len = ENDSWAP_INT32(*st);		*st = data_offset;		data_offset += frame_len;	}}int set_position (unsigned int pos) {	unsigned int seek_pos;	if (pos >= fframes) return 0;	if (!st_state) {		ttainfo->STATE = FILE_ERROR;		return -1;	}	seek_pos = ttainfo->DATAPOS + seek_table[data_pos = pos];	if (ttainfo->Reader->Seek(ttainfo->Reader, seek_pos, SEEK_SET) < 0) {		ttainfo->STATE = READ_ERROR;		return -1;	}	data_cur = 0;	framelen = 0;	// init bit reader	init_buffer_read();	return 0;}int player_init (tta_info *info) {	unsigned int checksum;	unsigned int data_offset;	unsigned int st_size;	ttainfo = info;	framelen = 0;	data_pos = 0;	data_cur = 0;	lastlen = ttainfo->DATALENGTH % ttainfo->FRAMELEN;	fframes = ttainfo->DATALENGTH / ttainfo->FRAMELEN + (lastlen ? 1 : 0);	st_size = (fframes + 1) * sizeof(int);	seek_table = (unsigned int *) malloc(st_size);	if (!seek_table) {		ttainfo->STATE = MEMORY_ERROR;		return -1;	}	// read seek table	if (!info->Reader->Read(info->Reader, seek_table, st_size)) {		ttainfo->STATE = READ_ERROR;		return -1;	}	checksum = crc32((unsigned char *) seek_table, st_size - sizeof(int));	st_state = (checksum == ENDSWAP_INT32(seek_table[fframes]));	data_offset = sizeof(tta_hdr) + st_size;	// init seek table	seek_table_init(seek_table, fframes, data_offset);	// init bit reader

⌨️ 快捷键说明

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