📄 aactag.c
字号:
/************************************************** * * aactag.c * * CVS ID: $Id: aactag.c,v 1.6 2007/07/02 08:43:55 marcucci Exp $ * Author: Sangwon Bae [swbae] - Optomech * Date: $Date: 2007/07/02 08:43:55 $ * Revision: $Revision: 1.6 $ * * Description: * * AAC header parsing and Tag decoding. * *************************************************** * * COPYRIGHT (C) Optomech 2006 * All Rights Reserved * *************************************************** * * STM CVS Log: * * $Log: aactag.c,v $ * Revision 1.6 2007/07/02 08:43:55 marcucci * Decoder Report Error if AAC file is not LC * * Revision 1.5 2007/03/19 17:58:20 belardi * Integration of Optomech AAC decoder P150307 * * Revision 1.4 2007/02/27 11:10:49 belardi * Reverted back to pre-Optomech patch (1.2) * * Revision 1.2 2006/12/19 11:04:22 belardi * Integration of Optomech AAC decode P061219 * * Revision 1.1 2006/11/28 09:27:20 belardi * m4a decoder alfa release from Optomech * * ***************************************************/// AAC library compiled in ARM mode//#pragma ARM#include <stdio.h>#include <string.h>#include "gendef.h"#if (0 != HAVE_AAC)//#include "osal.h"#include "aac/aacdec.h"#include "aacwrap.h"#include "aactag.h"#include "filesys.h"#include "tag_defs.h"#include "framebuffer.h"extern uint8 tag_buf[TAG_BUFFER_LENGTH];extern int ID3_TagDecode(t_SongInfos *song_info, uint32 count_down);extern eDecoderStatus AAC_ParseMpeg(t_SongInfos *song_info, oDecoderHandle handle, void *scratch, sDecoderBitstream *bitstream);static const int iSampFreqs[12] ={ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};eDecoderStatus AAC_ParseHeader(t_SongInfos *song_info, oDecoderHandle handle, void *scratch, sDecoderBitstream *bitstream){ eDecoderStatus res; if(BITSTREAM_TYPE_AAC_MPEG != bitstream->bitstreamType) { res = AACParseHeader(handle, scratch, bitstream); if(BITSTREAM_TYPE_AAC_MPEG != bitstream->bitstreamType) { return res; } } return AAC_ParseMpeg(song_info, handle, scratch, bitstream);}GRESULT AAC_TagDecode(t_SongInfos *song_info, uint32 count_down){ oDecoderHandle AACDecoderHandle; void *AACScratch_p; sDecoderFormats* AACFormats_p; sDecoderBitstream* AACBitstream_p; GRESULT res; int offset; uint8 *buffer = tag_buf; if (0 > XAR_SeekFile(song_info, 0, IO_READ_IMMEDIATE)) { return E_INVALID_CACHE_SEEK; } if(decoderFatalError == AACInitHeader(&AACDecoderHandle, &AACScratch_p, &AACFormats_p, &AACBitstream_p)) { return E_FAIL; } AACDecoderOpenBitstream(AACDecoderHandle, AACScratch_p, AACBitstream_p, AACFormats_p); offset = 0;// song_info->bitrate = 16000; // just default as 128 kbps AACBitstream_p->data = (char*)buffer; AACBitstream_p->dataOffset = 0; AACBitstream_p->dataLength = 0; AACBitstream_p->bitstreamType = 0; res = XAR_ReadFile(song_info, buffer, 1024, IO_READ_CACHE); if (!res) { return E_READ_FAILURE; } else { AACBitstream_p->dataLength += res; } AACBitstream_p->dataRequired = AACBitstream_p->dataLength; do { if(AACBitstream_p->dataLength < AACBitstream_p->dataRequired) { uint16 req; if((AACBitstream_p->dataLength + 1024) > TAG_BUFFER_LENGTH) { req = TAG_BUFFER_LENGTH - AACBitstream_p->dataLength; } else { req = 1024; } res = XAR_ReadFile(song_info, buffer + AACBitstream_p->dataLength, req, IO_READ_CACHE); if(res) { AACBitstream_p->dataLength += res; } else { return E_READ_FAILURE; } if((AACBitstream_p->dataLength + req) < AACBitstream_p->dataRequired) { AACBitstream_p->dataRequired = AACBitstream_p->dataLength + req; } } switch(AAC_ParseHeader(song_info, AACDecoderHandle, AACScratch_p, AACBitstream_p)) { case kDecoderStatus_NoError : if(AACBitstream_p->bitRate) { song_info->bitrate = AACBitstream_p->bitRate >> 3; } song_info->ch_num = AACBitstream_p->channels.total; song_info->sampling_fr = AACBitstream_p->sampleRate; if(AACBitstream_p->headerOffset) { song_info->start_offset = AACBitstream_p->frameRemain; } else { song_info->start_offset = offset + AACBitstream_p->dataOffset; }// XAR_SeekFile(song_info, 0, IO_READ_IMMEDIATE); return S_OK; case kDecoderStatus_MoreData : if(0x80000 < offset) { return E_FAIL; } break; default : return E_FAIL; } if(0 == AACBitstream_p->dataOffset) { break; } AACBitstream_p->dataLength -= AACBitstream_p->dataOffset; memmove(AACBitstream_p->data, AACBitstream_p->data + AACBitstream_p->dataOffset, AACBitstream_p->dataLength); offset += AACBitstream_p->dataOffset; AACBitstream_p->dataOffset = 0; } while(AACBitstream_p->dataRequired); return E_FAIL;}eDecoderStatus AAC_GetFrame(t_SongInfos *song_info, char* data, uint16 size, uint16* required){ uint16 len; char* pos = data; while(7 <= size) { if(0xFF == pos[0]) { if(0xF0 == (0xF6 & pos[1])) { len = ((0x03 & pos[3]) << 11) | (pos[4] << 3) | (pos[5] >> 5); if(FRAME_BUFFER_ELEMENT_LENGTH > len) { if(len > size) { *required = len; break; } if(0x40 != (0xC0 & pos[2])) { return kDecoderStatus_Fatal_UnsupportedFeature; } if(song_info->emphasis) { song_info->emphasis ++; song_info->packet_size += len; if(255 <= song_info->emphasis) { song_info->ch_num = 1; break; } } else { uint8 freq = 0x0F & (pos[2] >> 2); if(11 < freq) { return kDecoderStatus_UnknownBitstream; } song_info->sampling_fr = iSampFreqs[freq]; song_info->emphasis = 1; } pos += len; size -= len; continue; } } } pos ++; size --; } if(song_info->ch_num) { if(1 < song_info->emphasis) { song_info->bitrate = (song_info->packet_size * song_info->sampling_fr) / ((song_info->emphasis - 1) * 1024); return kDecoderStatus_NoError; } return kDecoderStatus_UnknownBitstream; } song_info->strtop = (uint16)(pos - data); return kDecoderStatus_MoreData;}GRESULT AAC_GetBitRate(t_SongInfos *song_info){ GRESULT res; uint16 dataLength; uint16 dataRequired; int offset; char* data; uint8 *buffer = tag_buf; if(0 > XAR_SeekFile(song_info, 0, IO_READ_IMMEDIATE)) { return E_INVALID_CACHE_SEEK; } offset = 0; // file offset dataLength = 0; dataRequired = 0x400; song_info->bitrate = 0; song_info->bitstreamType = 0; song_info->strtop = 0; // data offset song_info->emphasis = 0; // frame count song_info->ch_num = 0; // last indication song_info->packet_size = 0; // block size data = (char*)buffer; do { dataRequired = dataLength + 0x400; if(BITRATE_DETECT_LENGTH < (offset + dataRequired)) { dataRequired = BITRATE_DETECT_LENGTH - offset; song_info->ch_num = 1; } if(dataLength < dataRequired) { res = XAR_ReadFile(song_info, buffer + dataLength, dataRequired - dataLength, IO_READ_CACHE); if(res) { dataLength += res; } else { return E_READ_FAILURE; } } if(0 == song_info->bitstreamType) { if(('A' == data[0]) && ('D' == data[1]) && ('I' == data[2]) && ('F' == data[3])) { song_info->bitstreamType = BITSTREAM_TYPE_AAC_ADIF; return E_WRONG_FORMAT; } if(('f' == data[4]) && ('t' == data[5]) && ('y' == data[6]) && ('p' == data[7])) { song_info->bitstreamType = BITSTREAM_TYPE_AAC_MPEG; return E_WRONG_FORMAT; } song_info->bitstreamType = BITSTREAM_TYPE_AAC_ADTS; } switch(AAC_GetFrame(song_info, data, dataLength, &dataRequired)) { case kDecoderStatus_NoError : return S_OK; case kDecoderStatus_MoreData : break; default : return E_FAIL; } if((TAG_BUFFER_LENGTH < dataRequired) || ((0 == song_info->strtop) && (dataLength >= dataRequired))) { break; } if(song_info->strtop) { dataLength -= song_info->strtop; memmove(data, data + song_info->strtop, dataLength); offset += song_info->strtop; song_info->strtop = 0; } } while(dataRequired); return E_FAIL;}#endif // HAVE_AAC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -