initial commit from tarball

This commit is contained in:
2021-07-04 10:00:20 +02:00
commit ad5143f78d
41 changed files with 5859 additions and 0 deletions

237
src/Makefile.am Normal file
View File

@@ -0,0 +1,237 @@
DISTCLEANFILES = 26410-800.zip $(top_srcdir)/26410-800.doc 26410-800-ANSI-C_source_code.zip $(library_sources_used) $(library_headers_used)
EXTRA_DIST = libaacplus.sym
INCLUDES = @FFTW3_INCFLAGS@ -I$(top_srcdir)/include
LDADD = @FFTW3_LDFLAGS@
lib_LTLIBRARIES = \
libaacplus.la
library_sources_used = \
aacenc.c \
aac_rom.c \
adj_thr.c \
band_nrg.c \
bitbuffer.c \
bit_cnt.c \
bitenc.c \
bit_sbr.c \
block_switch.c \
cfftn.c \
channel_map.c \
code_env.c \
dyn_bits.c \
env_bit.c \
env_est.c \
fram_gen.c \
freq_sca.c \
grp_data.c \
hybrid.c \
interface.c \
invf_est.c \
line_pe.c \
mh_det.c \
ms_stereo.c \
nf_est.c \
pre_echo_control.c \
ps_bitenc.c \
ps_enc.c \
psy_configuration.c \
psy_main.c \
qc_main.c \
qmf_enc.c \
quantize.c \
resampler.c \
sbr_main.c \
sbr_misc.c \
sbr_rom.c \
sf_estim.c \
spreading.c \
stat_bits.c \
stprepro.c \
tns.c \
tns_param.c \
ton_corr.c \
tran_det.c \
transcendent.c \
transform.c
libaacplus_la_SOURCES = $(library_sources_used) aacplusenc.c adts.c
libaacplus_la_LDFLAGS = \
-export-symbols libaacplus.sym -no-undefined -version-info 2:2:0 @FFTW3_LDFLAGS@
libaacplusdir = \
$(includedir)/libaacplus
#counters.h
library_headers_used = \
aacenc.h \
aac_rom.h \
adj_thr_data.h \
adj_thr.h \
band_nrg.h \
bit_cnt.h \
bitenc.h \
bit_sbr.h \
block_switch.h \
cfftn.h \
channel_map.h \
cmondata.h \
code_env.h \
dyn_bits.h \
env_bit.h \
env_est.h \
FFR_bitbuffer.h \
FloatFR.h \
fram_gen.h \
freq_sca.h \
grp_data.h \
hybrid.h \
interface.h \
invf_est.h \
line_pe.h \
mh_det.h \
minmax.h \
ms_stereo.h \
nf_est.h \
pre_echo_control.h \
ps_bitenc.h \
ps_enc.h \
psy_configuration.h \
psy_const.h \
psy_data.h \
psy_main.h \
qc_data.h \
qc_main.h \
qmf_enc.h \
quantize.h \
resampler.h \
sbr_def.h \
sbr.h \
sbr_main.h \
sbr_misc.h \
sbr_rom.h \
sf_estim.h \
spreading.h \
stat_bits.h \
stprepro.h \
tns_func.h \
tns.h \
tns_param.h \
ton_corr.h \
tran_det.h \
transform.h
noinst_HEADERS = $(library_headers_used) aacplusenc.h adts.h aac_ram.h sbr_ram.h
sources_delete:
@echo echo "Deleting headers..."
for source in $(library_headers_used); \
do \
rm -f $$source; \
done
@echo echo "Deleting sources..."
for source in $(library_sources_used); \
do \
rm -f $$source; \
done
sources_copy:
@echo echo "Copying headers..."
for source in $(library_headers_used); \
do \
find $(srcdir)/FloatFR_aacPlusenc -name $$source -type f -exec cp {} $(srcdir) \; ; \
done
@echo echo "Copying sources..."
for source in $(library_sources_used); \
do \
find $(srcdir)/FloatFR_aacPlusenc -name $$source -type f -exec cp {} $(srcdir) \; ; \
done
patch_all:
@echo echo "Patching sources and headers..."
find $(top_srcdir)/patches -name *.patch -type f -print | sort | xargs cat | $(PATCH)
remove_debugging_symbols:
@echo echo "Removeing debugging symbols..."
for source in $(library_sources_used); \
do \
sed -e 's/ADD\ *([\ 0-9\*]*)\ *;//g;' $$source | \
sed -e 's/BRANCH\ *([\ 0-9]*)\ *;//g;' | \
sed -e 's/DIV\ *([\ 0-9]*)\ *;//g;' | \
sed -e 's/FUNC\ *([\ 0-9]*)\ *;//g;' | \
sed -e 's/INDIRECT\ *([\ 0-9]*)\ *;//g;' | \
sed -e 's/LOGIC\ *([0-9\ ]*)\ *;//g;' | \
sed -e 's/LOOP\ *([0-9\ ]*)\ *;//g;' | \
sed -e 's/MAC\ *([0-9\ ]*)\ *;//g;' | \
sed -e 's/MOVE\ *([a-zA-Z_0-9\ \+\*]*)\ *;//g;' | \
sed -e 's/MISC\ *([0-9\ ]*)\ *;//g;' | \
sed -e 's/MULT\ *([0-9\ \*\+]*)\ *;//g;' | \
sed -e 's/PTR_INIT\ *([0-9\ ]*)\ *;*//g;' | \
sed -e 's/STORE.*[^;];//g;' | \
sed -e 's/SHIFT\ *([a-zA-Z0-9\ \+]*)\ *;//g;' | \
sed -e 's/SQRT\ *([0-9\ ]*)\ *;//g;' | \
sed -e 's/TRANS\ *([0-9\ ]*)\ *;//g;' | \
sed -e 's/COUNT_init\ *(.*)\ *;//g;' | \
sed -e 's/COUNT_end\ *(.*)\ *;//g;' | \
sed -e 's/COUNT_sub_start\ *(.*)\ *;//g;' | \
sed -e 's/COUNT_sub_end\ *(.*)\ *;//g;' | \
sed -e 's/COUNT_frame_update\ *(.*)\ *;//g;' | \
sed -e 's/COUNT_ops\ *(.*)\ *;//g;' | \
sed -e 's/COUNT_mem\ *(.*)\ *;//g;' | \
sed -e 's/^#include\ *"counters.h"//g;' > $${source#*/}.new; \
mv $${source#*/}.new $${source#*/}; \
done
unpack_3gp_sources:
if ! [ -e $(srcdir)/aacenc.c ]; \
then \
$(MAKE) $(srcdir)/26410-800-ANSI-C_source_code.zip; \
$(MAKE) $(srcdir)/FloatFR_aacPlusenc; \
rm -f $(srcdir)/26410-800-ANSI-C_source_code.zip; \
$(MAKE) sources_delete; \
$(MAKE) sources_copy; \
rm -rf $(srcdir)/FloatFR_aacPlusenc; \
chmod -x-x-x *.c *.h; \
$(MAKE) remove_debugging_symbols; \
$(MAKE) patch_all; \
fi
$(library_sources_used):
$(MAKE) unpack_3gp_sources
$(srcdir)/FloatFR_aacPlusenc:
cd $(srcdir) && $(UNZIP) 26410-800-ANSI-C_source_code.zip
mv -f $(srcdir)/3GPP_enhanced_aacPlus_src_*/FloatFR_aacPlusenc $(srcdir)
rm -rf $(srcdir)/3GPP_enhanced_aacPlus_src_*
$(srcdir)/26410-800-ANSI-C_source_code.zip: $(srcdir)/26410-800.zip
rm -f $(srcdir)/26410-800-ANSI-C_source_code.zip $(srcdir)/26410-800.doc
cd $(srcdir) && $(UNZIP) 26410-800.zip
mv $(srcdir)/26410-800.doc $(top_srcdir)/26410-800.doc
chmod og-w $(top_srcdir)/26410-800.doc
$(srcdir)/26410-800.zip:
cd $(srcdir) && $(DOWNLOADER_PROG) http://www.3gpp.org/ftp/Specs/archive/26_series/26.410/26410-800.zip
extraclean:
rm -f $(distdir)/($(library_sources_used)) $(distdir)/($(library_headers_used)) $(distdir)/26410-800.zip $(distdir)/../26410-800.doc $(distdir)/26410-800_ANSI-C_source_code.zip
# WARNING: These commands use internal automake command and may fail in future version.
extradist-gzip: distdir extraclean
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
extradist-bzip2: distdir extraclean
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
extradist extradist-all: distdir extraclean
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)

33
src/aac_ram.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* aac_ram.h
*
* Created on: 7 окт. 2010
* Author: tipok
*/
#ifndef AAC_RAM_H_
#define AAC_RAM_H_
#include <stdio.h>
typedef struct {
/* Static memory areas, must not be overwritten in other sections of the encoder */
/* aac Encoder mdct delay buffer */
float mdctDelayBuffer[MAX_CHANNELS*BLOCK_SWITCHING_OFFSET];
/* these tables are initialized once at application start
and are not touched thereafter */
int sideInfoTabLong[MAX_SFB_LONG + 1];
int sideInfoTabShort[MAX_SFB_SHORT + 1];
/* Dynamic memory areas, might be reused in other algorithm sections, */
/* quantized spectrum */
short *quantSpec;
/* scratch space for quantization */
float *expSpec; /* FRAME_LEN_LONG values */
short *quantSpecTmp;
/* scalefactors */
short *scf; /*[MAX_CHANNELS*MAX_GROUPED_SFB];*/
/* max spectral values pre sfb */
unsigned short *maxValueInSfb; /* [MAX_CHANNELS*MAX_GROUPED_SFB]; */
} AACRam_t;
#endif /* AAC_RAM_H_ */

392
src/aacplusenc.c Normal file
View File

@@ -0,0 +1,392 @@
/*
* aacplusenc.c
*
* Created on: 6 окт. 2010
* Author: tipok
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "aacplus.h"
#include "aacplusenc.h"
const int mpeg4audio_sample_rates[16] = {
96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000, 7350
};
const uint8_t mpeg4audio_channels[8] = {
0, 1, 2, 3, 4, 5, 6, 8
};
int aacplusEncInitSBRAACRam(struct AAC_ENCODER *aacenc)
{
SBRRam_t *sbr = calloc(1, sizeof(SBRRam_t));
AACRam_t *aac = calloc(1, sizeof(AACRam_t));
if(!sbr || !aac) return -1;
sbr->PsBuf2= &aac->mdctDelayBuffer[BLOCK_SWITCHING_OFFSET];
/* Overlay PsBuf4 and PsBuf5 with sbr_toncorrBuff of 2nd channel, since SBR only works in mono */
sbr->PsBuf4 = &sbr->sbr_toncorrBuff[5*NO_OF_ESTIMATES*MAX_FREQ_COEFFS];
sbr->PsBuf5 = &sbr->sbr_toncorrBuff[5*NO_OF_ESTIMATES*MAX_FREQ_COEFFS + PS_BUF4_SIZE];
aacenc->sbr_ram = sbr;
/* aac_ram.c */
aac->quantSpec = (short*) sbr->PsBuf3;
aac->expSpec = sbr->sbr_envIBuffer; /* FRAME_LEN_LONG values */
aac->quantSpecTmp = (short*) &sbr->sbr_envIBuffer[FRAME_LEN_LONG];
aac->scf= (short*) &sbr->sbr_envIBuffer[2*FRAME_LEN_LONG]; /*[MAX_CHANNELS*MAX_GROUPED_SFB];*/
aac->maxValueInSfb = (unsigned short*) &sbr->sbr_envIBuffer[2*FRAME_LEN_LONG+MAX_CHANNELS*MAX_GROUPED_SFB]; /* [MAX_CHANNELS*MAX_GROUPED_SFB]; */
aacenc->aac_ram = aac;
return 1;
}
int aacplusEncFreeSBRAACRam(struct AAC_ENCODER *aacenc)
{
free(aacenc->sbr_ram);
free(aacenc->aac_ram);
return 1;
}
aacplusEncHandle aacplusEncOpen(unsigned long sampleRate,
unsigned int numChannels,
unsigned long *inputSamples,
unsigned long *maxOutputBytes) {
AACPContext *aacp = NULL;
assert(numChannels <= MAX_CHANNELS);
aacp = calloc(1, sizeof(AACPContext));
if(!aacp)
return aacp;
/* set up basic parameters for aacPlus codec */
AacInitDefaultConfig(&aacp->config);
aacp->config.nChannelsIn = numChannels;
aacp->config.sampleRate = sampleRate;
aacp->writeOffset = INPUT_DELAY*MAX_CHANNELS;
aacplusEncInitSBRAACRam(&aacp->aacEnc);
//#ifdef _FFTW3
init_plans(&aacp->fftctx);
//#endif
*inputSamples = AACENC_BLOCKSIZE*2 * numChannels;
*maxOutputBytes = (6144/8)*MAX_CHANNELS+ADTS_HEADER_SIZE;
return (aacplusEncHandle ) aacp;
}
aacplusEncConfiguration *aacplusEncGetCurrentConfiguration(aacplusEncHandle hEncoder)
{
AACPContext *aacp = (AACPContext *) hEncoder;
if(!aacp) return NULL;
return &aacp->config;
}
int aacplusEncSetConfiguration(aacplusEncHandle hEncoder,
aacplusEncConfiguration *cfg) {
AACPContext *aacp = (AACPContext *) hEncoder;
assert(cfg);
if(cfg != &aacp->config)
memcpy(&aacp->config, cfg, sizeof(aacplusEncConfiguration));
int sampleRateAAC = aacp->config.sampleRate;
if(!aacp->config.nChannelsOut)
aacp->config.nChannelsOut = aacp->config.nChannelsIn;
if(!aacp->config.bitRate)
return 0;
if(aacp->config.bandWidth > aacp->config.sampleRate/2)
return 0;
/* set input samples for not only 1024 framesize */
aacp->config.inputSamples = aacp->config.nSamplesPerFrame * 2 * aacp->config.nChannelsIn;
if ( (aacp->config.nChannelsOut == 2) && (aacp->config.bitRate >= 16000) && (aacp->config.bitRate < 44001) ) {
aacp->config.nChannelsOut=1;
aacp->useParametricStereo=1;
aacp->envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS;
aacp->coreWriteOffset = CORE_INPUT_OFFSET_PS;
aacp->writeOffset = aacp->envReadOffset;
} else {
/* set up 2:1 downsampling */
InitIIR21_Resampler(&aacp->IIR21_reSampler[0]);
InitIIR21_Resampler(&aacp->IIR21_reSampler[1]);
assert(aacp->IIR21_reSampler[0].delay <= MAX_DS_FILTER_DELAY);
aacp->writeOffset += aacp->IIR21_reSampler[0].delay*MAX_CHANNELS;
}
/* set up SBR configuration */
if(!IsSbrSettingAvail(aacp->config.bitRate, aacp->config.nChannelsOut, sampleRateAAC, &sampleRateAAC)) {
fprintf(stderr, "libaacplus: bad aac setting: br:%d, AACch:%d, AACsr:%d\n",
aacp->config.bitRate, aacp->config.nChannelsOut, sampleRateAAC);
return 0;
}
InitializeSbrDefaults (&aacp->sbrConfig);
aacp->sbrConfig.usePs = aacp->useParametricStereo;
if(!AdjustSbrSettings( &aacp->sbrConfig, aacp->config.bitRate, aacp->config.nChannelsOut, sampleRateAAC, AACENC_TRANS_FAC, 24000)) {
fprintf(stderr, "libaacplus: bad sbr setting: br:%d, AACch:%d, AACsr:%d PS:%d\n",
aacp->config.bitRate, aacp->config.nChannelsOut, sampleRateAAC, aacp->sbrConfig.usePs);
return 0;
}
if(EnvOpen(aacp->aacEnc.sbr_ram,
&aacp->hEnvEnc,
&aacp->inBuf[aacp->coreWriteOffset],
&aacp->sbrConfig,
&aacp->config.bandWidth) != 0){
EnvClose (&aacp->hEnvEnc);
fprintf(stderr, "libaacplus: can't open sbr encoder\n");
return 0;
}
//#ifdef _FFTW3
aacp->hEnvEnc.fftctx = &aacp->fftctx;
//#endif
/* set up AAC encoder, now that samling rate is known */
aacp->config.sampleRate = sampleRateAAC;
if (AacEncOpen( &aacp->aacEnc, &aacp->config) != 0){
AacEncClose(&aacp->aacEnc);
fprintf(stderr, "libaacplus: can't open aac encoder\n");
return 0;
}
//#ifdef _FFTW3
aacp->aacEnc.fftctx = &aacp->fftctx;
//#endif
/* create the ADTS header */
if(cfg->outputFormat==1) {
aacp->adts = calloc(1, sizeof(ADTSContext_t));
if(!aacp->adts) {
fprintf(stderr, "libaacplus: can't create adts context\n");
return 0;
}
adts_hdr_init(aacp->adts, &aacp->config, &aacp->aacEnc.bitStream);
}
return 1;
}
int FindSRIndex(int sr)
{
int i;
for (i = 0; i < 16; i++) {
if (sr == mpeg4audio_sample_rates[i])
return i;
}
return 16 - 1;
}
int FindCHIndex(int ch)
{
int i;
for (i = 0; i < 16; i++) {
if (ch == mpeg4audio_channels[i])
return i;
}
return 16 - 1;
}
/*
object_type (AOT_AAC_LC) = || 0001 | 0
sr_idx (6 = 24000) = 011 || 0
chan_cfg (1 = 1) = 000 | 1
(specific_config_bitindex = 27 bits)
blablabla = 000
sync_extension = || 0101 | 0110 || 111
object_type (AOT_SBR) = 0 | 0101
have_new_sr? = || 1
sr_idx (3 = 48000) = 001 | 1
000 ||
///////////////////////////
PS:
101 || 0100 1000 || x... .... ||
7
*/
/* create extradata for aac+ */
#define AACPLUS_AOT_AAC_LC 2
#define AACPLUS_AOT_SBR 5
#define AACPLUS_LOAS_SYNC 0x2b7
#define AACPLUS_PS_EXT 0x548
int aacplusEncGetDecoderSpecificInfo(aacplusEncHandle hEncoder, unsigned char **ppBuffer,
unsigned long *pSizeOfDecoderSpecificInfo){
AACPContext *aacp = (AACPContext *) hEncoder;
int srate_idx, ch_idx;
int window_size = 0;
int loas_sync = AACPLUS_LOAS_SYNC;
int ps_extension = 0;
uint8_t *extradata = calloc(1, MAX_EXTRADATA_SIZE);
if(!extradata)
return -3;
if(aacp->useParametricStereo)
ps_extension = AACPLUS_PS_EXT;
srate_idx = FindSRIndex(aacp->config.sampleRate);
ch_idx = FindCHIndex(aacp->config.nChannelsOut);
if(aacp->config.nSamplesPerFrame != AACENC_BLOCKSIZE)
window_size = 1;
extradata[0] = AACPLUS_AOT_AAC_LC << 3 | srate_idx >> 1;
extradata[1] = srate_idx << 7 | ch_idx << 3 | window_size << 2;
srate_idx = FindSRIndex(aacp->config.sampleRate * 2);
extradata[2] = loas_sync >> 3; //sync extension
extradata[3] = (loas_sync << 5) & 0xe0 | AACPLUS_AOT_SBR; //sync extension + sbr hdr
extradata[4] = 1 << 7 | srate_idx << 3 | ps_extension >> 8;
if(ps_extension) {
extradata[5] = ps_extension & 0xff;
extradata[6] = 1 << 7;
*pSizeOfDecoderSpecificInfo = 7;
} else {
*pSizeOfDecoderSpecificInfo = 5;
}
// fprintf(stderr, "libaacplus: codec config(%d): %02x %02x %02x %02x %02x %02x %02x\n", *pSizeOfDecoderSpecificInfo,
// extradata[0], extradata[1], extradata[2], extradata[3], extradata[4], extradata[5], extradata[6]);
*ppBuffer = extradata;
return 1;
}
int aacplusEncEncode(aacplusEncHandle hEncoder, int32_t *inputBuffer, unsigned int samplesInput,
unsigned char *outputBuffer,
unsigned int bufferSize) {
AACPContext *aacp = (AACPContext *) hEncoder;
unsigned int i;
int ch, outSamples=0, numOutBytes = 0;
int adts_offset = 0;
assert(outputBuffer);
if(samplesInput > aacp->config.inputSamples)
return -1;
switch (aacp->config.inputFormat){
case AACPLUS_INPUT_16BIT: {
int16_t *inbuff = (int16_t *) inputBuffer;
for (i=0; i<samplesInput; i++)
aacp->inBuf[(2/aacp->config.nChannelsIn)*i+aacp->writeOffset+aacp->writtenSamples] = (float) inbuff[i];
break;
}
case AACPLUS_INPUT_FLOAT: {
float *inbuff = (float *) inputBuffer;
for (i=0; i<samplesInput; i++)
aacp->inBuf[(2/aacp->config.nChannelsIn)*i+aacp->writeOffset+aacp->writtenSamples] = inbuff[i] * SHRT_MAX;
break;
}
default:
return -1;
break;
}
/* Simple stereo to mono conversion: L = (L+R)/2 */
if((aacp->config.nChannelsIn == 2) &&
(aacp->config.nChannelsOut == 1) && !aacp->useParametricStereo) {
for (i=0; i<samplesInput/2; i++)
aacp->inBuf[i+aacp->writeOffset+aacp->writtenSamples] = (aacp->inBuf[i+aacp->writeOffset+aacp->writtenSamples]
+ aacp->inBuf[i+aacp->writeOffset+aacp->writtenSamples+1])*0.5f;
}
aacp->writtenSamples+=samplesInput;
if (aacp->writtenSamples < aacp->config.inputSamples)
return 0;
if(aacp->adts) adts_offset=ADTS_HEADER_SIZE;
if (bufferSize < (6144/8)*MAX_CHANNELS+adts_offset)
return -1;
/* encode one SBR frame */
EnvEncodeFrame( &aacp->hEnvEnc,
&aacp->inBuf[aacp->envReadOffset],
&aacp->inBuf[aacp->coreWriteOffset],
MAX_CHANNELS,
&aacp->numAncDataBytes,
aacp->ancDataBytes);
/* 2:1 downsampling for AAC core */
if (!aacp->useParametricStereo)
for( ch=0; ch<aacp->config.nChannelsIn; ch++ )
IIR21_Downsample( &aacp->IIR21_reSampler[ch],
&aacp->inBuf[aacp->writeOffset+ch],
aacp->config.nSamplesPerFrame * 2, //aacp->writtenSamples,
MAX_CHANNELS,
&aacp->inBuf[ch],
&outSamples,
MAX_CHANNELS);
AacEncEncode( &aacp->aacEnc,
aacp->inBuf,
aacp->useParametricStereo ? 1 : MAX_CHANNELS, /* stride (step) */
aacp->ancDataBytes,
&aacp->numAncDataBytes,
(unsigned *) (outputBuffer+adts_offset),
&numOutBytes);
if (aacp->useParametricStereo) {
memcpy( aacp->inBuf,&aacp->inBuf[aacp->config.nSamplesPerFrame],CORE_INPUT_OFFSET_PS*sizeof(float));
} else {
memmove( aacp->inBuf,&aacp->inBuf[aacp->config.nSamplesPerFrame*2*MAX_CHANNELS],
aacp->writeOffset*sizeof(float));
}
/* Write one frame of encoded audio */
if(numOutBytes > 0 && aacp->adts) {
adts_hdr_up(aacp->adts, outputBuffer, numOutBytes);
numOutBytes+=adts_offset;
}
aacp->writtenSamples=0;
return numOutBytes;
}
int aacplusEncClose(aacplusEncHandle hEncoder) {
AACPContext *aacp = (AACPContext *) hEncoder;
if(!aacp) return 0;
AacEncClose(&aacp->aacEnc);
EnvClose(&aacp->hEnvEnc);
//#ifdef _FFTW3
destroy_plans(&aacp->fftctx);
//#endif
aacplusEncFreeSBRAACRam(&aacp->aacEnc);
if(aacp->adts)
free(aacp->adts);
free(aacp);
return 1;
}

166
src/aacplusenc.h Normal file
View File

@@ -0,0 +1,166 @@
/*
* aacplusenc.h
*
* Created on: 7 окт. 2010
* Author: tipok
*/
#ifndef AACPLUSENC_H_
#define AACPLUSENC_H_
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*-------------------------- defines --------------------------------------*/
/* here we distinguish between stereo and the mono only encoder */
#ifdef MONO_ONLY
#define MAX_CHANNELS 1
#else
#define MAX_CHANNELS 2
#endif
#define AACENC_BLOCKSIZE 1024 /*! encoder only takes BLOCKSIZE samples at a time */
#define AACENC_TRANS_FAC 8 /*! encoder short long ratio */
#define AACENC_PCM_LEVEL 1.0 /*! encoder pcm 0db refernence */
#define MAX_EXTRADATA_SIZE 7 /* LC + SBR + PS config */
#define BUFFERSIZE 1024 /* anc data */
#include "aacplus.h"
#include "minmax.h"
#include "sbr_def.h"
#include "psy_const.h"
#include "cfftn.h"
#include "hybrid.h"
#include "sbr_ram.h"
#include "sbr_main.h"
#include "fram_gen.h"
#include "tran_det.h"
#include "code_env.h"
#include "qmf_enc.h"
#include "env_est.h"
#include "mh_det.h"
#include "nf_est.h"
#include "invf_est.h"
#include "ton_corr.h"
#include "tns.h"
#include "sbr.h"
#include "aac_ram.h"
#include "tns_param.h"
#include "aac_rom.h"
#include "dyn_bits.h"
#include "adj_thr_data.h"
#include "qc_data.h"
#include "block_switch.h"
#include "psy_data.h"
#include "interface.h"
#include "psy_configuration.h"
#include "psy_main.h"
#include "FFR_bitbuffer.h"
#include "bitenc.h"
#include "stprepro.h"
#include "aacenc.h"
#include "adj_thr.h"
#include "adts.h"
#include "band_nrg.h"
#include "bit_cnt.h"
#include "bit_sbr.h"
#include "channel_map.h"
#include "env_bit.h"
#include "FloatFR.h"
#include "freq_sca.h"
#include "grp_data.h"
#include "line_pe.h"
#include "ms_stereo.h"
#include "pre_echo_control.h"
#include "ps_bitenc.h"
#include "ps_enc.h"
#include "cmondata.h"
#include "qc_main.h"
#include "quantize.h"
#include "resampler.h"
#include "sbr_misc.h"
#include "sbr_rom.h"
#include "sf_estim.h"
#include "spreading.h"
#include "stat_bits.h"
#include "tns_func.h"
#include "transform.h"
struct SBR_ENCODER
{
FFTWFContext_t *fftctx;
struct SBR_CONFIG_DATA sbrConfigData;
struct SBR_HEADER_DATA sbrHeaderData;
struct SBR_BITSTREAM_DATA sbrBitstreamData;
struct ENV_CHANNEL* hEnvChannel[MAX_CHANNELS];
struct COMMON_DATA CmonData;
struct PS_ENC *hPsEnc;
SBR_QMF_FILTER_BANK *hSynthesisQmfBank;
unsigned int sbrPayloadPrevious[MAX_PAYLOAD_SIZE/(sizeof(int))];
unsigned int sbrPayload[MAX_PAYLOAD_SIZE/(sizeof(int))];
int sbrPayloadSize;
} ;
#define CORE_DELAY (1600)
/* (96-64) makes AAC still some 64 core samples too early wrt SBR ... maybe -32 would be even more correct, but 1024-32 would need additional SBR bitstream delay by one frame */
#define CORE_INPUT_OFFSET_PS (0)
/* ((1600 (core codec)*2 (multi rate) + 6*64 (sbr dec delay) - 2048 (sbr enc delay) + magic*/
#define INPUT_DELAY ((CORE_DELAY)*2 +6*64-(AACENC_BLOCKSIZE*2)+1)
/* the additional max resampler filter delay (source fs)*/
#define MAX_DS_FILTER_DELAY 16
typedef struct {
/* adts stuff */
ADTSContext_t *adts;
/* AAC encoder instance for one encoder */
aacplusEncConfiguration config;
struct AAC_ENCODER aacEnc;
sbrConfiguration sbrConfig;
struct SBR_ENCODER hEnvEnc;
SBR_QMF_FILTER_BANK SynthesisQmfBank;
struct PS_ENC psEncoder;
/* 2x => 1x samplerate converter instance */
IIR21_RESAMPLER IIR21_reSampler[MAX_CHANNELS];
//#ifdef _FFTW3
FFTWFContext_t fftctx;
//#endif
float inBuf[(AACENC_BLOCKSIZE*2 + MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS];
//char outBuf[(6144/8)*MAX_CHANNELS+ADTS_HEADER_SIZE];
unsigned int numAncDataBytes;
unsigned char ancDataBytes[MAX_PAYLOAD_SIZE];
int useParametricStereo;
unsigned int inSamples;
unsigned int writtenSamples;
unsigned int writeOffset;
int envReadOffset;
int coreWriteOffset;
} AACPContext;
int FindSRIndex(int sr);
#endif /* AACPLUSENC_H_ */

70
src/adts.c Normal file
View File

@@ -0,0 +1,70 @@
/*
adts
Original work by Matteo Croce
Small changes and fixes by Rafael Diniz
Copyright (C) Matteo Croce and Rafael Diniz
*/
#include <string.h>
#include "aacplusenc.h"
void adts_hdr_init(ADTSContext_t *ctx, aacplusEncConfiguration *config, HANDLE_BIT_BUF bitBuffer)
{
ctx->adts_size = ADTS_HEADER_SIZE;
int mpeg_id = ADTS_MPEG_ID;
int profile = ADTS_MPEG_PROFILE;
int srate_idx = FindSRIndex(config->sampleRate);
ctx->bitBuffer = bitBuffer;
/* adts use only 1024 samples window */
assert(config->nSamplesPerFrame == AACENC_BLOCKSIZE);
/* SOURCE: http://blog.olivierlanglois.net/index.php/2008/09/12/aac_adts_header_buffer_fullness_field */
unsigned short min_dec_in_size = (6144*config->nChannelsOut);
ctx->mean_framelength = (unsigned short)((float) config->bitRate/config->sampleRate*1024);
ctx->max_bit_reservoir = min_dec_in_size - ctx->mean_framelength;
ctx->frl_divider = 32*config->nChannelsOut;
memset(ctx->const_hdr, 0, 4);
ctx->const_hdr[0] = 0xFF; /* 8bits: syncword */
ctx->const_hdr[1] = 0xF0; /* 4bits: syncword */
ctx->const_hdr[1] |= mpeg_id << 3; /* 1bit: mpeg id = 0 */
/* 2bits: layer = 00 */
ctx->const_hdr[1] |= 1; /* 1bit: protection absent (1 - means "no protection")*/
ctx->const_hdr[2] = ((profile << 6) & 0xC0); /* 2bits: profile */
ctx->const_hdr[2] |= ((srate_idx << 2) & 0x3C); /* 4b: sampling_frequency_index */
/* 1b: private = 0 */
ctx->const_hdr[2] |= ((config->nChannelsOut >> 2) & 0x1); /* 1b: channel_configuration */
ctx->const_hdr[3] = ((config->nChannelsOut << 6) & 0xC0); /* 2b: channel_configuration */
}
void adts_hdr_up(ADTSContext_t *ctx, char *buff, int size)
{
unsigned short len = size + ADTS_HEADER_SIZE;
unsigned short buffer_fullness = 0x07FF;
memcpy(buff, ctx->const_hdr, 4);
//#ifdef ENABLE_BIT_RESERVOIR
ctx->bit_reservoir_state += ctx->mean_framelength - GetBitsAvail(ctx->bitBuffer);
if (ctx->bit_reservoir_state < 0) {
ctx->bit_reservoir_state = 0;
} else if (ctx->bit_reservoir_state > ctx->max_bit_reservoir) {
ctx->bit_reservoir_state = ctx->max_bit_reservoir;
}
buffer_fullness = ctx->bit_reservoir_state/ctx->frl_divider;
//#endif
/* frame length, 13 bits */
buff[3] &= 0xFC;
buff[3] |= ((len >> 11) & 0x03); /* 2b: aac_frame_length */
buff[4] = len >> 3; /* 8b: aac_frame_length */
buff[5] = (len << 5) & 0xE0; /* 3b: aac_frame_length */
/* buffer fullness, 11 bits */
buff[5] |= ((buffer_fullness >> 6) & 0x1F); /* 5b: adts_buffer_fullness */
buff[6] = (buffer_fullness << 2) & 0xFC; /* 6b: adts_buffer_fullness */
/* 2b: num_raw_data_blocks */
}

33
src/adts.h Normal file
View File

@@ -0,0 +1,33 @@
/*
adts
Original work by Matteo Croce
Small changes and fixes by Rafael Diniz
Copyright (C) Matteo Croce and Rafael Diniz
*/
#ifndef adts_h_
#define adts_h_
#include <stdint.h>
#include "aacplusenc.h"
#define ADTS_HEADER_SIZE 7
#define ADTS_MPEG_ID 1 /* 0: MPEG-4, 1: MPEG-2 */
#define ADTS_MPEG_PROFILE 1
typedef struct {
HANDLE_BIT_BUF bitBuffer;
uint8_t const_hdr[4];
int bit_reservoir_state;
unsigned short mean_framelength;
unsigned short frl_divider;
unsigned short max_bit_reservoir;
int adts_size;
int window_size;
} ADTSContext_t;
void adts_hdr_init(ADTSContext_t *ctx, aacplusEncConfiguration *config, HANDLE_BIT_BUF bitBuffer);
void adts_hdr_up(ADTSContext_t *ctx, char *buff, int size);
#endif

6
src/libaacplus.sym Normal file
View File

@@ -0,0 +1,6 @@
aacplusEncGetCurrentConfiguration
aacplusEncSetConfiguration
aacplusEncOpen
aacplusEncGetDecoderSpecificInfo
aacplusEncEncode
aacplusEncClose

123
src/sbr_ram.h Normal file
View File

@@ -0,0 +1,123 @@
/*
* sbr_ram.h
*
* Created on: 7 окт. 2010
* Author: tipok
*/
#ifndef SBR_RAM_H_
#define SBR_RAM_H_
#include <stdio.h>
#include <assert.h>
#define PS_BUF4_SIZE (4*(QMF_TIME_SLOTS + QMF_BUFFER_MOVE) + 4*(NO_QMF_BANDS_IN_HYBRID + NO_QMF_BANDS_IN_HYBRID*QMF_BUFFER_MOVE))
#define PS_BUF5_SIZE (QMF_FILTER_LENGTH/2 + QMF_CHANNELS)
typedef struct {
/* sbr_ram.c */
/* Overlay with mdctDelayBuffer of 2nd channel since AAC only works in mono */
float *PsBuf2;
/* Overlay PsBuf4 and PsBuf5 with sbr_toncorrBuff of 2nd channel, since SBR only works in mono */
float *PsBuf4;
float *PsBuf5;
float PsBuf3[MAX_CHANNELS*FRAME_LEN_LONG*sizeof(short)/sizeof(float)];
/*!
\name StaticSbrData
Static memory areas, must not be overwritten in other sections of the encoder
*/
/*! Filter states for QMF-analysis. <br>
Dimension: #MAXNRSBRCHANNELS * #SBR_QMF_FILTER_LENGTH */
float sbr_QmfStatesAnalysis[MAX_CHANNELS * QMF_FILTER_LENGTH];
/*! Energy buffer for envelope extraction <br>
Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_SLOTS*2 * #SBR_QMF_CHANNELS
*/
float sbr_envYBuffer[MAX_CHANNELS * QMF_TIME_SLOTS * QMF_CHANNELS];
/*! Matrix holding the quota values for all estimates, all channels
Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_CHANNELS* #NO_OF_ESTIMATES
*/
float sbr_quotaMatrix[MAX_CHANNELS * NO_OF_ESTIMATES*QMF_CHANNELS];
/*! Thresholds for transient detection <br>
Dimension #MAXNRSBRCHANNELS * #SBR_QMF_CHANNELS
*/
float sbr_thresholds[MAX_CHANNELS *QMF_CHANNELS];
/*! Frequency band table (low res) <br>
Dimension #MAX_FREQ_COEFFS/2+1
*/
unsigned char sbr_freqBandTableLO[MAX_FREQ_COEFFS/2+1];
/*! Frequency band table (high res) <br>
Dimension #MAX_FREQ_COEFFS +1
*/
unsigned char sbr_freqBandTableHI[MAX_FREQ_COEFFS+1];
/*! vk matser table <br>
Dimension #MAX_FREQ_COEFFS +1
*/
unsigned char sbr_v_k_master[MAX_FREQ_COEFFS +1];
/*
Missing harmonics detection
*/
/*! sbr_detectionVectors <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
*/
unsigned char sbr_detectionVectors[MAX_CHANNELS*NO_OF_ESTIMATES*MAX_FREQ_COEFFS];
/*!
The following tonality correclation buffers are allocated in
one non-reusable buffer
sbr_tonalityDiff <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
sbr_sfmOrig <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
sbr_sfmSbr <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
sbr_guideVectorDiff <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
sbr_guideVectorOrig <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
*/
/* To overlay 2nd half of sbr_toncorrBuff with PS-Buffers, the 2nd half
must not fall below a minium size */
float sbr_toncorrBuff[max( /* two channels or... */
(MAX_CHANNELS*5*NO_OF_ESTIMATES*MAX_FREQ_COEFFS),
(
/* 1st half */
(5*NO_OF_ESTIMATES*MAX_FREQ_COEFFS)+
PS_BUF4_SIZE + PS_BUF5_SIZE
)
)];
/*! sbr_prevCompVec[ <br>
Dimension #MAX_CHANNELS*#MAX_FREQ_COEFFS]
*/
char sbr_prevEnvelopeCompensation[MAX_CHANNELS*MAX_FREQ_COEFFS];
/*! sbr_guideScfb[ <br>
Dimension #MAX_CHANNELS*#MAX_FREQ_COEFFS]
*/
unsigned char sbr_guideScfb[MAX_CHANNELS*MAX_FREQ_COEFFS];
/*! sbr_guideVectorDiff <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
*/
/*! sbr_guideVectorDetected <br>
Dimension #MAX_CHANNELS*#NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
*/
unsigned char sbr_guideVectorDetected[MAX_CHANNELS*NO_OF_ESTIMATES*MAX_FREQ_COEFFS];
/*!
\name DynamicSbrData
Dynamic memory areas, might be reused in other algorithm sections,
e.g. the core decoder
*/
/*! Real buffer for envelope extraction <br>
Dimension #SBR_QMF_SLOTS * #SBR_QMF_CHANNELS
*/
float sbr_envRBuffer [MAX_CHANNELS * QMF_TIME_SLOTS * QMF_CHANNELS];
/*! Imag buffer for envelope extraction <br>
Dimension #SBR_QMF_SLOTS * #SBR_QMF_CHANNELS
*/
float sbr_envIBuffer [MAX_CHANNELS * QMF_TIME_SLOTS * QMF_CHANNELS];
/*! Transients for transient detection <br>
Dimension MAX_CHANNELS*3* #QMF_TIME_SLOTS
*/
float sbr_transients[MAX_CHANNELS*3*QMF_TIME_SLOTS];
} SBRRam_t;
#endif /* SBR_RAM_H_ */