📄 aacdecode.c
字号:
/* <LIC_AMD_STD> * Copyright (c) 2005 Advanced Micro Devices, Inc. * * 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 * * The full GNU General Public License is included in this distribution in the * file called COPYING * </LIC_AMD_STD> *//* <CTL_AMD_STD> * </CTL_AMD_STD> *//* <DOC_AMD_STD> * </DOC_AMD_STD> */#if defined(WIN32) || defined(UNDER_CE) #include <windows.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#ifndef _WIN32 #include <unistd.h>#endif#include "mai_osal.h" /* needed for threads */#include "audio_change_info.h"#include "faad.h"#include "aacdecode.h" #define INIT_PRINTF(_args_) /* MAIOSDebugPrint _args_ */#define DPRINTF(_args_) /* MAIOSDebugPrint _args_ */#define INFO_PRINTF(_args_) /* MAIOSDebugPrint _args_ */static int frame_number;int mp4file; static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};xheaderinfo_t xheader;static faacDecHandle hDecoder;static int header_type = 0;static int tagsize;faacDecFrameInfo frameInfo;static faacDecConfigurationPtr config;static unsigned int cb_stream_position;static unsigned int cb_stream_size;static unsigned int cb_stream_used;static unsigned char *cb_stream_buffer;static long sampleId;static int gobble_amount;//static void dumpit(unsigned char * buf, int length)//{// int ii;// for (ii = 0; ii < length; ii++)// printf("%02x ", 0xff & *buf++);// printf("\n");//}//static void dumpitc(unsigned char * buf, int length)//{// int ii;// unsigned cc;// for (ii = 0; ii < length; ii++)// {// cc = *buf++;// if (isprint(cc))// printf("%c", cc);// else// printf(" ");// }// printf("\n");//}#if defined(WIN32) || defined(UNDER_CE) #if _MSC_VER typedef signed __int64 int64_t; #else typedef signed long long int64_t; #endif#endifstatic int undownmixed_number_of_channels;#define FRAC_ONE (1 << FRAC_BITS)#define FIX(a) ((int)((a) * FRAC_ONE))#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */#define MULL(a,b) ((int)(((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS))static short *downmix_buffer;static char *downmix_input_buffer;static int remaining_bytes;short *downmix_to_stereo(short *buf, int *length /* in bytes */) // assumes 16 bits per sample { int ii, used; int ch_length = *length / (undownmixed_number_of_channels * sizeof(short)); int input_length = *length; if (remaining_bytes) { memcpy(downmix_input_buffer+remaining_bytes, buf, *length); *length += remaining_bytes; remaining_bytes = 0; ch_length = *length / (undownmixed_number_of_channels * 2); input_length = *length; buf = (short *)downmix_input_buffer; } ch_length &= 0xfffff8; /* align to block */ switch (undownmixed_number_of_channels) { case 3: /* LF, CF, RF */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[3*ii], FIX(.5)) + MULL(buf[3*ii+1], FIX(.5)); downmix_buffer[2*ii + 1] = MULL(buf[3*ii+2], FIX(.5)) + MULL(buf[3*ii+1], FIX(.5)); } break; case 4: /* LF, RF, LR, RR */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[4*ii], FIX(.7)) + MULL(buf[4*ii+2], FIX(.4)); downmix_buffer[2*ii + 1] = MULL(buf[4*ii+1], FIX(.7)) + MULL(buf[4*ii+3], FIX(.4)); } break; case 5: /* LF, CF, RF, LR, RR */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[5*ii], FIX(.5)) + MULL(buf[5*ii+2], FIX(.4)) + MULL(buf[5*ii+1], FIX(.5)); downmix_buffer[2*ii + 1] = MULL(buf[5*ii+2], FIX(.5)) + MULL(buf[5*ii+4], FIX(.4)) + MULL(buf[5*ii+1], FIX(.5)); } break; case 6: /* CF, LF, RF, LR, RR, LFE Dolby's order is not used by AAC */ /* 0 1 2 3 4 5 */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[6*ii+1], FIX(.5)) - MULL(buf[6*ii+3], FIX(.4)) + MULL(buf[6*ii+0], FIX(.5)) + MULL(buf[6*ii+5], FIX(.2)); downmix_buffer[2*ii + 1] = MULL(buf[6*ii+2], FIX(.5)) - MULL(buf[6*ii+4], FIX(.4)) + MULL(buf[6*ii+0], FIX(.5)) + MULL(buf[6*ii+5], FIX(.2)); } break; case 7: /* LF, CF, RF, LR, RR, LFE, CR FIXIT this order may not be right */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[7*ii], FIX(.5)) + MULL(buf[7*ii+2], FIX(.4)) + MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3)); downmix_buffer[2*ii + 1] = MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+4], FIX(.4)) + MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3)); } break; case 8: /* LF, RF, CF, LFE, LR, RR, LS, RS */ /* AVI files do this. See: http://www.microsoft.com/windows/windowsmedia/howto/articles/creating71audio.aspx 0 Front left 1 Front right 2 Front center 3 Low frequency 4 Back left 5 Back right 6 Side left 7 Side right */ for (ii = 0; ii < ch_length; ii++) { downmix_buffer[2*ii] = MULL(buf[7*ii], FIX(.5)) + MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+3], FIX(.2)) - MULL(buf[7*ii+4], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3)); downmix_buffer[2*ii + 1] = MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+3], FIX(.2)) - MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+7], FIX(.3)); } break; default: remaining_bytes = 0; return buf; } used = (ch_length * undownmixed_number_of_channels * sizeof(short)); remaining_bytes = input_length - used; memcpy(downmix_input_buffer, ((char *)buf) + input_length - remaining_bytes, remaining_bytes); *length = (ch_length * 2 /* channels */ * sizeof(short)); return downmix_buffer;}int open_downmix(int buffer_max_size, int number_of_channels){ remaining_bytes = 0; if (downmix_buffer != NULL) free(downmix_buffer); if ((downmix_buffer = (short *)malloc(buffer_max_size * sizeof(short) * number_of_channels)) == NULL) { DPRINTF(("Unable to allocate downmix buffer\n")); return -1; } if (downmix_input_buffer != NULL) free(downmix_input_buffer); if ((downmix_input_buffer = (char *)malloc(buffer_max_size * sizeof(short) * number_of_channels)) == NULL) { DPRINTF(("Unable to allocate downmix input buffer\n")); return -1; } INFO_PRINTF(("Downmix %d to 2\n", undownmixed_number_of_channels)); return 0;}void close_downmix(void){ remaining_bytes = 0; if (downmix_buffer != NULL) free(downmix_buffer); downmix_buffer = NULL; if (downmix_input_buffer != NULL) free(downmix_input_buffer); downmix_input_buffer = NULL;}static int adts_parse(unsigned char *buffer, long *sampling_rate, int *frame_length){ /* check syncword */ if (!((buffer[0] == 0xFF) && ((buffer[1] & 0xF6) == 0xF0))) return 1; /* bad sync */ *sampling_rate = adts_sample_rates[(buffer[2]&0x3c)>>2]; *frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11) | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5); return 0;}/* channel definitions */#define SPEAKER_FRONT_LEFT 0x1#define SPEAKER_FRONT_RIGHT 0x2#define SPEAKER_FRONT_CENTER 0x4#define SPEAKER_LOW_FREQUENCY 0x8#define SPEAKER_BACK_LEFT 0x10#define SPEAKER_BACK_RIGHT 0x20#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80#define SPEAKER_BACK_CENTER 0x100#define SPEAKER_SIDE_LEFT 0x200#define SPEAKER_SIDE_RIGHT 0x400#define SPEAKER_TOP_CENTER 0x800#define SPEAKER_TOP_FRONT_LEFT 0x1000#define SPEAKER_TOP_FRONT_CENTER 0x2000#define SPEAKER_TOP_FRONT_RIGHT 0x4000#define SPEAKER_TOP_BACK_LEFT 0x8000#define SPEAKER_TOP_BACK_CENTER 0x10000#define SPEAKER_TOP_BACK_RIGHT 0x20000#define SPEAKER_RESERVED 0x80000000long aacChannelConfig2wavexChannelMask(faacDecFrameInfo *hInfo){ if (hInfo->channels == 6 && hInfo->num_lfe_channels) { return SPEAKER_FRONT_LEFT + SPEAKER_FRONT_RIGHT + SPEAKER_FRONT_CENTER + SPEAKER_LOW_FREQUENCY + SPEAKER_BACK_LEFT + SPEAKER_BACK_RIGHT; } else { return 0; }}char *position2string(int position){ switch (position) { case FRONT_CHANNEL_CENTER: return "Center front"; case FRONT_CHANNEL_LEFT: return "Left front"; case FRONT_CHANNEL_RIGHT: return "Right front"; case SIDE_CHANNEL_LEFT: return "Left side"; case SIDE_CHANNEL_RIGHT: return "Right side"; case BACK_CHANNEL_LEFT: return "Left back"; case BACK_CHANNEL_RIGHT: return "Right back"; case BACK_CHANNEL_CENTER: return "Center back"; case LFE_CHANNEL: return "LFE"; case UNKNOWN_CHANNEL: return "Unknown"; default: return ""; } return "";}void print_channel_info(faacDecFrameInfo *frameInfo){ /* print some channel info */ int i; long channelMask = aacChannelConfig2wavexChannelMask(frameInfo); INFO_PRINTF((M_TEXT(" ---------------------\n"))); if (frameInfo->num_lfe_channels > 0) { INFO_PRINTF((M_TEXT(" | Config: %2d.%d Ch |"), frameInfo->channels-frameInfo->num_lfe_channels, frameInfo->num_lfe_channels)); } else { INFO_PRINTF((M_TEXT(" | Config: %2d Ch |"), frameInfo->channels)); } if (channelMask) INFO_PRINTF((M_TEXT(" WARNING: channels are reordered according to\n"))); else INFO_PRINTF((M_TEXT("\n"))); INFO_PRINTF((M_TEXT(" ---------------------"))); if (channelMask) INFO_PRINTF((M_TEXT(" MS defaults defined in WAVE_FORMAT_EXTENSIBLE\n"))); else INFO_PRINTF((M_TEXT("\n"))); INFO_PRINTF((M_TEXT(" | Ch | Position |\n"))); INFO_PRINTF((M_TEXT(" ---------------------\n"))); for (i = 0; i < frameInfo->channels; i++) { INFO_PRINTF((M_TEXT(" | %.2d | %-14s |\n"), i, position2string((int)frameInfo->channel_position[i]))); } INFO_PRINTF((M_TEXT(" ---------------------\n"))); INFO_PRINTF((M_TEXT("\n")));}/* return the number of input bytes used */static long save_samplerate;static unsigned char save_channels;static unsigned char demux_stipulated_channels;static int demux_stipulated_samplerate = 0;#ifndef SBR_DEC static int non_SBR_upsample; static int non_SBR_ups_save[4];#endifint aacdecode(audiodecChangeInfo *ci, unsigned char **p_outbuf, int *out_size, unsigned char *input_buf, int inbuf_size, unsigned int stream_position){ int def_srate = 0; /* might want to use this later to force the sampling rate */ int bytes_read = 0; int track = 0; unsigned int frame_length; unsigned char *buffer; unsigned int buffer_size; cb_stream_position = stream_position; cb_stream_size = inbuf_size; cb_stream_buffer = input_buf; cb_stream_used = 0; // { // static int frame = 0; // printf("Frame %d\n", frame); // frame++; // } DPRINTF((M_TEXT("inputinputinputinputinputinput %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"), input_buf[0], input_buf[1], input_buf[2], input_buf[3], input_buf[4], input_buf[5], input_buf[6], input_buf[7], input_buf[8], input_buf[9], input_buf[10], input_buf[11], input_buf[12], input_buf[13], input_buf[14], input_buf[15])); /* gobble up the ID3 tag or other tag as needed */ if (gobble_amount) { if (gobble_amount > inbuf_size) { DPRINTF((M_TEXT("TAG: still gobbling %d\n"), gobble_amount)); gobble_amount -= inbuf_size; DPRINTF((M_TEXT("gobble left %d\n"), gobble_amount)); *out_size = 0; return inbuf_size; /* means we gobbled inbuf_size this time, and we need to gobble more */ } else { *out_size = 0; tagsize = gobble_amount; gobble_amount = 0; return tagsize; /* done gobbling */ } } DPRINTF((M_TEXT("check for header, frame %d\n"), frame_number)); /* check for header */ if (frame_number == 0) { mp4file = 0; demux_stipulated_channels = 0; demux_stipulated_samplerate = 0; /* This is our own interface for parsing with the demuxer. First four bytes: 'faac' Next byte: object type Next byte: channels Next int32: sampling rate */ if (input_buf[0] == 'f' && input_buf[1] == 'a' && input_buf[2] == 'a' && input_buf[3] == 'c') { /* bits meaning 5 objectTypeIndex 4 samplingFrequencyIndex 4 channelsConfiguration if objectTypeIndex == 5 SBR 4 samplingFrequencyIndex extension if samplingFrequencyIndex == 15 24 samplingFrequency 5 objectTypeIndex 11 syncExtensionType if syncExtensionType == 2b7 5 objectTypeIndex */ int samplerate; unsigned int samplerate_code; unsigned int object_type = input_buf[4]; unsigned int demux_chans = input_buf[5]; unsigned short obj; const int sample_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 }; hDecoder = faacDecOpen(); INIT_PRINTF((M_TEXT("Special FAAC\n"))); samplerate = input_buf[6]; samplerate |= ((unsigned int)input_buf[7]) << 8; samplerate |= ((unsigned int)input_buf[8]) << 16; samplerate |= ((unsigned int)input_buf[9]) << 24; demux_stipulated_samplerate = samplerate; for (samplerate_code = 0; samplerate_code < 12; samplerate_code++) { if (sample_rates[samplerate_code] == samplerate)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -