acc之ADTS解说二

前面主要讲了介绍AAC的ADTS格式的原理,接下来用C语言来实现AAC的ADTS格式的解析,从而获取acc文件的相关属属性,比如采样率、每一帧的大小、声道数等。
ADTS头一般是7个字节,主要是由固定头信息:adts_fixed_header()和 可变头信息:adts_variable_header()组成。只需从acc文件开头处读取七个字节,然后结合头信息各个成员所占用的位数进行解析即可。

解析代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>

struct adts_fixed_header
{
	unsigned int syncword;
	unsigned int sample;
	unsigned int channel_configurion;
	unsigned short int layer;
	unsigned short int profile;
	unsigned char ID;
	unsigned char protection_absebt;
	unsigned char private_bit;
	unsigned char original_copy;
	unsigned char home;
}adts_fixed_header_st={0};

struct adts_variable_header
{
	char copyright_identification_bit;
	char copyright_identification_start;
	unsigned short int  frame_length;
	unsigned short int adts_buffer_fullness;
	char number_of_raw_data_blocks_in_frame;
}adts_variable_header_st = {0};

int ptint_adts_fixed_header(struct adts_fixed_header  adts_header)
{
	printf("adts_header.syncword = %x\n",adts_header.syncword);
	printf("adts_header.ID = %x\n",adts_header.ID);
	printf("adts_header.layer = %x\n",adts_header.layer);
	printf("adts_header.protection_absebt = %x\n",adts_header.protection_absebt);
	printf("adts_header.profile = %x\n",adts_header.profile);
	printf("adts_header.sample = %x\n",adts_header.sample);
	printf("adts_header.private_bit = %x\n",adts_header.private_bit);
	printf("adts_header.channel_configurion = %x\n",adts_header.channel_configurion);
	printf("adts_header.original_copy = %x\n",adts_header.original_copy);
	printf("adts_header.home = %x\n",adts_header.home);
	return 0; 	
}

int ptint_adts_variable_header(struct adts_variable_header  adts_header)
{
	printf("adts_header.copyright_identification_bit = %x\n",adts_header.copyright_identification_bit);
	printf("adts_header.copyright_identification_start = %x\n",adts_header.copyright_identification_start);
	printf("adts_header.frame_length = %x\n",adts_header.frame_length);
	printf("adts_header.adts_buffer_fullness = %x\n",adts_header.adts_buffer_fullness);
	printf("adts_header.number_of_raw_data_blocks_in_frame = %x\n",adts_header.number_of_raw_data_blocks_in_frame);
	return 0;
}

int get_adts_fixed_header(struct adts_fixed_header*  adts_header, const unsigned char *data)
{
	if(adts_header == NULL || data == NULL)
	{
		printf("adts_header or data is NULL!\n"); 
	}
	
	adts_header->syncword = (data[0] << 4) + (data[1] >> 4);
	adts_header->ID = (data[1] >> 2) & 0x1;
	adts_header->layer = (data[1] >> 1) & 0x3;
	adts_header->protection_absebt = data[1] & 0x1;
	adts_header->profile = (data[2] >> 6) & 0x3;
	adts_header->sample = (data[2] >> 2) & 0xf;
	adts_header->private_bit = (data[2] >> 1)&0x1;
	adts_header->channel_configurion = ((data[2] & 0x1) << 2) + ((data[3] >> 6) & 0x3);
	adts_header->original_copy =(data[3] >> 5) & 0x1;
	adts_header->home =(data[3] >> 4) & 0x1;
	return 0;
}

int get_adts_variable_header(struct adts_variable_header*  adts_header, const unsigned char *data)
{
	if(adts_header == NULL || data == NULL)
	{
		printf("adts_header or data is NULL!\n"); 
	}
	
	adts_header->copyright_identification_bit = (data[3] >> 3) & 0x1;
	adts_header->copyright_identification_start = (data[3] >> 2) & 0x1;
	adts_header->frame_length = ((data[3] & 0x3) << 11) + (data[4] << 3) + ((data[5] >> 5) & 0x7);
	adts_header->adts_buffer_fullness = ((data[5] & 0x1f) << 6) + ((data[6] >> 2) & 0x3f);
	adts_header->number_of_raw_data_blocks_in_frame = data[6]& 0x3;
	return 0;
}

int main(int argc,char **argv )
{
	unsigned char data[7];
	char *finename="mp3.aac";
	FILE* fp = NULL;

	fp = fopen(finename, "r");
    if(NULL == fp)
    {
        printf("open file file failed!");
        return -1;
    }
	else
    {
    	fread(data, 7, 1, fp);
        fclose(fp);
	}

	get_adts_fixed_header(&adts_fixed_header_st,data);
	get_adts_variable_header(&adts_variable_header_st,data);
	
	ptint_adts_fixed_header(adts_fixed_header_st);
	ptint_adts_variable_header(adts_variable_header_st);
	
	return 0;
}

结果打印信息:

root@chen:/home/chenjg/share/test/audio# ./test
adts_header.syncword = fff
adts_header.ID = 0
adts_header.layer = 0
adts_header.protection_absebt = 1
adts_header.profile = 1
adts_header.sample = 4
adts_header.private_bit = 0
adts_header.channel_configurion = 1
adts_header.original_copy = 0
adts_header.home = 0
adts_header.copyright_identification_bit = 0
adts_header.copyright_identification_start = 0
adts_header.frame_length = 1d
adts_header.adts_buffer_fullness = 7ff
adts_header.number_of_raw_data_blocks_in_frame = 0

通过软件解析acc文件的数据情况如图所示:
在这里插入图片描述
源码路径(包含acc文件读取软件)
链接:https://pan.baidu.com/s/1WjHvD2gpUqZ1O7zb_Y37UA
提取码:p667

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值