Initial commit

This commit is contained in:
Milan Nikolic 2018-03-06 04:50:55 +01:00
commit 0e9ca200fb
84 changed files with 20788 additions and 0 deletions

22
.appveyor.yml Normal file
View file

@ -0,0 +1,22 @@
version: "{build}"
clone_depth: 1
clone_folder: c:\gopath\src\github.com\gen2brain\aac-go
environment:
GOPATH: c:\gopath
MSYS_PATH: c:\msys64
CGO_ENABLED: 1
GOARCH: 386
CC: i686-w64-mingw32-gcc
install:
- echo %GOPATH%
- echo %MSYS_PATH%
- set PATH=%GOPATH%\bin;c:\go\bin;%MSYS_PATH%\usr\bin;%MSYS_PATH%\mingw32\bin;%PATH%
- go version
- go env
build_script:
- bash -lc "cd /c/gopath/src/github.com/gen2brain/aac-go && go build"

7
.travis.yml Normal file
View file

@ -0,0 +1,7 @@
language: go
go:
- 1.9.x
script:
- go test -v ./

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
Milan Nikolic <gen2brain@gmail.com>

191
COPYING Normal file
View file

@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the
copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other
entities that control, are controlled by, or are under common control with
that entity. For the purposes of this definition, "control" means (i) the
power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty
percent (50%) or more of the outstanding shares, or (iii) beneficial
ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation source,
and configuration files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled
object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the
Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial
revisions, annotations, elaborations, or other modifications represent, as
a whole, an original work of authorship. For the purposes of this License,
Derivative Works shall not include works that remain separable from, or
merely link (or bind by name) to the interfaces of, the Work and Derivative
Works thereof.
"Contribution" shall mean any work of authorship, including the original
version of the Work and any modifications or additions to that Work or
Derivative Works thereof, that is intentionally submitted to Licensor for
inclusion in the Work by the copyright owner or by an individual or Legal
Entity authorized to submit on behalf of the copyright owner. For the
purposes of this definition, "submitted" means any form of electronic,
verbal, or written communication sent to the Licensor or its
representatives, including but not limited to communication on electronic
mailing lists, source code control systems, and issue tracking systems that
are managed by, or on behalf of, the Licensor for the purpose of discussing
and improving the Work, but excluding communication that is conspicuously
marked or otherwise designated in writing by the copyright owner as "Not a
Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on
behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
reproduce, prepare Derivative Works of, publicly display, publicly perform,
sublicense, and distribute the Work and such Derivative Works in Source or
Object form.
3. Grant of Patent License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in
this section) patent license to make, have made, use, offer to sell, sell,
import, and otherwise transfer the Work, where such license applies only to
those patent claims licensable by such Contributor that are necessarily
infringed by their Contribution(s) alone or by combination of their
Contribution(s) with the Work to which such Contribution(s) was submitted.
If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or
contributory patent infringement, then any patent licenses granted to You
under this License for that Work shall terminate as of the date such
litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
1. You must give any other recipients of the Work or Derivative Works a
copy of this License; and
2. You must cause any modified files to carry prominent notices stating
that You changed the files; and
3. You must retain, in the Source form of any Derivative Works that You
distribute, all copyright, patent, trademark, and attribution notices from
the Source form of the Work, excluding those notices that do not pertain to
any part of the Derivative Works; and
4. If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must include a
readable copy of the attribution notices contained within such NOTICE file,
excluding those notices that do not pertain to any part of the Derivative
Works, in at least one of the following places: within a NOTICE text file
distributed as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or, within a
display generated by the Derivative Works, if and wherever such third-party
notices normally appear. The contents of the NOTICE file are for
informational purposes only and do not modify the License. You may add Your
own attribution notices within Derivative Works that You distribute,
alongside or as an addendum to the NOTICE text from the Work, provided that
such additional attribution notices cannot be construed as modifying the
License.
You may add Your own copyright statement to Your modifications and may
provide additional or different license terms and conditions for use,
reproduction, or distribution of Your modifications, or for any such
Derivative Works as a whole, provided Your use, reproduction, and
distribution of the Work otherwise complies with the conditions stated in
this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to
the Licensor shall be under the terms and conditions of this License,
without any additional terms or conditions. Notwithstanding the above,
nothing herein shall supersede or modify the terms of any separate license
agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor, except
as required for reasonable and customary use in describing the origin of
the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
in writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any
warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or
FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for
determining the appropriateness of using or redistributing the Work and
assume any risks associated with Your exercise of permissions under this
License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or
inability to use the Work (including but not limited to damages for loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor has been
advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the
Work or Derivative Works thereof, You may choose to offer, and charge a fee
for, acceptance of support, warranty, indemnity, or other liability
obligations and/or rights consistent with this License. However, in
accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if
You agree to indemnify, defend, and hold each Contributor harmless for any
liability incurred by, or claims asserted against, such Contributor by
reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included
on the same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain a
copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable
law or agreed to in writing, software distributed under the License is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.

69
README.md Normal file
View file

@ -0,0 +1,69 @@
## aac-go
[![TravisCI Build Status](https://travis-ci.org/gen2brain/aac-go.svg?branch=master)](https://travis-ci.org/gen2brain/aac-go)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/wfkqlac5ffwk5xgb?svg=true)](https://ci.appveyor.com/project/gen2brain/aac-go)
[![GoDoc](https://godoc.org/github.com/gen2brain/aac-go?status.svg)](https://godoc.org/github.com/gen2brain/aac-go)
[![Go Report Card](https://goreportcard.com/badge/github.com/gen2brain/aac-go?branch=master)](https://goreportcard.com/report/github.com/gen2brain/aac-go)
`aac-go` provides AAC codec encoder based on [VisualOn AAC encoder library](https://github.com/mstorsjo/vo-aacenc) library.
### Installation
go get -u github.com/gen2brain/aac-go
### Example
```go
package main
import (
"bytes"
"io/ioutil"
"os"
"github.com/gen2brain/aac-go"
"github.com/youpy/go-wav"
)
func main() {
file, err := os.Open("test.wav")
if err != nil {
panic(err)
}
wreader := wav.NewReader(file)
f, err := wreader.Format()
if err != nil {
panic(err)
}
buf := bytes.NewBuffer(make([]byte, 0))
opts := &aac.Options{}
opts.SampleRate = int(f.SampleRate)
opts.NumChannels = int(f.NumChannels)
enc, err := aac.NewEncoder(buf, opts)
if err != nil {
panic(err)
}
err = enc.Encode(wreader)
if err != nil {
panic(err)
}
err = enc.Close()
if err != nil {
panic(err)
}
err = ioutil.WriteFile("test.aac", buf.Bytes(), 0644)
if err != nil {
panic(err)
}
}
```
## More
For H.264 encoder see [x264-go](https://github.com/gen2brain/x264-go).

316
aacenc/aacenc.go Normal file
View file

@ -0,0 +1,316 @@
// Package aacenc implements cgo bindings for [VisualOn AAC encoder library](https://github.com/mstorsjo/vo-aacenc) library.
package aacenc
//#include "voAAC.h"
import "C"
import (
"errors"
"unsafe"
)
// Constants.
const (
// AAC Param ID
VoPidAacMdoule = 0x42211000
VoPidAacEncparam = VoPidAacMdoule | 0x0040
// AAC decoder error ID
VoErrAacMdoule = 0x82210000
VoErrAacUnsfileformat = (VoErrAacMdoule | 0xF001)
VoErrAacUnsprofile = (VoErrAacMdoule | 0xF002)
// The base param ID for AUDIO codec
VoPidAudioBase = 0x42000000
// The format data of audio in track
VoPidAudioFormat = (VoPidAudioBase | 0x0001)
// The sample rate of audio
VoPidAudioSampleRate = (VoPidAudioBase | 0x0002)
// The channel of audio
VoPidAudioChannels = (VoPidAudioBase | 0x0003)
// The bit rate of audio
VoPidAudioBitrate = (VoPidAudioBase | 0x0004)
// The channel mode of audio
VoPidAudioChannelmode = (VoPidAudioBase | 0x0005)
// The base of common param ID
VoPidCommonBase = 0x40000000
// Query the memory needed; Reserved
VoPidCommonQueryMem = (VoPidCommonBase | 0)
// Set or get the input buffer type
VoPidCommonInputType = (VoPidCommonBase | 0)
// Query it has resource to be used
VoPidCommonHasResource = (VoPidCommonBase | 0)
// Decoder track header data
VoPidCommonHeadData = (VoPidCommonBase | 0)
// VoPidCommonFlush as defined in include/voIndex.h:182
VoPidCommonFlush = (VoPidCommonBase | 0)
)
// Error codes.
const (
VoErrNone = 0x00000000
VoErrFinish = 0x00000001
VoErrFailed = 0x80000001
VoErrOutofMemory = 0x80000002
VoErrNotImplement = 0x80000003
VoErrInvalidArg = 0x80000004
VoErrInputBufferSmall = 0x80000005
VoErrOutputBufferSmall = 0x80000006
VoErrWrongStatus = 0x80000007
VoErrWrongParamId = 0x80000008
VoErrLicenseError = 0x80000009
VoErrAudioBase = 0x82000000
VoErrAudioUnsChannel = VoErrAudioBase | 0x0001
VoErrAudioUnsSampleRate = VoErrAudioBase | 0x0002
VoErrAudioUnsFeature = VoErrAudioBase | 0x0003
)
// Enumeration used to define the possible audio coding formats.
const (
// Placeholder value when coding is N/A
VoAudioCodingUnused int32 = iota
// Any variant of PCM coding
VoAudioCodingPcm
// Any variant of ADPCM encoded data
VoAudioCodingAdpcm
// Any variant of AMR encoded data
VoAudioCodingAmrnb
// Any variant of AMR encoded data
VoAudioCodingAmrwb
// Any variant of AMR encoded data
VoAudioCodingAmrwbp
// Any variant of QCELP 13kbps encoded data
VoAudioCodingQcelp13
// Any variant of EVRC encoded data
VoAudioCodingEvrc
// Any variant of AAC encoded data, 0xA106 - ISO/MPEG-4 AAC, 0xFF - AAC
VoAudioCodingAac
// Any variant of AC3 encoded data
VoAudioCodingAc3
// Any variant of FLAC encoded data
VoAudioCodingFlac
// Any variant of MP1 encoded data
VoAudioCodingMp1
// Any variant of MP3 encoded data
VoAudioCodingMp3
// Any variant of OGG encoded data
VoAudioCodingOgg
// Any variant of WMA encoded data
VoAudioCodingWma
// Any variant of RA encoded data
VoAudioCodingRa
// Any variant of MIDI encoded data
VoAudioCodingMidi
// Any variant of dra encoded data
VoAudioCodingDra
// Any variant of dra encoded data
VoAudioCodingG729
)
// The frame type that the decoder supports.
const (
// Contains only raw aac data in a frame
VoAacRawdata int32 = iota
// Contains ADTS header + raw AAC data in a frame
VoAacAdts
)
// The channel type value.
const (
// Center channel
VoChannelCenter int32 = 1
// Front left channel
VoChannelFrontLeft = 1 << 1
// Front right channel
VoChannelFrontRight = 1 << 2
// Side left channel
VoChannelSideLeft = 1 << 3
// Side right channel
VoChannelSideRight = 1 << 4
// Back left channel
VoChannelBackLeft = 1 << 5
// Back right channel
VoChannelBackRight = 1 << 6
// Back center channel
VoChannelBackCenter = 1 << 7
// Low-frequency effects bass channel
VoChannelLfeBass = 1 << 8
// Include all channels (default)
VoChannelAll = 0xffff
)
// Input stream format, Frame or Stream.
const (
// Input contains completely frame(s) data
VoInputFrame int32 = iota + 1
// Input is stream data.
VoInputStream
)
// VoAudioFormat - general audio format info.
type VoAudioFormat struct {
// Sample rate
SampleRate int
// Channel count
Channels int
// Bits per sample
SampleBits int
}
// cptr return C pointer.
func (v *VoAudioFormat) cptr() *C.VO_AUDIO_FORMAT {
return (*C.VO_AUDIO_FORMAT)(unsafe.Pointer(v))
}
// VoAudioOutputinfo - general audio output info.
type VoAudioOutputinfo struct {
// Sample rate
Format VoAudioFormat
// Channel count
InputUsed uint
// Reserved
Reserve uint
}
// cptr return C pointer.
func (v *VoAudioOutputinfo) cptr() *C.VO_AUDIO_OUTPUTINFO {
return (*C.VO_AUDIO_OUTPUTINFO)(unsafe.Pointer(v))
}
// VoCodecBuffer - general data buffer, used as input or output.
type VoCodecBuffer struct {
// Buffer pointer
Buffer unsafe.Pointer
// Buffer size in byte
Length uint64
// The time of the buffer
Time int64
}
// cptr return C pointer.
func (v *VoCodecBuffer) cptr() *C.VO_CODECBUFFER {
return (*C.VO_CODECBUFFER)(unsafe.Pointer(v))
}
// AacencParam - the structure for AAC encoder input parameter.
type AacencParam struct {
// Audio file sample rate
SampleRate int32
// Encoder bit rate in bits/sec
BitRate int32
// Number of channels on input (1,2)
NChannels int16
// Whether write adts header
AdtsUsed int16
}
var handle C.VO_HANDLE
// Errors.
var (
ErrFinish = errors.New("aac: error finish")
ErrFailed = errors.New("aac: process data failed")
ErrOutOfMemory = errors.New("aac: out of memory")
ErrNotImplement = errors.New("aac: feature not implemented")
ErrInvalidArg = errors.New("aac: invalid argument")
ErrInputBufferSmall = errors.New("aac: input buffer data too small")
ErrOutputBufferSmall = errors.New("aac: output buffer size too small")
ErrWrongStatus = errors.New("aac: wrong encoder run-time status")
ErrWrongParamId = errors.New("aac: wrong parameter id")
ErrLicenseError = errors.New("aac: license error")
ErrAudioBase = errors.New("aac: error audio base")
ErrAudioUnsChannel = errors.New("aac: unsupported number of channel")
ErrAudioUnsSampleRate = errors.New("aac: unsupported sample rate")
ErrAudioUnsFeature = errors.New("aac: unsupported feature")
)
// ErrorFromResult returns error for result code
func ErrorFromResult(r uint) error {
switch r {
case VoErrNone:
return nil
case VoErrFinish:
return ErrFinish
case VoErrFailed:
return ErrFailed
case VoErrOutofMemory:
return ErrOutOfMemory
case VoErrNotImplement:
return ErrNotImplement
case VoErrInvalidArg:
return ErrInvalidArg
case VoErrInputBufferSmall:
return ErrInputBufferSmall
case VoErrOutputBufferSmall:
return ErrOutputBufferSmall
case VoErrWrongStatus:
return ErrWrongStatus
case VoErrWrongParamId:
return ErrWrongParamId
case VoErrLicenseError:
return ErrLicenseError
case VoErrAudioBase:
return ErrAudioBase
case VoErrAudioUnsChannel:
return ErrAudioUnsChannel
case VoErrAudioUnsSampleRate:
return ErrAudioUnsSampleRate
case VoErrAudioUnsFeature:
return ErrAudioUnsFeature
default:
return nil
}
}
// Init - init the audio codec module and return codec handle.
func Init(vtype int32) uint {
cvtype := (C.VO_AUDIO_CODINGTYPE)(vtype)
ret := C.voAACEncInit(&handle, cvtype, nil)
v := (uint)(ret)
return v
}
// SetInputData - set input audio data.
func SetInputData(pinput *VoCodecBuffer) uint {
cpinput := pinput.cptr()
ret := C.voAACEncSetInputData(handle, cpinput)
v := (uint)(ret)
return v
}
// GetOutputData - get the outut audio data.
func GetOutputData(poutbuffer *VoCodecBuffer, poutinfo *VoAudioOutputinfo) uint {
cpoutbuffer := poutbuffer.cptr()
cpoutinfo := poutinfo.cptr()
ret := C.voAACEncGetOutputData(handle, cpoutbuffer, cpoutinfo)
v := (uint)(ret)
return v
}
// SetParam - set the parameter for the specified param ID.
func SetParam(uparamid int, pdata unsafe.Pointer) uint {
cuparamid := (C.VO_S32)(uparamid)
cpdata := (C.VO_PTR)(pdata)
ret := C.voAACEncSetParam(handle, cuparamid, cpdata)
v := (uint)(ret)
return v
}
// GetParam - get the parameter for the specified param ID.
func GetParam(uparamid int, pdata unsafe.Pointer) uint {
cuparamid := (C.VO_S32)(uparamid)
cpdata := (C.VO_PTR)(pdata)
ret := C.voAACEncGetParam(handle, cuparamid, cpdata)
v := (uint)(ret)
return v
}
// Uninit - uninit the Codec.
func Uninit() uint {
ret := C.voAACEncUninit(handle)
v := (uint)(ret)
return v
}

36
aacenc/aacenc_cgo.go Normal file
View file

@ -0,0 +1,36 @@
package aacenc
/*
#include "external/aacenc/src/cmnMemory.c"
#include "external/aacenc/src/basicop2.c"
#include "external/aacenc/src/oper_32b.c"
#include "external/aacenc/src/aac_rom.c"
#include "external/aacenc/src/aacenc.c"
#include "external/aacenc/src/aacenc_core.c"
#include "external/aacenc/src/adj_thr.c"
#include "external/aacenc/src/band_nrg.c"
#include "external/aacenc/src/bit_cnt.c"
#include "external/aacenc/src/bitbuffer.c"
#include "external/aacenc/src/bitenc.c"
#include "external/aacenc/src/block_switch.c"
#include "external/aacenc/src/channel_map.c"
#include "external/aacenc/src/dyn_bits.c"
#include "external/aacenc/src/grp_data.c"
#include "external/aacenc/src/interface.c"
#include "external/aacenc/src/line_pe.c"
#include "external/aacenc/src/memalign.c"
#include "external/aacenc/src/ms_stereo.c"
#include "external/aacenc/src/pre_echo_control.c"
#include "external/aacenc/src/psy_configuration.c"
#include "external/aacenc/src/psy_main.c"
#include "external/aacenc/src/qc_main.c"
#include "external/aacenc/src/quantize.c"
#include "external/aacenc/src/sf_estim.c"
#include "external/aacenc/src/spreading.c"
#include "external/aacenc/src/stat_bits.c"
#include "external/aacenc/src/tns.c"
#include "external/aacenc/src/transform.c"
#cgo CFLAGS: -std=gnu99 -Iexternal/aacenc/include -DUSE_DEFAULT_MEM
*/
import "C"

191
aacenc/external/aacenc/COPYING vendored Normal file
View file

@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the
copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other
entities that control, are controlled by, or are under common control with
that entity. For the purposes of this definition, "control" means (i) the
power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty
percent (50%) or more of the outstanding shares, or (iii) beneficial
ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation source,
and configuration files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled
object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the
Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial
revisions, annotations, elaborations, or other modifications represent, as
a whole, an original work of authorship. For the purposes of this License,
Derivative Works shall not include works that remain separable from, or
merely link (or bind by name) to the interfaces of, the Work and Derivative
Works thereof.
"Contribution" shall mean any work of authorship, including the original
version of the Work and any modifications or additions to that Work or
Derivative Works thereof, that is intentionally submitted to Licensor for
inclusion in the Work by the copyright owner or by an individual or Legal
Entity authorized to submit on behalf of the copyright owner. For the
purposes of this definition, "submitted" means any form of electronic,
verbal, or written communication sent to the Licensor or its
representatives, including but not limited to communication on electronic
mailing lists, source code control systems, and issue tracking systems that
are managed by, or on behalf of, the Licensor for the purpose of discussing
and improving the Work, but excluding communication that is conspicuously
marked or otherwise designated in writing by the copyright owner as "Not a
Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on
behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
reproduce, prepare Derivative Works of, publicly display, publicly perform,
sublicense, and distribute the Work and such Derivative Works in Source or
Object form.
3. Grant of Patent License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in
this section) patent license to make, have made, use, offer to sell, sell,
import, and otherwise transfer the Work, where such license applies only to
those patent claims licensable by such Contributor that are necessarily
infringed by their Contribution(s) alone or by combination of their
Contribution(s) with the Work to which such Contribution(s) was submitted.
If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or
contributory patent infringement, then any patent licenses granted to You
under this License for that Work shall terminate as of the date such
litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
1. You must give any other recipients of the Work or Derivative Works a
copy of this License; and
2. You must cause any modified files to carry prominent notices stating
that You changed the files; and
3. You must retain, in the Source form of any Derivative Works that You
distribute, all copyright, patent, trademark, and attribution notices from
the Source form of the Work, excluding those notices that do not pertain to
any part of the Derivative Works; and
4. If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must include a
readable copy of the attribution notices contained within such NOTICE file,
excluding those notices that do not pertain to any part of the Derivative
Works, in at least one of the following places: within a NOTICE text file
distributed as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or, within a
display generated by the Derivative Works, if and wherever such third-party
notices normally appear. The contents of the NOTICE file are for
informational purposes only and do not modify the License. You may add Your
own attribution notices within Derivative Works that You distribute,
alongside or as an addendum to the NOTICE text from the Work, provided that
such additional attribution notices cannot be construed as modifying the
License.
You may add Your own copyright statement to Your modifications and may
provide additional or different license terms and conditions for use,
reproduction, or distribution of Your modifications, or for any such
Derivative Works as a whole, provided Your use, reproduction, and
distribution of the Work otherwise complies with the conditions stated in
this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to
the Licensor shall be under the terms and conditions of this License,
without any additional terms or conditions. Notwithstanding the above,
nothing herein shall supersede or modify the terms of any separate license
agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor, except
as required for reasonable and customary use in describing the origin of
the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
in writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any
warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or
FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for
determining the appropriateness of using or redistributing the Work and
assume any risks associated with Your exercise of permissions under this
License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or
inability to use the Work (including but not limited to damages for loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor has been
advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the
Work or Derivative Works thereof, You may choose to offer, and charge a fee
for, acceptance of support, warranty, indemnity, or other liability
obligations and/or rights consistent with this License. However, in
accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if
You agree to indemnify, defend, and hold each Contributor harmless for any
liability incurred by, or claims asserted against, such Contributor by
reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included
on the same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain a
copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable
law or agreed to in writing, software distributed under the License is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.

7
aacenc/external/aacenc/README vendored Normal file
View file

@ -0,0 +1,7 @@
VisualOn AAC encoder library
This library contains an encoder implementation of the Advanced Audio
Coding (AAC) audio codec. The library is based on a codec implementation
by VisualOn as part of the Stagefright framework from the Google
Android project.

82
aacenc/external/aacenc/include/voAAC.h vendored Normal file
View file

@ -0,0 +1,82 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: voAAC.h
Content: AAC codec APIs & data types
*******************************************************************************/
#ifndef __voAAC_H__
#define __voAAC_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "voAudio.h"
/*!
* the frame type that the decoder supports
*/
typedef enum {
VOAAC_RAWDATA = 0, /*!<contains only raw aac data in a frame*/
VOAAC_ADTS = 1, /*!<contains ADTS header + raw AAC data in a frame*/
VOAAC_FT_MAX = VO_MAX_ENUM_VALUE
} VOAACFRAMETYPE;
/*!
* the structure for AAC encoder input parameter
*/
typedef struct {
int sampleRate; /*! audio file sample rate */
int bitRate; /*! encoder bit rate in bits/sec */
short nChannels; /*! number of channels on input (1,2) */
short adtsUsed; /*! whether write adts header */
} AACENC_PARAM;
/* AAC Param ID */
#define VO_PID_AAC_Mdoule 0x42211000
#define VO_PID_AAC_ENCPARAM VO_PID_AAC_Mdoule | 0x0040 /*!< get/set AAC encoder parameter, the parameter is a pointer to AACENC_PARAM */
/* AAC decoder error ID */
#define VO_ERR_AAC_Mdoule 0x82210000
#define VO_ERR_AAC_UNSFILEFORMAT (VO_ERR_AAC_Mdoule | 0xF001)
#define VO_ERR_AAC_UNSPROFILE (VO_ERR_AAC_Mdoule | 0xF002)
/**
* Get audio encoder API interface
* \param pEncHandle [out] Return the AAC Encoder handle.
* \retval VO_ERR_OK Succeeded.
*/
VO_S32 VO_API voGetAACEncAPI (VO_AUDIO_CODECAPI * pEncHandle);
VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec, VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA * pUserData );
VO_U32 VO_API voAACEncSetInputData(VO_HANDLE hCodec, VO_CODECBUFFER * pInput);
VO_U32 VO_API voAACEncGetOutputData(VO_HANDLE hCodec, VO_CODECBUFFER * pOutBuffer, VO_AUDIO_OUTPUTINFO * pOutInfo);
VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData);
VO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData);
VO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // __voAAC_H__

173
aacenc/external/aacenc/include/voAudio.h vendored Normal file
View file

@ -0,0 +1,173 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: voAudio.h
Content: Audio types and functions
*******************************************************************************/
#ifndef __voAudio_H__
#define __voAudio_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "voIndex.h"
#include "voMem.h"
#define VO_PID_AUDIO_BASE 0x42000000 /*!< The base param ID for AUDIO codec */
#define VO_PID_AUDIO_FORMAT (VO_PID_AUDIO_BASE | 0X0001) /*!< The format data of audio in track */
#define VO_PID_AUDIO_SAMPLEREATE (VO_PID_AUDIO_BASE | 0X0002) /*!< The sample rate of audio */
#define VO_PID_AUDIO_CHANNELS (VO_PID_AUDIO_BASE | 0X0003) /*!< The channel of audio */
#define VO_PID_AUDIO_BITRATE (VO_PID_AUDIO_BASE | 0X0004) /*!< The bit rate of audio */
#define VO_PID_AUDIO_CHANNELMODE (VO_PID_AUDIO_BASE | 0X0005) /*!< The channel mode of audio */
#define VO_ERR_AUDIO_BASE 0x82000000
#define VO_ERR_AUDIO_UNSCHANNEL VO_ERR_AUDIO_BASE | 0x0001
#define VO_ERR_AUDIO_UNSSAMPLERATE VO_ERR_AUDIO_BASE | 0x0002
#define VO_ERR_AUDIO_UNSFEATURE VO_ERR_AUDIO_BASE | 0x0003
/**
*Enumeration used to define the possible audio coding formats.
*/
typedef enum VO_AUDIO_CODINGTYPE {
VO_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */
VO_AUDIO_CodingPCM, /**< Any variant of PCM coding */
VO_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */
VO_AUDIO_CodingAMRNB, /**< Any variant of AMR encoded data */
VO_AUDIO_CodingAMRWB, /**< Any variant of AMR encoded data */
VO_AUDIO_CodingAMRWBP, /**< Any variant of AMR encoded data */
VO_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */
VO_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */
VO_AUDIO_CodingAAC, /**< Any variant of AAC encoded data, 0xA106 - ISO/MPEG-4 AAC, 0xFF - AAC */
VO_AUDIO_CodingAC3, /**< Any variant of AC3 encoded data */
VO_AUDIO_CodingFLAC, /**< Any variant of FLAC encoded data */
VO_AUDIO_CodingMP1, /**< Any variant of MP1 encoded data */
VO_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */
VO_AUDIO_CodingOGG, /**< Any variant of OGG encoded data */
VO_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */
VO_AUDIO_CodingRA, /**< Any variant of RA encoded data */
VO_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */
VO_AUDIO_CodingDRA, /**< Any variant of dra encoded data */
VO_AUDIO_CodingG729, /**< Any variant of dra encoded data */
VO_AUDIO_Coding_MAX = VO_MAX_ENUM_VALUE
} VO_AUDIO_CODINGTYPE;
/*!
* the channel type value
*/
typedef enum {
VO_CHANNEL_CENTER = 1, /*!<center channel*/
VO_CHANNEL_FRONT_LEFT = 1<<1, /*!<front left channel*/
VO_CHANNEL_FRONT_RIGHT = 1<<2, /*!<front right channel*/
VO_CHANNEL_SIDE_LEFT = 1<<3, /*!<side left channel*/
VO_CHANNEL_SIDE_RIGHT = 1<<4, /*!<side right channel*/
VO_CHANNEL_BACK_LEFT = 1<<5, /*!<back left channel*/
VO_CHANNEL_BACK_RIGHT = 1<<6, /*!<back right channel*/
VO_CHANNEL_BACK_CENTER = 1<<7, /*!<back center channel*/
VO_CHANNEL_LFE_BASS = 1<<8, /*!<low-frequency effects bass channel*/
VO_CHANNEL_ALL = 0xffff,/*!<[default] include all channels */
VO_CHANNEL_MAX = VO_MAX_ENUM_VALUE
} VO_AUDIO_CHANNELTYPE;
/**
* General audio format info
*/
typedef struct
{
VO_S32 SampleRate; /*!< Sample rate */
VO_S32 Channels; /*!< Channel count */
VO_S32 SampleBits; /*!< Bits per sample */
} VO_AUDIO_FORMAT;
/**
* General audio output info
*/
typedef struct
{
VO_AUDIO_FORMAT Format; /*!< Sample rate */
VO_U32 InputUsed; /*!< Channel count */
VO_U32 Resever; /*!< Resevered */
} VO_AUDIO_OUTPUTINFO;
/**
* General audio codec function set
*/
typedef struct VO_AUDIO_CODECAPI
{
/**
* Init the audio codec module and return codec handle
* \param phCodec [OUT] Return the video codec handle
* \param vType [IN] The codec type if the module support multi codec.
* \param pUserData [IN] The init param. It is either a memory operator or an allocated memory
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 (VO_API * Init) (VO_HANDLE * phCodec, VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA * pUserData );
/**
* Set input audio data.
* \param hCodec [IN]] The codec handle which was created by Init function.
* \param pInput [IN] The input buffer param.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 (VO_API * SetInputData) (VO_HANDLE hCodec, VO_CODECBUFFER * pInput);
/**
* Get the outut audio data
* \param hCodec [IN]] The codec handle which was created by Init function.
* \param pOutBuffer [OUT] The output audio data
* \param pOutInfo [OUT] The codec fills audio format and the input data size used in current call.
* pOutInfo->InputUsed is total used input data size in byte.
* \retval VO_ERR_NONE Succeeded.
* VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought. Continue to input
* data before next call.
*/
VO_U32 (VO_API * GetOutputData) (VO_HANDLE hCodec, VO_CODECBUFFER * pOutBuffer, VO_AUDIO_OUTPUTINFO * pOutInfo);
/**
* Set the parameter for the specified param ID.
* \param hCodec [IN]] The codec handle which was created by Init function.
* \param uParamID [IN] The param ID.
* \param pData [IN] The param value.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 (VO_API * SetParam) (VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData);
/**
* Get the parameter for the specified param ID.
* \param hCodec [IN]] The codec handle which was created by Init function.
* \param uParamID [IN] The param ID.
* \param pData [IN] The param value.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 (VO_API * GetParam) (VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData);
/**
* Uninit the Codec.
* \param hCodec [IN]] The codec handle which was created by Init function.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 (VO_API * Uninit) (VO_HANDLE hCodec);
} VO_AUDIO_CODECAPI;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // __voAudio_H__

193
aacenc/external/aacenc/include/voIndex.h vendored Normal file
View file

@ -0,0 +1,193 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: voIndex.h
Content: module and ID definition
*******************************************************************************/
#ifndef __voIndex_H__
#define __voIndex_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "voType.h"
/* Define the module ID */
#define _MAKE_SOURCE_ID(id, name) \
VO_INDEX_SRC_##name = _VO_INDEX_SOURCE | id,
#define _MAKE_CODEC_ID(id, name) \
VO_INDEX_DEC_##name = _VO_INDEX_DEC | id, \
VO_INDEX_ENC_##name = _VO_INDEX_ENC | id,
#define _MAKE_EFFECT_ID(id, name) \
VO_INDEX_EFT_##name = _VO_INDEX_EFFECT | id,
#define _MAKE_SINK_ID(id, name) \
VO_INDEX_SNK_##name = _VO_INDEX_SINK | id,
#define _MAKE_FILTER_ID(id, name) \
VO_INDEX_FLT_##name = _VO_INDEX_FILTER | id,
#define _MAKE_OMX_ID(id, name) \
VO_INDEX_OMX_##name = _VO_INDEX_OMX | id,
#define _MAKE_MFW_ID(id, name) \
VO_INDEX_MFW_##name = _VO_INDEX_MFW | id,
enum
{
_VO_INDEX_SOURCE = 0x01000000,
_VO_INDEX_DEC = 0x02000000,
_VO_INDEX_ENC = 0x03000000,
_VO_INDEX_EFFECT = 0x04000000,
_VO_INDEX_SINK = 0x05000000,
_VO_INDEX_FILTER = 0x06000000,
_VO_INDEX_OMX = 0x07000000,
_VO_INDEX_MFW = 0x08000000,
// define file parser modules
_MAKE_SOURCE_ID (0x010000, MP4)
_MAKE_SOURCE_ID (0x020000, AVI)
_MAKE_SOURCE_ID (0x030000, ASF)
_MAKE_SOURCE_ID (0x040000, REAL)
_MAKE_SOURCE_ID (0x050000, AUDIO)
_MAKE_SOURCE_ID (0x060000, FLASH)
_MAKE_SOURCE_ID (0x070000, OGG)
_MAKE_SOURCE_ID (0x080000, MKV)
// define network source modules
_MAKE_SOURCE_ID (0x110000, RTSP)
_MAKE_SOURCE_ID (0x120000, HTTP)
// define CMMB source modules
_MAKE_SOURCE_ID (0x200000, CMMB)
_MAKE_SOURCE_ID (0x210000, CMMB_INNO)
_MAKE_SOURCE_ID (0x220000, CMMB_TELE)
_MAKE_SOURCE_ID (0x230000, CMMB_SIANO)
// define DVBT source modules
_MAKE_SOURCE_ID (0x300000, DVBT)
_MAKE_SOURCE_ID (0x310000, DVBT_DIBCOM)
// define other source modules
_MAKE_SOURCE_ID (0x400000, ID3)
// define video codec modules
_MAKE_CODEC_ID (0x010000, H264)
_MAKE_CODEC_ID (0x020000, MPEG4)
_MAKE_CODEC_ID (0x030000, H263)
_MAKE_CODEC_ID (0x040000, S263)
_MAKE_CODEC_ID (0x050000, RV)
_MAKE_CODEC_ID (0x060000, WMV)
_MAKE_CODEC_ID (0x070000, DIVX3)
_MAKE_CODEC_ID (0x080000, MJPEG)
_MAKE_CODEC_ID (0x090000, MPEG2)
_MAKE_CODEC_ID (0x0A0000, VP6)
// define audio codec modules
_MAKE_CODEC_ID (0x210000, AAC)
_MAKE_CODEC_ID (0x220000, MP3)
_MAKE_CODEC_ID (0x230000, WMA)
_MAKE_CODEC_ID (0x240000, RA)
_MAKE_CODEC_ID (0x250000, AMRNB)
_MAKE_CODEC_ID (0x260000, AMRWB)
_MAKE_CODEC_ID (0x270000, AMRWBP)
_MAKE_CODEC_ID (0x280000, QCELP)
_MAKE_CODEC_ID (0x290000, EVRC)
_MAKE_CODEC_ID (0x2A0000, ADPCM)
_MAKE_CODEC_ID (0x2B0000, MIDI)
_MAKE_CODEC_ID (0x2C0000, AC3)
_MAKE_CODEC_ID (0x2D0000, FLAC)
_MAKE_CODEC_ID (0x2E0000, DRA)
_MAKE_CODEC_ID (0x2F0000, OGG)
_MAKE_CODEC_ID (0x300000, G729)
// define image codec modules
_MAKE_CODEC_ID (0x410000, JPEG)
_MAKE_CODEC_ID (0x420000, GIF)
_MAKE_CODEC_ID (0x430000, PNG)
_MAKE_CODEC_ID (0x440000, TIF)
// define effect modules
_MAKE_EFFECT_ID (0x010000, EQ)
// define sink modules
_MAKE_SINK_ID (0x010000, VIDEO)
_MAKE_SINK_ID (0x020000, AUDIO)
_MAKE_SINK_ID (0x030000, CCRRR)
_MAKE_SINK_ID (0x040000, CCRRV)
_MAKE_SINK_ID (0x110000, MP4)
_MAKE_SINK_ID (0x120000, AVI)
_MAKE_SINK_ID (0x130000, AFW)
// define media frame module ID
_MAKE_MFW_ID (0x010000, VOMMPLAY)
_MAKE_MFW_ID (0x020000, VOMMREC)
_MAKE_MFW_ID (0x030000, VOME)
};
/* define the error ID */
#define VO_ERR_NONE 0x00000000
#define VO_ERR_FINISH 0x00000001
#define VO_ERR_BASE 0X80000000
#define VO_ERR_FAILED 0x80000001
#define VO_ERR_OUTOF_MEMORY 0x80000002
#define VO_ERR_NOT_IMPLEMENT 0x80000003
#define VO_ERR_INVALID_ARG 0x80000004
#define VO_ERR_INPUT_BUFFER_SMALL 0x80000005
#define VO_ERR_OUTPUT_BUFFER_SMALL 0x80000006
#define VO_ERR_WRONG_STATUS 0x80000007
#define VO_ERR_WRONG_PARAM_ID 0x80000008
#define VO_ERR_LICENSE_ERROR 0x80000009
/* xxx is the module ID
#define VO_ERR_FAILED 0x8xxx0001
#define VO_ERR_OUTOF_MEMORY 0x8xxx0002
#define VO_ERR_NOT_IMPLEMENT 0x8xxx0003
#define VO_ERR_INVALID_ARG 0x8xxx0004
#define VO_ERR_INPUT_BUFFER_SMALL 0x8xxx0005
#define VO_ERR_OUTPUT_BUFFER_SMALL 0x8xxx0006
#define VO_ERR_WRONG_STATUS 0x8xxx0007
#define VO_ERR_WRONG_PARAM_ID 0x8xxx0008
#define VO_ERR_LICENSE_ERROR 0x8xxx0009
// Module own error ID
#define VO_ERR_Module 0x8xxx0X00
*/
#define VO_PID_COMMON_BASE 0x40000000 /*!< The base of common param ID */
#define VO_PID_COMMON_QUERYMEM (VO_PID_COMMON_BASE | 0X0001) /*!< Query the memory needed; Reserved. */
#define VO_PID_COMMON_INPUTTYPE (VO_PID_COMMON_BASE | 0X0002) /*!< Set or get the input buffer type. VO_INPUT_TYPE */
#define VO_PID_COMMON_HASRESOURCE (VO_PID_COMMON_BASE | 0X0003) /*!< Query it has resource to be used. VO_U32 *, 1 have, 0 No */
#define VO_PID_COMMON_HEADDATA (VO_PID_COMMON_BASE | 0X0004) /*!< Decoder track header data. VO_CODECBUFFER * */
#define VO_PID_COMMON_FLUSH (VO_PID_COMMON_BASE | 0X0005) /*!< Flush the codec buffer. VO_U32 *, 1 Flush, 0 No * */
/*
// Module Param ID
#define VO_ID_Mdoule 0x0xxx1000
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // __voIndex_H__

65
aacenc/external/aacenc/include/voMem.h vendored Normal file
View file

@ -0,0 +1,65 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: voMem.h
Content: memory functions & data structures
*******************************************************************************/
#ifndef __voMem_H__
#define __voMem_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "voIndex.h"
typedef struct
{
VO_S32 Size; /*!< Buffer stride */
VO_S32 Flag;
VO_PTR VBuffer; /*!< user data pointer */
VO_PTR PBuffer; /*!< user data pointer */
}
VO_MEM_INFO;
typedef struct VO_MEM_OPERATOR
{
VO_U32 (VO_API * Alloc) (VO_S32 uID, VO_MEM_INFO * pMemInfo);
VO_U32 (VO_API * Free) (VO_S32 uID, VO_PTR pBuff);
VO_U32 (VO_API * Set) (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize);
VO_U32 (VO_API * Copy) (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);
VO_U32 (VO_API * Check) (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize);
VO_S32 (VO_API * Compare) (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize);
VO_U32 (VO_API * Move) (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);
} VO_MEM_OPERATOR;
#define voMemAlloc(pBuff, pMemOP, ID, nSize) \
{ \
VO_MEM_INFO voMemInfo; \
voMemInfo.Size=nSize; \
pMemOP->Alloc(ID, &voMemInfo); \
pBuff=(VO_PBYTE)voMemInfo.VBuffer; \
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // __voMem_H__

197
aacenc/external/aacenc/include/voType.h vendored Normal file
View file

@ -0,0 +1,197 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: voType.h
Content: data type definition
*******************************************************************************/
#ifndef __voType_H__
#define __voType_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef _WIN32
# define VO_API __cdecl
# define VO_CBI __stdcall
#else
# define VO_API
# define VO_CBI
#endif //_WIN32
/** VO_IN is used to identify inputs to an VO function. This designation
will also be used in the case of a pointer that points to a parameter
that is used as an output. */
#ifndef VO_IN
#define VO_IN
#endif
/** VO_OUT is used to identify outputs from an VO function. This
designation will also be used in the case of a pointer that points
to a parameter that is used as an input. */
#ifndef VO_OUT
#define VO_OUT
#endif
/** VO_INOUT is used to identify parameters that may be either inputs or
outputs from an VO function at the same time. This designation will
also be used in the case of a pointer that points to a parameter that
is used both as an input and an output. */
#ifndef VO_INOUT
#define VO_INOUT
#endif
#define VO_MAX_ENUM_VALUE 0X7FFFFFFF
/** VO_VOID */
typedef void VO_VOID;
/** VO_U8 is an 8 bit unsigned quantity that is byte aligned */
typedef unsigned char VO_U8;
/** VO_BYTE is an 8 bit unsigned quantity that is byte aligned */
typedef unsigned char VO_BYTE;
/** VO_S8 is an 8 bit signed quantity that is byte aligned */
typedef signed char VO_S8;
/** VO_CHAR is an 8 bit signed quantity that is byte aligned */
typedef char VO_CHAR;
/** VO_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
typedef unsigned short VO_U16;
/** VO_S16 is a 16 bit signed quantity that is 16 bit word aligned */
typedef signed short VO_S16;
/** VO_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
typedef unsigned long VO_U32;
/** VO_S32 is a 32 bit signed quantity that is 32 bit word aligned */
typedef signed long VO_S32;
/* Users with compilers that cannot accept the "long long" designation should
define the VO_SKIP64BIT macro. It should be noted that this may cause
some components to fail to compile if the component was written to require
64 bit integral types. However, these components would NOT compile anyway
since the compiler does not support the way the component was written.
*/
#ifndef VO_SKIP64BIT
#ifdef _MSC_VER
/** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
typedef unsigned __int64 VO_U64;
/** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
typedef signed __int64 VO_S64;
#else // WIN32
/** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
typedef unsigned long long VO_U64;
/** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
typedef signed long long VO_S64;
#endif // WIN32
#endif // VO_SKIP64BIT
/** The VO_BOOL type is intended to be used to represent a true or a false
value when passing parameters to and from the VO core and components. The
VO_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.
*/
typedef enum VO_BOOL {
VO_FALSE = 0,
VO_TRUE = !VO_FALSE,
VO_BOOL_MAX = VO_MAX_ENUM_VALUE
} VO_BOOL;
/** The VO_PTR type is intended to be used to pass pointers between the VO
applications and the VO Core and components. This is a 32 bit pointer and
is aligned on a 32 bit boundary.
*/
typedef void* VO_PTR;
/** The VO_HANDLE type is intended to be used to pass pointers between the VO
applications and the VO Core and components. This is a 32 bit pointer and
is aligned on a 32 bit boundary.
*/
typedef void* VO_HANDLE;
/** The VO_STRING type is intended to be used to pass "C" type strings between
the application and the core and component. The VO_STRING type is a 32
bit pointer to a zero terminated string. The pointer is word aligned and
the string is byte aligned.
*/
typedef char* VO_PCHAR;
/** The VO_PBYTE type is intended to be used to pass arrays of bytes such as
buffers between the application and the component and core. The VO_PBYTE
type is a 32 bit pointer to a zero terminated string. The pointer is word
aligned and the string is byte aligned.
*/
typedef unsigned char* VO_PBYTE;
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
/**
* Input stream format, Frame or Stream..
*/
typedef enum {
VO_INPUT_FRAME = 1, /*!< Input contains completely frame(s) data. */
VO_INPUT_STREAM, /*!< Input is stream data. */
VO_INPUT_STREAM_MAX = VO_MAX_ENUM_VALUE
} VO_INPUT_TYPE;
/**
* General data buffer, used as input or output.
*/
typedef struct {
VO_PBYTE Buffer; /*!< Buffer pointer */
VO_U32 Length; /*!< Buffer size in byte */
VO_S64 Time; /*!< The time of the buffer */
} VO_CODECBUFFER;
/**
* The init memdata flag.
*/
typedef enum{
VO_IMF_USERMEMOPERATOR =0, /*!< memData is the pointer of memoperator function*/
VO_IMF_PREALLOCATEDBUFFER =1, /*!< memData is preallocated memory*/
VO_IMF_MAX = VO_MAX_ENUM_VALUE
}VO_INIT_MEM_FlAG;
/**
* The init memory structure..
*/
typedef struct{
VO_INIT_MEM_FlAG memflag; /*!<memory flag */
VO_PTR memData; /*!<a pointer to VO_MEM_OPERATOR or a preallocated buffer */
VO_U32 reserved1; /*!<reserved */
VO_U32 reserved2; /*!<reserved */
}VO_CODEC_INIT_USERDATA;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // __voType_H__

2363
aacenc/external/aacenc/src/aac_rom.c vendored Normal file

File diff suppressed because it is too large Load diff

117
aacenc/external/aacenc/src/aac_rom.h vendored Normal file
View file

@ -0,0 +1,117 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: aac_rom.h
Content: constant tables
*******************************************************************************/
#ifndef ROM_H
#define ROM_H
#include "config.h"
#include "psy_const.h"
#include "tns_param.h"
/*
mdct
*/
extern const int ShortWindowSine[FRAME_LEN_SHORT/2];
extern const int LongWindowKBD[FRAME_LEN_LONG/2];
extern const unsigned char bitrevTab[17 + 129];
extern const int cossintab[128 + 1024];
#if defined (ARMV5E) && !defined (ARMV7Neon)
extern const int twidTab64[(4*6 + 16*6)/2];
extern const int twidTab512[(8*6 + 32*6 + 128*6)/2];
#else
extern const int twidTab64[4*6 + 16*6];
extern const int twidTab512[8*6 + 32*6 + 128*6];
#endif
/*
form factor
*/
extern const Word32 formfac_sqrttable[96];
/*
quantizer
*/
extern const Word32 mTab_3_4[512];
extern const Word32 mTab_4_3[512];
/*! $2^{-\frac{n}{16}}$ table */
extern const Word16 pow2tominusNover16[17] ;
extern const Word32 specExpMantTableComb_enc[4][14];
extern const UWord8 specExpTableComb_enc[4][14];
extern const Word16 quantBorders[4][4];
//extern const Word16 quantRecon[3][4];
extern const Word16 quantRecon[4][3];
/*
huffman
*/
extern const UWord16 huff_ltab1_2[3][3][3][3];
extern const UWord16 huff_ltab3_4[3][3][3][3];
extern const UWord16 huff_ltab5_6[9][9];
extern const UWord16 huff_ltab7_8[8][8];
extern const UWord16 huff_ltab9_10[13][13];
extern const UWord16 huff_ltab11[17][17];
extern const UWord16 huff_ltabscf[121];
extern const UWord16 huff_ctab1[3][3][3][3];
extern const UWord16 huff_ctab2[3][3][3][3];
extern const UWord16 huff_ctab3[3][3][3][3];
extern const UWord16 huff_ctab4[3][3][3][3];
extern const UWord16 huff_ctab5[9][9];
extern const UWord16 huff_ctab6[9][9];
extern const UWord16 huff_ctab7[8][8];
extern const UWord16 huff_ctab8[8][8];
extern const UWord16 huff_ctab9[13][13];
extern const UWord16 huff_ctab10[13][13];
extern const UWord16 huff_ctab11[17][17];
extern const UWord32 huff_ctabscf[121];
/*
misc
*/
extern const int sampRateTab[NUM_SAMPLE_RATES];
extern const int BandwithCoefTab[8][NUM_SAMPLE_RATES];
extern const int rates[8];
extern const UWord8 sfBandTotalShort[NUM_SAMPLE_RATES];
extern const UWord8 sfBandTotalLong[NUM_SAMPLE_RATES];
extern const int sfBandTabShortOffset[NUM_SAMPLE_RATES];
extern const short sfBandTabShort[76];
extern const int sfBandTabLongOffset[NUM_SAMPLE_RATES];
extern const short sfBandTabLong[325];
extern const Word32 m_log2_table[INT_BITS];
/*
TNS
*/
extern const Word32 tnsCoeff3[8];
extern const Word32 tnsCoeff3Borders[8];
extern const Word32 tnsCoeff4[16];
extern const Word32 tnsCoeff4Borders[16];
extern const Word32 invSBF[24];
extern const Word16 sideInfoTabLong[MAX_SFB_LONG + 1];
extern const Word16 sideInfoTabShort[MAX_SFB_SHORT + 1];
#endif

505
aacenc/external/aacenc/src/aacenc.c vendored Normal file
View file

@ -0,0 +1,505 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: aacenc.c
Content: aac encoder interface functions
*******************************************************************************/
#include "voAAC.h"
#include "typedef.h"
#include "aacenc_core.h"
#include "aac_rom.h"
#include "cmnMemory.h"
#include "memalign.h"
#define UNUSED(x) (void)(x)
/**
* Init the audio codec module and return codec handle
* \param phCodec [OUT] Return the video codec handle
* \param vType [IN] The codec type if the module support multi codec.
* \param pUserData [IN] The init param. It is memory operator or alloced memory
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA *pUserData)
{
AAC_ENCODER*hAacEnc;
int error;
#ifdef USE_DEFAULT_MEM
VO_MEM_OPERATOR voMemoprator;
#endif
VO_MEM_OPERATOR *pMemOP;
#ifdef USE_DEFAULT_MEM
int interMem;
interMem = 0;
#endif
UNUSED(vType);
error = 0;
/* init the memory operator */
if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
{
#ifdef USE_DEFAULT_MEM
voMemoprator.Alloc = cmnMemAlloc;
voMemoprator.Copy = cmnMemCopy;
voMemoprator.Free = cmnMemFree;
voMemoprator.Set = cmnMemSet;
voMemoprator.Check = cmnMemCheck;
interMem = 1;
pMemOP = &voMemoprator;
#else
*phCodec = NULL;
return VO_ERR_INVALID_ARG;
#endif
}
else
{
pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
}
/* init the aac encoder handle */
hAacEnc = (AAC_ENCODER*)mem_malloc(pMemOP, sizeof(AAC_ENCODER), 32, VO_INDEX_ENC_AAC);
if(NULL == hAacEnc)
{
error = 1;
}
if(!error)
{
/* init the aac encoder intra memory */
hAacEnc->intbuf = (short *)mem_malloc(pMemOP, AACENC_BLOCKSIZE*MAX_CHANNELS*sizeof(short), 32, VO_INDEX_ENC_AAC);
if(NULL == hAacEnc->intbuf)
{
error = 1;
}
}
if (!error) {
/* init the aac encoder psychoacoustic */
error = (PsyNew(&hAacEnc->psyKernel, MAX_CHANNELS, pMemOP) ||
PsyOutNew(&hAacEnc->psyOut, pMemOP));
}
if (!error) {
/* init the aac encoder quantization elements */
error = QCOutNew(&hAacEnc->qcOut,MAX_CHANNELS, pMemOP);
}
if (!error) {
/* init the aac encoder quantization state */
error = QCNew(&hAacEnc->qcKernel, pMemOP);
}
/* uninit the aac encoder if error is nozero */
if(error)
{
AacEncClose(hAacEnc, pMemOP);
if(hAacEnc)
{
mem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC);
hAacEnc = NULL;
}
*phCodec = NULL;
return VO_ERR_OUTOF_MEMORY;
}
/* init the aac encoder memory operator */
#ifdef USE_DEFAULT_MEM
if(interMem)
{
hAacEnc->voMemoprator.Alloc = cmnMemAlloc;
hAacEnc->voMemoprator.Copy = cmnMemCopy;
hAacEnc->voMemoprator.Free = cmnMemFree;
hAacEnc->voMemoprator.Set = cmnMemSet;
hAacEnc->voMemoprator.Check = cmnMemCheck;
pMemOP = &hAacEnc->voMemoprator;
}
#endif
/* init the aac encoder default parameter */
if(hAacEnc->initOK == 0)
{
AACENC_CONFIG config;
config.adtsUsed = 1;
config.bitRate = 128000;
config.nChannelsIn = 2;
config.nChannelsOut = 2;
config.sampleRate = 44100;
config.bandWidth = 20000;
AacEncOpen(hAacEnc, config);
}
hAacEnc->voMemop = pMemOP;
*phCodec = hAacEnc;
return VO_ERR_NONE;
}
/**
* Set input audio data.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param pInput [IN] The input buffer param.
* \param pOutBuffer [OUT] The output buffer info.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncSetInputData(VO_HANDLE hCodec, VO_CODECBUFFER * pInput)
{
AAC_ENCODER *hAacEnc;
int length;
if(NULL == hCodec || NULL == pInput || NULL == pInput->Buffer)
{
return VO_ERR_INVALID_ARG;
}
hAacEnc = (AAC_ENCODER *)hCodec;
/* init input pcm buffer and length*/
hAacEnc->inbuf = (short *)pInput->Buffer;
hAacEnc->inlen = pInput->Length / sizeof(short);
hAacEnc->uselength = 0;
hAacEnc->encbuf = hAacEnc->inbuf;
hAacEnc->enclen = hAacEnc->inlen;
/* rebuild intra pcm buffer and length*/
if(hAacEnc->intlen)
{
length = min(hAacEnc->config.nChannelsIn*AACENC_BLOCKSIZE - hAacEnc->intlen, hAacEnc->inlen);
hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen,
hAacEnc->inbuf, length*sizeof(short));
hAacEnc->encbuf = hAacEnc->intbuf;
hAacEnc->enclen = hAacEnc->intlen + length;
hAacEnc->inbuf += length;
hAacEnc->inlen -= length;
}
return VO_ERR_NONE;
}
/**
* Get the outut audio data
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param pOutBuffer [OUT] The output audio data
* \param pOutInfo [OUT] The dec module filled audio format and used the input size.
* pOutInfo->InputUsed is total used the input size.
* \retval VO_ERR_NONE Succeeded.
* VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought.
*/
VO_U32 VO_API voAACEncGetOutputData(VO_HANDLE hCodec, VO_CODECBUFFER * pOutput, VO_AUDIO_OUTPUTINFO * pOutInfo)
{
AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
Word16 numAncDataBytes=0;
Word32 inbuflen;
int length;
if(NULL == hAacEnc)
return VO_ERR_INVALID_ARG;
inbuflen = AACENC_BLOCKSIZE*hAacEnc->config.nChannelsIn;
/* check the input pcm buffer and length*/
if(NULL == hAacEnc->encbuf || hAacEnc->enclen < inbuflen)
{
length = hAacEnc->enclen;
if(hAacEnc->intlen == 0)
{
hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf,
hAacEnc->encbuf, length*sizeof(short));
hAacEnc->uselength += length*sizeof(short);
}
else
{
hAacEnc->uselength += (length - hAacEnc->intlen)*sizeof(short);
}
hAacEnc->intlen = length;
pOutput->Length = 0;
if(pOutInfo)
pOutInfo->InputUsed = hAacEnc->uselength;
return VO_ERR_INPUT_BUFFER_SMALL;
}
/* check the output aac buffer and length*/
if(NULL == pOutput || NULL == pOutput->Buffer || pOutput->Length < (6144/8)*hAacEnc->config.nChannelsOut/(sizeof(Word32)))
return VO_ERR_OUTPUT_BUFFER_SMALL;
/* aac encoder core function */
AacEncEncode( hAacEnc,
(Word16*)hAacEnc->encbuf,
NULL,
&numAncDataBytes,
pOutput->Buffer,
&pOutput->Length);
/* update the input pcm buffer and length*/
if(hAacEnc->intlen)
{
length = inbuflen - hAacEnc->intlen;
hAacEnc->encbuf = hAacEnc->inbuf;
hAacEnc->enclen = hAacEnc->inlen;
hAacEnc->uselength += length*sizeof(short);
hAacEnc->intlen = 0;
}
else
{
hAacEnc->encbuf = hAacEnc->encbuf + inbuflen;
hAacEnc->enclen = hAacEnc->enclen - inbuflen;
hAacEnc->uselength += inbuflen*sizeof(short);
}
/* update the output aac information */
if(pOutInfo)
{
pOutInfo->Format.Channels = hAacEnc->config.nChannelsOut;
pOutInfo->Format.SampleRate = hAacEnc->config.sampleRate;
pOutInfo->Format.SampleBits = 16;
pOutInfo->InputUsed = hAacEnc->uselength;
}
return VO_ERR_NONE;
}
/**
* Uninit the Codec.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec)
{
AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
if(NULL != hAacEnc)
{
/* close the aac encoder */
AacEncClose(hAacEnc, hAacEnc->voMemop);
/* free the aac encoder handle*/
mem_free(hAacEnc->voMemop, hAacEnc, VO_INDEX_ENC_AAC);
hAacEnc = NULL;
}
return VO_ERR_NONE;
}
/**
* Set the param for special target.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param uParamID [IN] The param ID.
* \param pData [IN] The param value depend on the ID>
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
{
AACENC_CONFIG config;
AACENC_PARAM* pAAC_param;
VO_AUDIO_FORMAT *pWAV_Format;
AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
int ret, i, bitrate, tmp;
int SampleRateIdx;
if(NULL == hAacEnc)
return VO_ERR_INVALID_ARG;
switch(uParamID)
{
case VO_PID_AAC_ENCPARAM: /* init aac encoder parameter*/
AacInitDefaultConfig(&config);
if(pData == NULL)
return VO_ERR_INVALID_ARG;
pAAC_param = (AACENC_PARAM*)pData;
config.adtsUsed = pAAC_param->adtsUsed;
config.bitRate = pAAC_param->bitRate;
config.nChannelsIn = pAAC_param->nChannels;
config.nChannelsOut = pAAC_param->nChannels;
config.sampleRate = pAAC_param->sampleRate;
/* check the channel */
if(config.nChannelsIn< 1 || config.nChannelsIn > MAX_CHANNELS ||
config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
return VO_ERR_AUDIO_UNSCHANNEL;
/* check the samplerate */
ret = -1;
for(i = 0; i < NUM_SAMPLE_RATES; i++)
{
if(config.sampleRate == sampRateTab[i])
{
ret = 0;
break;
}
}
if(ret < 0)
return VO_ERR_AUDIO_UNSSAMPLERATE;
SampleRateIdx = i;
tmp = 441;
if(config.sampleRate%8000 == 0)
tmp =480;
/* check the bitrate */
if(config.bitRate!=0 && ((config.bitRate/config.nChannelsOut < 4000) ||
(config.bitRate/config.nChannelsOut > 160000) ||
(config.bitRate > config.sampleRate*6*config.nChannelsOut)))
{
config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
if(config.bitRate/config.nChannelsOut < 4000)
config.bitRate = 4000 * config.nChannelsOut;
else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
config.bitRate = config.sampleRate*6*config.nChannelsOut;
else if(config.bitRate/config.nChannelsOut > 160000)
config.bitRate = config.nChannelsOut*160000;
}
/* check the bandwidth */
bitrate = config.bitRate / config.nChannelsOut;
bitrate = bitrate * tmp / config.sampleRate;
for (i = 0; rates[i]; i++)
{
if (rates[i] >= bitrate)
break;
}
config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
/* init aac encoder core */
ret = AacEncOpen(hAacEnc, config);
if(ret)
return VO_ERR_AUDIO_UNSFEATURE;
break;
case VO_PID_AUDIO_FORMAT: /* init pcm channel and samplerate*/
AacInitDefaultConfig(&config);
if(pData == NULL)
return VO_ERR_INVALID_ARG;
pWAV_Format = (VO_AUDIO_FORMAT*)pData;
config.adtsUsed = 1;
config.nChannelsIn = pWAV_Format->Channels;
config.nChannelsOut = pWAV_Format->Channels;
config.sampleRate = pWAV_Format->SampleRate;
/* check the channel */
if(config.nChannelsIn< 1 || config.nChannelsIn > MAX_CHANNELS ||
config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
return VO_ERR_AUDIO_UNSCHANNEL;
/* check the samplebits */
if(pWAV_Format->SampleBits != 16)
{
return VO_ERR_AUDIO_UNSFEATURE;
}
/* check the samplerate */
ret = -1;
for(i = 0; i < NUM_SAMPLE_RATES; i++)
{
if(config.sampleRate == sampRateTab[i])
{
ret = 0;
break;
}
}
if(ret < 0)
return VO_ERR_AUDIO_UNSSAMPLERATE;
SampleRateIdx = i;
/* update the bitrates */
tmp = 441;
if(config.sampleRate%8000 == 0)
tmp =480;
config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
if(config.bitRate/config.nChannelsOut < 4000)
config.bitRate = 4000 * config.nChannelsOut;
else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
config.bitRate = config.sampleRate*6*config.nChannelsOut;
else if(config.bitRate/config.nChannelsOut > 160000)
config.bitRate = config.nChannelsOut*160000;
/* check the bandwidth */
bitrate = config.bitRate / config.nChannelsOut;
bitrate = bitrate * tmp / config.sampleRate;
for (i = 0; rates[i]; i++)
{
if (rates[i] >= bitrate)
break;
}
config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
/* init aac encoder core */
ret = AacEncOpen(hAacEnc, config);
if(ret)
return VO_ERR_AUDIO_UNSFEATURE;
break;
default:
return VO_ERR_WRONG_PARAM_ID;
}
return VO_ERR_NONE;
}
/**
* Get the param for special target.
* \param hCodec [IN]] The Codec Handle which was created by Init function.
* \param uParamID [IN] The param ID.
* \param pData [IN] The param value depend on the ID>
* \retval VO_ERR_NONE Succeeded.
*/
VO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
{
UNUSED(hCodec);
UNUSED(uParamID);
UNUSED(pData);
return VO_ERR_NONE;
}
/**
* Get audio codec API interface
* \param pEncHandle [out] Return the AAC Encoder handle.
* \retval VO_ERR_OK Succeeded.
*/
VO_S32 VO_API voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)
{
if(pDecHandle == NULL)
return VO_ERR_INVALID_ARG;
pDecHandle->Init = voAACEncInit;
pDecHandle->SetInputData = voAACEncSetInputData;
pDecHandle->GetOutputData = voAACEncGetOutputData;
pDecHandle->SetParam = voAACEncSetParam;
pDecHandle->GetParam = voAACEncGetParam;
pDecHandle->Uninit = voAACEncUninit;
return VO_ERR_NONE;
}

238
aacenc/external/aacenc/src/aacenc_core.c vendored Normal file
View file

@ -0,0 +1,238 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: aacenc_core.c
Content: aac encoder core functions
*******************************************************************************/
#include "typedef.h"
#include "aacenc_core.h"
#include "bitenc.h"
#include "psy_configuration.h"
#include "psy_main.h"
#include "qc_main.h"
#include "psy_main.h"
#include "channel_map.h"
#include "aac_rom.h"
/********************************************************************************
*
* function name: AacInitDefaultConfig
* description: gives reasonable default configuration
*
**********************************************************************************/
void AacInitDefaultConfig(AACENC_CONFIG *config)
{
/* default configurations */
config->adtsUsed = 1;
config->nChannelsIn = 2;
config->nChannelsOut = 2;
config->bitRate = 128000;
config->bandWidth = 0;
}
/********************************************************************************
*
* function name: AacEncOpen
* description: allocate and initialize a new encoder instance
* returns: 0 if success
*
**********************************************************************************/
Word16 AacEncOpen( AAC_ENCODER* hAacEnc, /* pointer to an encoder handle, initialized on return */
const AACENC_CONFIG config /* pre-initialized config struct */
)
{
Word32 error = 0;
Word16 profile = 1;
ELEMENT_INFO *elInfo = NULL;
if (hAacEnc==0) {
error=1;
}
if (!error) {
hAacEnc->config = config;
}
if (!error) {
error = InitElementInfo (config.nChannelsOut,
&hAacEnc->elInfo);
}
if (!error) {
elInfo = &hAacEnc->elInfo;
}
if (!error) {
/* use or not tns tool for long and short block */
Word16 tnsMask=3;
/* init encoder psychoacoustic */
error = psyMainInit(&hAacEnc->psyKernel,
config.sampleRate,
config.bitRate,
elInfo->nChannelsInEl,
tnsMask,
hAacEnc->config.bandWidth);
}
/* use or not adts header */
if(!error) {
hAacEnc->qcOut.qcElement.adtsUsed = config.adtsUsed;
}
/* init encoder quantization */
if (!error) {
struct QC_INIT qcInit;
/*qcInit.channelMapping = &hAacEnc->channelMapping;*/
qcInit.elInfo = &hAacEnc->elInfo;
qcInit.maxBits = (Word16) (MAXBITS_COEF*elInfo->nChannelsInEl);
qcInit.bitRes = qcInit.maxBits;
qcInit.averageBits = (Word16) ((config.bitRate * FRAME_LEN_LONG) / config.sampleRate);
qcInit.padding.paddingRest = config.sampleRate;
qcInit.meanPe = (Word16) ((10 * FRAME_LEN_LONG * hAacEnc->config.bandWidth) /
(config.sampleRate>>1));
qcInit.maxBitFac = (Word16) ((100 * (MAXBITS_COEF-MINBITS_COEF)* elInfo->nChannelsInEl)/
(qcInit.averageBits?qcInit.averageBits:1));
qcInit.bitrate = config.bitRate;
error = QCInit(&hAacEnc->qcKernel, &qcInit);
}
/* init bitstream encoder */
if (!error) {
hAacEnc->bseInit.nChannels = elInfo->nChannelsInEl;
hAacEnc->bseInit.bitrate = config.bitRate;
hAacEnc->bseInit.sampleRate = config.sampleRate;
hAacEnc->bseInit.profile = profile;
}
return error;
}
/********************************************************************************
*
* function name: AacEncEncode
* description: encode pcm to aac data core function
* returns: 0 if success
*
**********************************************************************************/
Word16 AacEncEncode(AAC_ENCODER *aacEnc, /*!< an encoder handle */
Word16 *timeSignal, /*!< BLOCKSIZE*nChannels audio samples, interleaved */
const UWord8 *ancBytes, /*!< pointer to ancillary data bytes */
Word16 *numAncBytes, /*!< number of ancillary Data Bytes */
UWord8 *outBytes, /*!< pointer to output buffer (must be large MINBITS_COEF/8*MAX_CHANNELS bytes) */
VO_U32 *numOutBytes /*!< number of bytes in output buffer after processing */
)
{
ELEMENT_INFO *elInfo = &aacEnc->elInfo;
Word16 globUsedBits;
Word16 ancDataBytes, ancDataBytesLeft;
ancDataBytes = ancDataBytesLeft = *numAncBytes;
/* init output aac data buffer and length */
aacEnc->hBitStream = CreateBitBuffer(&aacEnc->bitStream, outBytes, *numOutBytes);
/* psychoacoustic process */
psyMain(aacEnc->config.nChannelsOut,
elInfo,
timeSignal,
&aacEnc->psyKernel.psyData[elInfo->ChannelIndex[0]],
&aacEnc->psyKernel.tnsData[elInfo->ChannelIndex[0]],
&aacEnc->psyKernel.psyConfLong,
&aacEnc->psyKernel.psyConfShort,
&aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
&aacEnc->psyOut.psyOutElement,
aacEnc->psyKernel.pScratchTns,
aacEnc->config.sampleRate);
/* adjust bitrate and frame length */
AdjustBitrate(&aacEnc->qcKernel,
aacEnc->config.bitRate,
aacEnc->config.sampleRate);
/* quantization and coding process */
QCMain(&aacEnc->qcKernel,
&aacEnc->qcKernel.elementBits,
&aacEnc->qcKernel.adjThr.adjThrStateElem,
&aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
&aacEnc->psyOut.psyOutElement,
&aacEnc->qcOut.qcChannel[elInfo->ChannelIndex[0]],
&aacEnc->qcOut.qcElement,
elInfo->nChannelsInEl,
min(ancDataBytesLeft,ancDataBytes));
ancDataBytesLeft = ancDataBytesLeft - ancDataBytes;
globUsedBits = FinalizeBitConsumption(&aacEnc->qcKernel,
&aacEnc->qcOut);
/* write bitstream process */
WriteBitstream(aacEnc->hBitStream,
*elInfo,
&aacEnc->qcOut,
&aacEnc->psyOut,
&globUsedBits,
ancBytes,
aacEnc->psyKernel.sampleRateIdx);
updateBitres(&aacEnc->qcKernel,
&aacEnc->qcOut);
/* write out the bitstream */
*numOutBytes = GetBitsAvail(aacEnc->hBitStream) >> 3;
return 0;
}
/********************************************************************************
*
* function name:AacEncClose
* description: deallocate an encoder instance
*
**********************************************************************************/
void AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP)
{
if (hAacEnc) {
QCDelete(&hAacEnc->qcKernel, pMemOP);
QCOutDelete(&hAacEnc->qcOut, pMemOP);
PsyDelete(&hAacEnc->psyKernel, pMemOP);
PsyOutDelete(&hAacEnc->psyOut, pMemOP);
DeleteBitBuffer(&hAacEnc->hBitStream);
if(hAacEnc->intbuf)
{
mem_free(pMemOP, hAacEnc->intbuf, VO_INDEX_ENC_AAC);
hAacEnc->intbuf = NULL;
}
}
}

117
aacenc/external/aacenc/src/aacenc_core.h vendored Normal file
View file

@ -0,0 +1,117 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: aacenc_core.h
Content: aac encoder interface functions
*******************************************************************************/
#ifndef _aacenc_core_h_
#define _aacenc_core_h_
#include "typedef.h"
#include "config.h"
#include "bitenc.h"
#include "psy_configuration.h"
#include "psy_main.h"
#include "qc_main.h"
#include "psy_main.h"
/*-------------------------- defines --------------------------------------*/
/*-------------------- structure definitions ------------------------------*/
typedef struct {
Word32 sampleRate; /* audio file sample rate */
Word32 bitRate; /* encoder bit rate in bits/sec */
Word16 nChannelsIn; /* number of channels on input (1,2) */
Word16 nChannelsOut; /* number of channels on output (1,2) */
Word16 bandWidth; /* targeted audio bandwidth in Hz */
Word16 adtsUsed; /* whether write adts header */
} AACENC_CONFIG;
typedef struct {
AACENC_CONFIG config; /* Word16 size: 8 */
ELEMENT_INFO elInfo; /* Word16 size: 4 */
QC_STATE qcKernel; /* Word16 size: 6 + 5(PADDING) + 7(ELEMENT_BITS) + 54(ADJ_THR_STATE) = 72 */
QC_OUT qcOut; /* Word16 size: MAX_CHANNELS*920(QC_OUT_CHANNEL) + 5(QC_OUT_ELEMENT) + 7 = 932 / 1852 */
PSY_OUT psyOut; /* Word16 size: MAX_CHANNELS*186 + 2 = 188 / 374 */
PSY_KERNEL psyKernel; /* Word16 size: 2587 / 4491 */
struct BITSTREAMENCODER_INIT bseInit; /* Word16 size: 6 */
struct BIT_BUF bitStream; /* Word16 size: 8 */
HANDLE_BIT_BUF hBitStream;
int initOK;
short *intbuf;
short *encbuf;
short *inbuf;
int enclen;
int inlen;
int intlen;
int uselength;
void *hCheck;
VO_MEM_OPERATOR *voMemop;
VO_MEM_OPERATOR voMemoprator;
}AAC_ENCODER; /* Word16 size: 3809 / 6851 */
/*-----------------------------------------------------------------------------
functionname: AacInitDefaultConfig
description: gives reasonable default configuration
returns: ---
------------------------------------------------------------------------------*/
void AacInitDefaultConfig(AACENC_CONFIG *config);
/*---------------------------------------------------------------------------
functionname:AacEncOpen
description: allocate and initialize a new encoder instance
returns: AACENC_OK if success
---------------------------------------------------------------------------*/
Word16 AacEncOpen (AAC_ENCODER *hAacEnc, /* pointer to an encoder handle, initialized on return */
const AACENC_CONFIG config); /* pre-initialized config struct */
Word16 AacEncEncode(AAC_ENCODER *hAacEnc,
Word16 *timeSignal,
const UWord8 *ancBytes, /*!< pointer to ancillary data bytes */
Word16 *numAncBytes, /*!< number of ancillary Data Bytes, send as fill element */
UWord8 *outBytes, /*!< pointer to output buffer */
VO_U32 *numOutBytes /*!< number of bytes in output buffer */
);
/*---------------------------------------------------------------------------
functionname:AacEncClose
description: deallocate an encoder instance
---------------------------------------------------------------------------*/
void AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP); /* an encoder handle */
#endif /* _aacenc_h_ */

1230
aacenc/external/aacenc/src/adj_thr.c vendored Normal file
View file

@ -0,0 +1,1230 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: adj_thr.c
Content: Threshold compensation functions
*******************************************************************************/
/* Include system headers before local headers - the local headers
* redefine __inline, which can mess up definitions in libc headers if
* they happen to use __inline. */
#include <string.h>
#include "basic_op.h"
#include "oper_32b.h"
#include "adj_thr_data.h"
#include "adj_thr.h"
#include "qc_data.h"
#include "line_pe.h"
#define minSnrLimit 0x6666 /* 1 dB */
#define PEBITS_COEF 0x170a /* 0.18*(1 << 15)*/
#define HOLE_THR_LONG 0x2873 /* 0.316*(1 << 15) */
#define HOLE_THR_SHORT 0x4000 /* 0.5 *(1 << 15) */
#define MS_THRSPREAD_COEF 0x7333 /* 0.9 * (1 << 15) */
#define MIN_SNR_COEF 0x651f /* 3.16* (1 << (15 - 2)) */
/* values for avoid hole flag */
enum _avoid_hole_state {
NO_AH =0,
AH_INACTIVE =1,
AH_ACTIVE =2
};
/********************************************************************************
*
* function name:bits2pe
* description: convert from bits to pe
* pe = 1.18*desiredBits
*
**********************************************************************************/
Word16 bits2pe(const Word16 bits) {
return (bits + ((PEBITS_COEF * bits) >> 15));
}
/********************************************************************************
*
* function name:calcThreshExp
* description: loudness calculation (threshold to the power of redExp)
* thr(n)^0.25
*
**********************************************************************************/
static void calcThreshExp(Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
const Word16 nChannels)
{
Word16 ch, sfb, sfbGrp;
Word32 *pthrExp = NULL, *psfbThre;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)
pthrExp = &(thrExp[ch][sfbGrp]);
psfbThre = psyOutChan->sfbThreshold + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
*pthrExp = rsqrt(rsqrt(*psfbThre,INT_BITS),INT_BITS);
pthrExp++; psfbThre++;
}
}
}
/********************************************************************************
*
* function name:adaptMinSnr
* description: reduce minSnr requirements for bands with relative low energies
*
**********************************************************************************/
static void adaptMinSnr(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
MINSNR_ADAPT_PARAM *msaParam,
const Word16 nChannels)
{
Word16 ch, sfb, sfbOffs;
Word32 nSfb, avgEn;
Word16 log_avgEn = 0;
Word32 startRatio_x_avgEn = 0;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL* psyOutChan = &psyOutChannel[ch];
/* calc average energy per scalefactor band */
avgEn = 0;
nSfb = 0;
for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfbOffs+sfb]);
nSfb = nSfb + 1;
}
}
if (nSfb > 0) {
avgEn = avgEn / nSfb;
log_avgEn = iLog4(avgEn);
startRatio_x_avgEn = fixmul(msaParam->startRatio, avgEn);
}
/* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */
for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
if (psyOutChan->sfbEnergy[sfbOffs+sfb] < startRatio_x_avgEn) {
Word16 dbRatio, minSnrRed;
Word32 snrRed;
Word16 newMinSnr;
dbRatio = log_avgEn - logSfbEnergy[ch][sfbOffs+sfb];
dbRatio = dbRatio + (dbRatio << 1);
minSnrRed = 110 - ((dbRatio + (dbRatio << 1)) >> 2);
minSnrRed = max(minSnrRed, 20); /* 110: (0.375(redOffs)+1)*80,
3: 0.00375(redRatioFac)*80
20: 0.25(maxRed) * 80 */
snrRed = minSnrRed * iLog4((psyOutChan->sfbMinSnr[sfbOffs+sfb] << 16));
/*
snrRedI si now scaled by 80 (minSnrRed) and 4 (ffr_iLog4)
*/
newMinSnr = round16(pow2_xy(snrRed,80*4));
psyOutChan->sfbMinSnr[sfbOffs+sfb] = min(newMinSnr, minSnrLimit);
}
}
}
}
}
/********************************************************************************
*
* function name:initAvoidHoleFlag
* description: determine bands where avoid hole is not necessary resp. possible
*
**********************************************************************************/
static void initAvoidHoleFlag(Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT* psyOutElement,
const Word16 nChannels,
AH_PARAM *ahParam)
{
Word16 ch, sfb, sfbGrp, shift;
Word32 threshold;
Word32* psfbSpreadEn;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
if (psyOutChan->windowSequence != SHORT_WINDOW) {
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
psfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
*psfbSpreadEn = *psfbSpreadEn >> 1; /* 0.5 */
++psfbSpreadEn;
}
}
}
else {
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
psfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
*psfbSpreadEn = (*psfbSpreadEn >> 1) + (*psfbSpreadEn >> 3); /* 0.63 */
++psfbSpreadEn;
}
}
}
}
/* increase minSnr for local peaks, decrease it for valleys */
if (ahParam->modifyMinSnr) {
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
if (psyOutChan->windowSequence != SHORT_WINDOW)
threshold = HOLE_THR_LONG;
else
threshold = HOLE_THR_SHORT;
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
Word16 *psfbMinSnr = psyOutChan->sfbMinSnr + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
Word32 sfbEn, sfbEnm1, sfbEnp1, avgEn;
if (sfb > 0)
sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp+sfb-1];
else
sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp];
if (sfb < (psyOutChan->maxSfbPerGroup-1))
sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb+1];
else
sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb];
avgEn = (sfbEnm1 + sfbEnp1) >> 1;
sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];
if (sfbEn > avgEn && avgEn > 0) {
Word32 tmpMinSnr;
shift = norm_l(sfbEn);
tmpMinSnr = Div_32(L_mpy_ls(avgEn, minSnrLimit) << shift, sfbEn << shift );
tmpMinSnr = max(tmpMinSnr, HOLE_THR_LONG);
tmpMinSnr = max(tmpMinSnr, threshold);
*psfbMinSnr = min(*psfbMinSnr, tmpMinSnr);
}
/* valley ? */
if ((sfbEn < (avgEn >> 1)) && (sfbEn > 0)) {
Word32 tmpMinSnr;
Word32 minSnrEn = L_mpy_wx(avgEn, *psfbMinSnr);
if(minSnrEn < sfbEn) {
shift = norm_l(sfbEn);
tmpMinSnr = Div_32( minSnrEn << shift, sfbEn<<shift);
}
else {
tmpMinSnr = MAX_16;
}
tmpMinSnr = min(minSnrLimit, tmpMinSnr);
*psfbMinSnr =
(min((tmpMinSnr >> 2), mult(*psfbMinSnr, MIN_SNR_COEF)) << 2);
}
psfbMinSnr++;
}
}
}
}
/* stereo: adapt the minimum requirements sfbMinSnr of mid and
side channels */
if (nChannels == 2) {
PSY_OUT_CHANNEL *psyOutChanM = &psyOutChannel[0];
PSY_OUT_CHANNEL *psyOutChanS = &psyOutChannel[1];
for (sfb=0; sfb<psyOutChanM->sfbCnt; sfb++) {
if (psyOutElement->toolsInfo.msMask[sfb]) {
Word32 sfbEnM = psyOutChanM->sfbEnergy[sfb];
Word32 sfbEnS = psyOutChanS->sfbEnergy[sfb];
Word32 maxSfbEn = max(sfbEnM, sfbEnS);
Word32 maxThr = L_mpy_wx(maxSfbEn, psyOutChanM->sfbMinSnr[sfb]) >> 1;
if(maxThr >= sfbEnM) {
psyOutChanM->sfbMinSnr[sfb] = MAX_16;
}
else {
shift = norm_l(sfbEnM);
psyOutChanM->sfbMinSnr[sfb] = min(max(psyOutChanM->sfbMinSnr[sfb],
round16(Div_32(maxThr<<shift, sfbEnM << shift))), minSnrLimit);
}
if(maxThr >= sfbEnS) {
psyOutChanS->sfbMinSnr[sfb] = MAX_16;
}
else {
shift = norm_l(sfbEnS);
psyOutChanS->sfbMinSnr[sfb] = min(max(psyOutChanS->sfbMinSnr[sfb],
round16(Div_32(maxThr << shift, sfbEnS << shift))), minSnrLimit);
}
if (sfbEnM > psyOutChanM->sfbSpreadedEnergy[sfb])
psyOutChanS->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnS, MS_THRSPREAD_COEF);
if (sfbEnS > psyOutChanS->sfbSpreadedEnergy[sfb])
psyOutChanM->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnM, MS_THRSPREAD_COEF);
}
}
}
/* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
Word16 *pahFlag = ahFlag[ch] + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
if ((psyOutChan->sfbSpreadedEnergy[sfbGrp+sfb] > psyOutChan->sfbEnergy[sfbGrp+sfb]) ||
(psyOutChan->sfbEnergy[sfbGrp+sfb] <= psyOutChan->sfbThreshold[sfbGrp+sfb]) ||
(psyOutChan->sfbMinSnr[sfbGrp+sfb] == MAX_16)) {
*pahFlag++ = NO_AH;
}
else {
*pahFlag++ = AH_INACTIVE;
}
}
for (sfb=psyOutChan->maxSfbPerGroup; sfb<psyOutChan->sfbPerGroup; sfb++) {
*pahFlag++ = NO_AH;
}
}
}
}
/********************************************************************************
*
* function name:calcPeNoAH
* description: sum the pe data only for bands where avoid hole is inactive
*
**********************************************************************************/
static void calcPeNoAH(Word16 *pe,
Word16 *constPart,
Word16 *nActiveLines,
PE_DATA *peData,
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
const Word16 nChannels)
{
Word16 ch, sfb, sfbGrp;
int ipe, iconstPart, inActiveLines;
ipe = 0;
iconstPart = 0;
inActiveLines = 0;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
if (ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) {
ipe = ipe + peChanData->sfbPe[sfbGrp+sfb];
iconstPart = iconstPart + peChanData->sfbConstPart[sfbGrp+sfb];
inActiveLines = inActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
}
}
}
}
*pe = saturate(ipe);
*constPart = saturate(iconstPart);
*nActiveLines = saturate(inActiveLines);
}
/********************************************************************************
*
* function name:reduceThresholds
* description: apply reduction formula
*
**********************************************************************************/
static void reduceThresholds(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels,
const Word32 redVal)
{
Word32 sfbThrReduced;
Word32 *psfbEn, *psfbThr;
Word16 ch, sfb, sfbGrp;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
psfbEn = psyOutChan->sfbEnergy + sfbGrp;
psfbThr = psyOutChan->sfbThreshold + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
if (*psfbEn > *psfbThr) {
/* threshold reduction formula */
Word32 tmp = thrExp[ch][sfbGrp+sfb] + redVal;
tmp = fixmul(tmp, tmp);
sfbThrReduced = fixmul(tmp, tmp);
/* avoid holes */
tmp = L_mpy_ls(*psfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);
if ((sfbThrReduced > tmp) &&
(ahFlag[ch][sfbGrp+sfb] != NO_AH)){
sfbThrReduced = max(tmp, *psfbThr);
ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE;
}
*psfbThr = sfbThrReduced;
}
psfbEn++; psfbThr++;
}
}
}
}
/********************************************************************************
*
* function name:correctThresh
* description: if pe difference deltaPe between desired pe and real pe is small enough,
* the difference can be distributed among the scale factor bands.
*
**********************************************************************************/
static void correctThresh(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
PE_DATA *peData,
Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word32 redVal,
const Word16 nChannels,
const Word32 deltaPe)
{
Word16 ch, sfb, sfbGrp,shift;
PSY_OUT_CHANNEL *psyOutChan;
PE_CHANNEL_DATA *peChanData;
Word32 deltaSfbPe;
Word32 normFactor;
Word32 *psfbPeFactors;
Word16 *psfbNActiveLines, *pahFlag;
Word32 sfbEn, sfbThr;
Word32 sfbThrReduced;
/* for each sfb calc relative factors for pe changes */
normFactor = 1;
for(ch=0; ch<nChannels; ch++) {
psyOutChan = &psyOutChannel[ch];
peChanData = &peData->peChannelData[ch];
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
psfbPeFactors = peData->sfbPeFactors[ch] + sfbGrp;
psfbNActiveLines = peChanData->sfbNActiveLines + sfbGrp;
pahFlag = ahFlag[ch] + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
Word32 redThrExp = thrExp[ch][sfbGrp+sfb] + redVal;
if (((*pahFlag < AH_ACTIVE) || (deltaPe > 0)) && (redThrExp > 0) && (redThrExp >= *psfbNActiveLines)) {
*psfbPeFactors = (*psfbNActiveLines) * (0x7fffffff / redThrExp);
normFactor = L_add(normFactor, *psfbPeFactors);
}
else {
*psfbPeFactors = 0;
}
psfbPeFactors++;
pahFlag++; psfbNActiveLines++;
}
}
}
/* calculate new thresholds */
for(ch=0; ch<nChannels; ch++) {
psyOutChan = &psyOutChannel[ch];
peChanData = &peData->peChannelData[ch];
for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
psfbPeFactors = peData->sfbPeFactors[ch] + sfbGrp;
psfbNActiveLines = peChanData->sfbNActiveLines + sfbGrp;
pahFlag = ahFlag[ch] + sfbGrp;
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
/* pe difference for this sfb */
deltaSfbPe = *psfbPeFactors * deltaPe;
/* thr3(n) = thr2(n)*2^deltaSfbPe/b(n) */
if (*psfbNActiveLines > 0 && (normFactor* (*psfbNActiveLines)) != 0) {
/* new threshold */
Word32 thrFactor;
sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];
sfbThr = psyOutChan->sfbThreshold[sfbGrp+sfb];
if(deltaSfbPe >= 0){
/*
reduce threshold
*/
thrFactor = pow2_xy(L_negate(deltaSfbPe), (normFactor* (*psfbNActiveLines)));
sfbThrReduced = L_mpy_ls(sfbThr, round16(thrFactor));
}
else {
/*
increase threshold
*/
thrFactor = pow2_xy(deltaSfbPe, (normFactor * (*psfbNActiveLines)));
if(thrFactor > sfbThr) {
shift = norm_l(thrFactor);
sfbThrReduced = Div_32( sfbThr << shift, thrFactor<<shift );
}
else {
sfbThrReduced = MAX_32;
}
}
/* avoid hole */
sfbEn = L_mpy_ls(sfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);
if ((sfbThrReduced > sfbEn) &&
(*pahFlag == AH_INACTIVE)) {
sfbThrReduced = max(sfbEn, sfbThr);
*pahFlag = AH_ACTIVE;
}
psyOutChan->sfbThreshold[sfbGrp+sfb] = sfbThrReduced;
}
pahFlag++; psfbNActiveLines++; psfbPeFactors++;
}
}
}
}
/********************************************************************************
*
* function name:reduceMinSnr
* description: if the desired pe can not be reached, reduce pe by reducing minSnr
*
**********************************************************************************/
static void reduceMinSnr(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PE_DATA *peData,
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels,
const Word16 desiredPe)
{
Word16 ch, sfb, sfbSubWin;
Word16 deltaPe;
/* start at highest freq down to 0 */
sfbSubWin = psyOutChannel[0].maxSfbPerGroup;
while (peData->pe > desiredPe && sfbSubWin > 0) {
sfbSubWin = sfbSubWin - 1;
/* loop over all subwindows */
for (sfb=sfbSubWin; sfb<psyOutChannel[0].sfbCnt;
sfb+=psyOutChannel[0].sfbPerGroup) {
/* loop over all channels */
PE_CHANNEL_DATA* peChan = peData->peChannelData;
PSY_OUT_CHANNEL* psyOutCh = psyOutChannel;
for (ch=0; ch<nChannels; ch++) {
if (ahFlag[ch][sfb] != NO_AH &&
psyOutCh->sfbMinSnr[sfb] < minSnrLimit) {
psyOutCh->sfbMinSnr[sfb] = minSnrLimit;
psyOutCh->sfbThreshold[sfb] =
L_mpy_ls(psyOutCh->sfbEnergy[sfb], psyOutCh->sfbMinSnr[sfb]);
/* calc new pe */
deltaPe = ((peChan->sfbNLines4[sfb] + (peChan->sfbNLines4[sfb] >> 1)) >> 2) -
peChan->sfbPe[sfb];
peData->pe = peData->pe + deltaPe;
peChan->pe = peChan->pe + deltaPe;
}
peChan += 1; psyOutCh += 1;
}
/* stop if enough has been saved */
if (peData->pe <= desiredPe)
break;
}
}
}
/********************************************************************************
*
* function name:allowMoreHoles
* description: if the desired pe can not be reached, some more scalefactor bands
* have to be quantized to zero
*
**********************************************************************************/
static void allowMoreHoles(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
PE_DATA *peData,
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
const AH_PARAM *ahParam,
const Word16 nChannels,
const Word16 desiredPe)
{
Word16 ch, sfb;
Word16 actPe, shift;
actPe = peData->pe;
/* for MS allow hole in the channel with less energy */
if (nChannels==2 &&
psyOutChannel[0].windowSequence==psyOutChannel[1].windowSequence) {
PSY_OUT_CHANNEL *psyOutChanL = &psyOutChannel[0];
PSY_OUT_CHANNEL *psyOutChanR = &psyOutChannel[1];
for (sfb=0; sfb<psyOutChanL->sfbCnt; sfb++) {
Word32 minEn;
if (psyOutElement->toolsInfo.msMask[sfb]) {
/* allow hole in side channel ? */
minEn = L_mpy_ls(psyOutChanL->sfbEnergy[sfb], (minSnrLimit * psyOutChanL->sfbMinSnr[sfb]) >> 16);
if (ahFlag[1][sfb] != NO_AH &&
minEn > psyOutChanR->sfbEnergy[sfb]) {
ahFlag[1][sfb] = NO_AH;
psyOutChanR->sfbThreshold[sfb] = L_add(psyOutChanR->sfbEnergy[sfb], psyOutChanR->sfbEnergy[sfb]);
actPe = actPe - peData->peChannelData[1].sfbPe[sfb];
}
/* allow hole in mid channel ? */
else {
minEn = L_mpy_ls(psyOutChanR->sfbEnergy[sfb], (minSnrLimit * psyOutChanR->sfbMinSnr[sfb]) >> 16);
if (ahFlag[0][sfb]!= NO_AH &&
minEn > psyOutChanL->sfbEnergy[sfb]) {
ahFlag[0][sfb] = NO_AH;
psyOutChanL->sfbThreshold[sfb] = L_add(psyOutChanL->sfbEnergy[sfb], psyOutChanL->sfbEnergy[sfb]);
actPe = actPe - peData->peChannelData[0].sfbPe[sfb];
}
}
if (actPe < desiredPe)
break;
}
}
}
/* subsequently erase bands */
if (actPe > desiredPe) {
Word16 startSfb[2];
Word32 avgEn, minEn;
Word16 ahCnt;
Word16 enIdx;
Word16 enDiff;
Word32 en[4];
Word16 minSfb, maxSfb;
Flag done;
/* do not go below startSfb */
for (ch=0; ch<nChannels; ch++) {
if (psyOutChannel[ch].windowSequence != SHORT_WINDOW)
startSfb[ch] = ahParam->startSfbL;
else
startSfb[ch] = ahParam->startSfbS;
}
avgEn = 0;
minEn = MAX_32;
ahCnt = 0;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for (sfb=startSfb[ch]; sfb<psyOutChan->sfbCnt; sfb++) {
if ((ahFlag[ch][sfb] != NO_AH) &&
(psyOutChan->sfbEnergy[sfb] > psyOutChan->sfbThreshold[sfb])) {
minEn = min(minEn, psyOutChan->sfbEnergy[sfb]);
avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfb]);
ahCnt++;
}
}
}
if(ahCnt) {
Word32 iahCnt;
shift = norm_l(ahCnt);
iahCnt = Div_32( 1 << shift, ahCnt << shift );
avgEn = fixmul(avgEn, iahCnt);
if (avgEn < minEn)
avgEn = minEn;
}
enDiff = iLog4(avgEn) - iLog4(minEn);
/* calc some energy borders between minEn and avgEn */
for (enIdx=0; enIdx<4; enIdx++) {
Word32 enFac;
enFac = ((6-(enIdx << 1)) * enDiff);
en[enIdx] = fixmul(avgEn, pow2_xy(L_negate(enFac),7*4));
}
/* start with lowest energy border at highest sfb */
maxSfb = psyOutChannel[0].sfbCnt - 1;
minSfb = startSfb[0];
if (nChannels == 2) {
maxSfb = max(maxSfb, (psyOutChannel[1].sfbCnt - 1));
minSfb = min(minSfb, startSfb[1]);
}
sfb = maxSfb;
enIdx = 0;
done = 0;
while (!done) {
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
if (sfb>=startSfb[ch] && sfb<psyOutChan->sfbCnt) {
/* sfb energy below border ? */
if (ahFlag[ch][sfb] != NO_AH && psyOutChan->sfbEnergy[sfb] < en[enIdx]){
/* allow hole */
ahFlag[ch][sfb] = NO_AH;
psyOutChan->sfbThreshold[sfb] = L_add(psyOutChan->sfbEnergy[sfb], psyOutChan->sfbEnergy[sfb]);
actPe = actPe - peData->peChannelData[ch].sfbPe[sfb];
}
if (actPe < desiredPe) {
done = 1;
break;
}
}
}
sfb = sfb - 1;
if (sfb < minSfb) {
/* restart with next energy border */
sfb = maxSfb;
enIdx = enIdx + 1;
if (enIdx - 4 >= 0)
done = 1;
}
}
}
}
/********************************************************************************
*
* function name:adaptThresholdsToPe
* description: two guesses for the reduction value and one final correction of the
* thresholds
*
**********************************************************************************/
static void adaptThresholdsToPe(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
PE_DATA *peData,
const Word16 nChannels,
const Word16 desiredPe,
AH_PARAM *ahParam,
MINSNR_ADAPT_PARAM *msaParam)
{
Word16 noRedPe, redPe, redPeNoAH;
Word16 constPart, constPartNoAH;
Word16 nActiveLines, nActiveLinesNoAH;
Word16 desiredPeNoAH;
Word32 redVal, avgThrExp;
Word32 iter;
calcThreshExp(peData->thrExp, psyOutChannel, nChannels);
adaptMinSnr(psyOutChannel, logSfbEnergy, msaParam, nChannels);
initAvoidHoleFlag(peData->ahFlag, psyOutChannel, psyOutElement, nChannels, ahParam);
noRedPe = peData->pe;
constPart = peData->constPart;
nActiveLines = peData->nActiveLines;
/* first guess of reduction value t^0.25 = 2^((a-pen)/4*b) */
avgThrExp = pow2_xy((constPart - noRedPe), (nActiveLines << 2));
/* r1 = 2^((a-per)/4*b) - t^0.25 */
redVal = pow2_xy((constPart - desiredPe), (nActiveLines << 2)) - avgThrExp;
/* reduce thresholds */
reduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);
/* pe after first guess */
calcSfbPe(peData, psyOutChannel, nChannels);
redPe = peData->pe;
iter = 0;
do {
/* pe for bands where avoid hole is inactive */
calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH,
peData, peData->ahFlag, psyOutChannel, nChannels);
desiredPeNoAH = desiredPe -(redPe - redPeNoAH);
if (desiredPeNoAH < 0) {
desiredPeNoAH = 0;
}
/* second guess */
if (nActiveLinesNoAH > 0) {
avgThrExp = pow2_xy((constPartNoAH - redPeNoAH), (nActiveLinesNoAH << 2));
redVal = (redVal + pow2_xy((constPartNoAH - desiredPeNoAH), (nActiveLinesNoAH << 2))) - avgThrExp;
/* reduce thresholds */
reduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);
}
calcSfbPe(peData, psyOutChannel, nChannels);
redPe = peData->pe;
iter = iter+1;
} while ((20 * abs_s(redPe - desiredPe) > desiredPe) && (iter < 2));
if ((100 * redPe < 115 * desiredPe)) {
correctThresh(psyOutChannel, peData->ahFlag, peData, peData->thrExp, redVal,
nChannels, desiredPe - redPe);
}
else {
Word16 desiredPe105 = (105 * desiredPe) / 100;
reduceMinSnr(psyOutChannel, peData, peData->ahFlag,
nChannels, desiredPe105);
allowMoreHoles(psyOutChannel, psyOutElement, peData, peData->ahFlag,
ahParam, nChannels, desiredPe105);
}
}
/*****************************************************************************
*
* function name: calcBitSave
* description: Calculates percentage of bit save, see figure below
* returns:
* input: parameters and bitres-fullness
* output: percentage of bit save
*
*****************************************************************************/
static Word16 calcBitSave(Word16 fillLevel,
const Word16 clipLow,
const Word16 clipHigh,
const Word16 minBitSave,
const Word16 maxBitSave)
{
Word16 bitsave = 0;
fillLevel = max(fillLevel, clipLow);
fillLevel = min(fillLevel, clipHigh);
if(clipHigh-clipLow)
bitsave = (maxBitSave - (((maxBitSave-minBitSave)*(fillLevel-clipLow))/
(clipHigh-clipLow)));
return (bitsave);
}
/*****************************************************************************
*
* function name: calcBitSpend
* description: Calculates percentage of bit spend, see figure below
* returns:
* input: parameters and bitres-fullness
* output: percentage of bit spend
*
*****************************************************************************/
static Word16 calcBitSpend(Word16 fillLevel,
const Word16 clipLow,
const Word16 clipHigh,
const Word16 minBitSpend,
const Word16 maxBitSpend)
{
Word16 bitspend = 1;
fillLevel = max(fillLevel, clipLow);
fillLevel = min(fillLevel, clipHigh);
if(clipHigh-clipLow)
bitspend = (minBitSpend + ((maxBitSpend - minBitSpend)*(fillLevel - clipLow) /
(clipHigh-clipLow)));
return (bitspend);
}
/*****************************************************************************
*
* function name: adjustPeMinMax()
* description: adjusts peMin and peMax parameters over time
* returns:
* input: current pe, peMin, peMax
* output: adjusted peMin/peMax
*
*****************************************************************************/
static void adjustPeMinMax(const Word16 currPe,
Word16 *peMin,
Word16 *peMax)
{
Word16 minFacHi, maxFacHi, minFacLo, maxFacLo;
Word16 diff;
Word16 minDiff = extract_l(currPe / 6);
minFacHi = 30;
maxFacHi = 100;
minFacLo = 14;
maxFacLo = 7;
diff = currPe - *peMax ;
if (diff > 0) {
*peMin = *peMin + ((diff * minFacHi) / 100);
*peMax = *peMax + ((diff * maxFacHi) / 100);
} else {
diff = *peMin - currPe;
if (diff > 0) {
*peMin = *peMin - ((diff * minFacLo) / 100);
*peMax = *peMax - ((diff * maxFacLo) / 100);
} else {
*peMin = *peMin + ((currPe - *peMin) * minFacHi / 100);
*peMax = *peMax - ((*peMax - currPe) * maxFacLo / 100);
}
}
if ((*peMax - *peMin) < minDiff) {
Word16 partLo, partHi;
partLo = max(0, (currPe - *peMin));
partHi = max(0, (*peMax - currPe));
*peMax = currPe + ((partHi * minDiff) / (partLo + partHi));
*peMin = currPe - ((partLo * minDiff) / (partLo + partHi));
*peMin = max(0, *peMin);
}
}
/*****************************************************************************
*
* function name: BitresCalcBitFac
* description: calculates factor of spending bits for one frame
* 1.0 : take all frame dynpart bits
* >1.0 : take all frame dynpart bits + bitres
* <1.0 : put bits in bitreservoir
* returns: BitFac*100
* input: bitres-fullness, pe, blockType, parameter-settings
* output:
*
*****************************************************************************/
static Word16 bitresCalcBitFac( const Word16 bitresBits,
const Word16 maxBitresBits,
const Word16 pe,
const Word16 windowSequence,
const Word16 avgBits,
const Word16 maxBitFac,
ADJ_THR_STATE *AdjThr,
ATS_ELEMENT *adjThrChan)
{
BRES_PARAM *bresParam;
Word16 pex;
Word16 fillLevel;
Word16 bitSave, bitSpend, bitresFac;
fillLevel = extract_l((100* bitresBits) / maxBitresBits);
if (windowSequence != SHORT_WINDOW)
bresParam = &(AdjThr->bresParamLong);
else
bresParam = &(AdjThr->bresParamShort);
pex = max(pe, adjThrChan->peMin);
pex = min(pex,adjThrChan->peMax);
bitSave = calcBitSave(fillLevel,
bresParam->clipSaveLow, bresParam->clipSaveHigh,
bresParam->minBitSave, bresParam->maxBitSave);
bitSpend = calcBitSpend(fillLevel,
bresParam->clipSpendLow, bresParam->clipSpendHigh,
bresParam->minBitSpend, bresParam->maxBitSpend);
if(adjThrChan->peMax != adjThrChan->peMin)
bitresFac = (100 - bitSave) + extract_l(((bitSpend + bitSave) * (pex - adjThrChan->peMin)) /
(adjThrChan->peMax - adjThrChan->peMin));
else
bitresFac = 0x7fff;
bitresFac = min(bitresFac,
(100-30 + extract_l((100 * bitresBits) / avgBits)));
bitresFac = min(bitresFac, maxBitFac);
adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax);
return bitresFac;
}
/*****************************************************************************
*
* function name: AdjThrInit
* description: init thresholds parameter
*
*****************************************************************************/
void AdjThrInit(ADJ_THR_STATE *hAdjThr,
const Word32 meanPe,
Word32 chBitrate)
{
ATS_ELEMENT* atsElem = &hAdjThr->adjThrStateElem;
MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam;
/* common for all elements: */
/* parameters for bitres control */
hAdjThr->bresParamLong.clipSaveLow = 20;
hAdjThr->bresParamLong.clipSaveHigh = 95;
hAdjThr->bresParamLong.minBitSave = -5;
hAdjThr->bresParamLong.maxBitSave = 30;
hAdjThr->bresParamLong.clipSpendLow = 20;
hAdjThr->bresParamLong.clipSpendHigh = 95;
hAdjThr->bresParamLong.minBitSpend = -10;
hAdjThr->bresParamLong.maxBitSpend = 40;
hAdjThr->bresParamShort.clipSaveLow = 20;
hAdjThr->bresParamShort.clipSaveHigh = 75;
hAdjThr->bresParamShort.minBitSave = 0;
hAdjThr->bresParamShort.maxBitSave = 20;
hAdjThr->bresParamShort.clipSpendLow = 20;
hAdjThr->bresParamShort.clipSpendHigh = 75;
hAdjThr->bresParamShort.minBitSpend = -5;
hAdjThr->bresParamShort.maxBitSpend = 50;
/* specific for each element: */
/* parameters for bitres control */
atsElem->peMin = extract_l(((80*meanPe) / 100));
atsElem->peMax = extract_l(((120*meanPe) / 100));
/* additional pe offset to correct pe2bits for low bitrates */
atsElem->peOffset = 0;
if (chBitrate < 32000) {
atsElem->peOffset = max(50, (100 - extract_l((100 * chBitrate) / 32000)));
}
/* avoid hole parameters */
if (chBitrate > 20000) {
atsElem->ahParam.modifyMinSnr = TRUE;
atsElem->ahParam.startSfbL = 15;
atsElem->ahParam.startSfbS = 3;
}
else {
atsElem->ahParam.modifyMinSnr = FALSE;
atsElem->ahParam.startSfbL = 0;
atsElem->ahParam.startSfbS = 0;
}
/* minSnr adaptation */
/* maximum reduction of minSnr goes down to minSnr^maxRed */
msaParam->maxRed = 0x20000000; /* *0.25f */
/* start adaptation of minSnr for avgEn/sfbEn > startRatio */
msaParam->startRatio = 0x0ccccccd; /* 10 */
/* maximum minSnr reduction to minSnr^maxRed is reached for
avgEn/sfbEn >= maxRatio */
msaParam->maxRatio = 0x0020c49c; /* 1000 */
/* helper variables to interpolate minSnr reduction for
avgEn/sfbEn between startRatio and maxRatio */
msaParam->redRatioFac = 0xfb333333; /* -0.75/20 */
msaParam->redOffs = 0x30000000; /* msaParam->redRatioFac * 10*log10(msaParam->startRatio) */
/* pe correction */
atsElem->peLast = 0;
atsElem->dynBitsLast = 0;
atsElem->peCorrectionFactor = 100; /* 1.0 */
}
/*****************************************************************************
*
* function name: calcPeCorrection
* description: calculates the desired perceptual entropy factor
* It is between 0.85 and 1.15
*
*****************************************************************************/
static void calcPeCorrection(Word16 *correctionFac,
const Word16 peAct,
const Word16 peLast,
const Word16 bitsLast)
{
Word32 peAct100 = 100 * peAct;
Word32 peLast100 = 100 * peLast;
Word16 peBitsLast = bits2pe(bitsLast);
if ((bitsLast > 0) &&
(peAct100 < (150 * peLast)) && (peAct100 > (70 * peLast)) &&
((120 * peBitsLast) > peLast100 ) && (( 65 * peBitsLast) < peLast100))
{
Word16 newFac = (100 * peLast) / peBitsLast;
/* dead zone */
if (newFac < 100) {
newFac = min(((110 * newFac) / 100), 100);
newFac = max(newFac, 85);
}
else {
newFac = max(((90 * newFac) / 100), 100);
newFac = min(newFac, 115);
}
if ((newFac > 100 && *correctionFac < 100) ||
(newFac < 100 && *correctionFac > 100)) {
*correctionFac = 100;
}
/* faster adaptation towards 1.0, slower in the other direction */
if ((*correctionFac < 100 && newFac < *correctionFac) ||
(*correctionFac > 100 && newFac > *correctionFac))
*correctionFac = (85 * *correctionFac + 15 * newFac) / 100;
else
*correctionFac = (70 * *correctionFac + 30 * newFac) / 100;
*correctionFac = min(*correctionFac, 115);
*correctionFac = max(*correctionFac, 85);
}
else {
*correctionFac = 100;
}
}
/********************************************************************************
*
* function name: AdjustThresholds
* description: Adjust thresholds to the desired bitrate
*
**********************************************************************************/
void AdjustThresholds(ADJ_THR_STATE *adjThrState,
ATS_ELEMENT *AdjThrStateElement,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word16 *chBitDistribution,
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
QC_OUT_ELEMENT *qcOE,
ELEMENT_BITS *elBits,
const Word16 nChannels,
const Word16 maxBitFac)
{
PE_DATA peData;
Word16 noRedPe, grantedPe, grantedPeCorr;
Word16 curWindowSequence;
Word16 bitFactor;
Word16 avgBits = (elBits->averageBits - (qcOE->staticBitsUsed + qcOE->ancBitsUsed));
Word16 bitresBits = elBits->bitResLevel;
Word16 maxBitresBits = elBits->maxBits;
Word16 sideInfoBits = (qcOE->staticBitsUsed + qcOE->ancBitsUsed);
Word16 ch;
memset(&peData, 0, sizeof(peData));
prepareSfbPe(&peData, psyOutChannel, logSfbEnergy, sfbNRelevantLines, nChannels, AdjThrStateElement->peOffset);
/* pe without reduction */
calcSfbPe(&peData, psyOutChannel, nChannels);
noRedPe = peData.pe;
curWindowSequence = LONG_WINDOW;
if (nChannels == 2) {
if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) ||
(psyOutChannel[1].windowSequence == SHORT_WINDOW)) {
curWindowSequence = SHORT_WINDOW;
}
}
else {
curWindowSequence = psyOutChannel[0].windowSequence;
}
/* bit factor */
bitFactor = bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe+5*sideInfoBits,
curWindowSequence, avgBits, maxBitFac,
adjThrState,
AdjThrStateElement);
/* desired pe */
grantedPe = ((bitFactor * bits2pe(avgBits)) / 100);
/* correction of pe value */
calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor),
min(grantedPe, noRedPe),
AdjThrStateElement->peLast,
AdjThrStateElement->dynBitsLast);
grantedPeCorr = (grantedPe * AdjThrStateElement->peCorrectionFactor) / 100;
if (grantedPeCorr < noRedPe && noRedPe > peData.offset) {
/* calc threshold necessary for desired pe */
adaptThresholdsToPe(psyOutChannel,
psyOutElement,
logSfbEnergy,
&peData,
nChannels,
grantedPeCorr,
&AdjThrStateElement->ahParam,
&AdjThrStateElement->minSnrAdaptParam);
}
/* calculate relative distribution */
for (ch=0; ch<nChannels; ch++) {
Word16 peOffsDiff = peData.pe - peData.offset;
chBitDistribution[ch] = 200;
if (peOffsDiff > 0) {
Word32 temp = 1000 - (nChannels * 200);
chBitDistribution[ch] = chBitDistribution[ch] +
(temp * peData.peChannelData[ch].pe) / peOffsDiff;
}
}
/* store pe */
qcOE->pe = noRedPe;
/* update last pe */
AdjThrStateElement->peLast = grantedPe;
}
/********************************************************************************
*
* function name: AdjThrUpdate
* description: save dynBitsUsed for correction of bits2pe relation
*
**********************************************************************************/
void AdjThrUpdate(ATS_ELEMENT *AdjThrStateElement,
const Word16 dynBitsUsed)
{
AdjThrStateElement->dynBitsLast = dynBitsUsed;
}

57
aacenc/external/aacenc/src/adj_thr.h vendored Normal file
View file

@ -0,0 +1,57 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: adj_thr.h
Content: Threshold compensation function
*******************************************************************************/
#ifndef __ADJ_THR_H
#define __ADJ_THR_H
#include "adj_thr_data.h"
#include "qc_data.h"
#include "interface.h"
Word16 bits2pe(const Word16 bits);
Word32 AdjThrNew(ADJ_THR_STATE** phAdjThr,
Word32 nElements);
void AdjThrDelete(ADJ_THR_STATE *hAdjThr);
void AdjThrInit(ADJ_THR_STATE *hAdjThr,
const Word32 peMean,
Word32 chBitrate);
void AdjustThresholds(ADJ_THR_STATE *adjThrState,
ATS_ELEMENT* AdjThrStateElement,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word16 *chBitDistribution,
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
QC_OUT_ELEMENT* qcOE,
ELEMENT_BITS* elBits,
const Word16 nChannels,
const Word16 maxBitFac);
void AdjThrUpdate(ATS_ELEMENT *AdjThrStateElement,
const Word16 dynBitsUsed);
#endif

View file

@ -0,0 +1,69 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: adj_thr_data.h
Content: Threshold compensation parameter
*******************************************************************************/
#ifndef __ADJ_THR_DATA_H
#define __ADJ_THR_DATA_H
#include "typedef.h"
#include "psy_const.h"
#include "line_pe.h"
typedef struct {
Word16 clipSaveLow, clipSaveHigh;
Word16 minBitSave, maxBitSave;
Word16 clipSpendLow, clipSpendHigh;
Word16 minBitSpend, maxBitSpend;
} BRES_PARAM;
typedef struct {
UWord8 modifyMinSnr;
Word16 startSfbL, startSfbS;
} AH_PARAM;
typedef struct {
Word32 maxRed;
Word32 startRatio, maxRatio;
Word32 redRatioFac;
Word32 redOffs;
} MINSNR_ADAPT_PARAM;
typedef struct {
/* parameters for bitreservoir control */
Word16 peMin, peMax;
/* constant offset to pe */
Word16 peOffset;
/* avoid hole parameters */
AH_PARAM ahParam;
/* paramters for adaptation of minSnr */
MINSNR_ADAPT_PARAM minSnrAdaptParam;
/* values for correction of pe */
Word16 peLast;
Word16 dynBitsLast;
Word16 peCorrectionFactor;
} ATS_ELEMENT;
typedef struct {
BRES_PARAM bresParamLong, bresParamShort; /* Word16 size: 2*8 */
ATS_ELEMENT adjThrStateElem; /* Word16 size: 19 */
} ADJ_THR_STATE;
#endif

102
aacenc/external/aacenc/src/band_nrg.c vendored Normal file
View file

@ -0,0 +1,102 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: band_nrg.c
Content: Band/Line energy calculations functions
*******************************************************************************/
#include "basic_op.h"
#include "band_nrg.h"
#ifndef ARMV5E
/********************************************************************************
*
* function name: CalcBandEnergy
* description: Calc sfb-bandwise mdct-energies for left and right channel
*
**********************************************************************************/
void CalcBandEnergy(const Word32 *mdctSpectrum,
const Word16 *bandOffset,
const Word16 numBands,
Word32 *bandEnergy,
Word32 *bandEnergySum)
{
Word32 i, j;
Word32 accuSum = 0;
for (i=0; i<numBands; i++) {
Word32 accu = 0;
for (j=bandOffset[i]; j<bandOffset[i+1]; j++)
accu = L_add(accu, MULHIGH(mdctSpectrum[j], mdctSpectrum[j]));
accu = L_add(accu, accu);
accuSum = L_add(accuSum, accu);
bandEnergy[i] = accu;
}
*bandEnergySum = accuSum;
}
/********************************************************************************
*
* function name: CalcBandEnergyMS
* description: Calc sfb-bandwise mdct-energies for left add or minus right channel
*
**********************************************************************************/
void CalcBandEnergyMS(const Word32 *mdctSpectrumLeft,
const Word32 *mdctSpectrumRight,
const Word16 *bandOffset,
const Word16 numBands,
Word32 *bandEnergyMid,
Word32 *bandEnergyMidSum,
Word32 *bandEnergySide,
Word32 *bandEnergySideSum)
{
Word32 i, j;
Word32 accuMidSum = 0;
Word32 accuSideSum = 0;
for(i=0; i<numBands; i++) {
Word32 accuMid = 0;
Word32 accuSide = 0;
for (j=bandOffset[i]; j<bandOffset[i+1]; j++) {
Word32 specm, specs;
Word32 l, r;
l = mdctSpectrumLeft[j] >> 1;
r = mdctSpectrumRight[j] >> 1;
specm = l + r;
specs = l - r;
accuMid = L_add(accuMid, MULHIGH(specm, specm));
accuSide = L_add(accuSide, MULHIGH(specs, specs));
}
accuMid = L_add(accuMid, accuMid);
accuSide = L_add(accuSide, accuSide);
bandEnergyMid[i] = accuMid;
accuMidSum = L_add(accuMidSum, accuMid);
bandEnergySide[i] = accuSide;
accuSideSum = L_add(accuSideSum, accuSide);
}
*bandEnergyMidSum = accuMidSum;
*bandEnergySideSum = accuSideSum;
}
#endif

46
aacenc/external/aacenc/src/band_nrg.h vendored Normal file
View file

@ -0,0 +1,46 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: band_nrg.h
Content: Band/Line energy calculations functions
*******************************************************************************/
#ifndef _BAND_NRG_H
#define _BAND_NRG_H
#include "typedef.h"
void CalcBandEnergy(const Word32 *mdctSpectrum,
const Word16 *bandOffset,
const Word16 numBands,
Word32 *bandEnergy,
Word32 *bandEnergySum);
void CalcBandEnergyMS(const Word32 *mdctSpectrumLeft,
const Word32 *mdctSpectrumRight,
const Word16 *bandOffset,
const Word16 numBands,
Word32 *bandEnergyMid,
Word32 *bandEnergyMidSum,
Word32 *bandEnergySide,
Word32 *bandEnergySideSum);
#endif

1178
aacenc/external/aacenc/src/basic_op.h vendored Normal file
View file

@ -0,0 +1,1178 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: basicop2.h
Content: Constants , Globals and Basic arithmetic operators.
*******************************************************************************/
#ifndef __BASIC_OP_H
#define __BASIC_OP_H
#include "typedef.h"
#define MAX_32 (Word32)0x7fffffffL
#define MIN_32 (Word32)0x80000000L
#define MAX_16 (Word16)0x7fff
#define MIN_16 (Word16)0x8000
#define ABS(a) ((a) >= 0) ? (a) : (-(a))
/* Short abs, 1 */
#define abs_s(x) (((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16)
/* 16 bit var1 -> MSB, 2 */
#define L_deposit_h(x) (((Word32)(x)) << 16)
/* 16 bit var1 -> LSB, 2 */
#define L_deposit_l(x) ((Word32)(x))
/* Long abs, 3 */
#define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)
/* Short negate, 1 */
#define negate(var1) (((var1) == MIN_16) ? MAX_16 : (-(var1)))
/* Long negate, 2 */
#define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))
#define MULHIGH(A,B) (int)(((Word64)(A)*(Word64)(B)) >> 32)
#define fixmul(a, b) (int)((((Word64)(a)*(Word64)(b)) >> 32) << 1)
#if (SATRUATE_IS_INLINE)
__inline Word32 saturate(Word32 L_var1);
#else
Word16 saturate(Word32 L_var1);
#endif
/* Short shift left, 1 */
#if (SHL_IS_INLINE)
__inline Word32 shl (Word32 var1, Word32 var2);
#else
Word16 shl (Word16 var1, Word16 var2);
#endif
/* Short shift right, 1 */
#if (SHR_IS_INLINE)
__inline Word32 shr (Word32 var1, Word32 var2);
#else
Word16 shr (Word16 var1, Word16 var2);
#endif
#if (L_MULT_IS_INLINE)
__inline Word32 L_mult(Word32 var1, Word32 var2);
#else
Word32 L_mult(Word16 var1, Word16 var2);
#endif
/* Msu, 1 */
#if (L_MSU_IS_INLINE)
__inline Word32 L_msu (Word32 L_var3, Word32 var1, Word32 var2);
#else
Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);
#endif
/* Long sub, 2 */
#if (L_SUB_IS_INLINE)
__inline Word32 L_sub(Word32 L_var1, Word32 L_var2);
#else
Word32 L_sub(Word32 L_var1, Word32 L_var2);
#endif
/* Long shift left, 2 */
#if (L_SHL_IS_INLINE)
__inline Word32 L_shl (Word32 L_var1, Word32 var2);
#else
Word32 L_shl (Word32 L_var1, Word16 var2);
#endif
/* Long shift right, 2*/
#if (L_SHR_IS_INLINE)
__inline Word32 L_shr (Word32 L_var1, Word32 var2);
#else
Word32 L_shr (Word32 L_var1, Word16 var2);
#endif
/* Short add, 1 */
#if (ADD_IS_INLINE)
__inline Word32 add (Word32 var1, Word32 var2);
#else
Word16 add (Word16 var1, Word16 var2);
#endif
/* Short sub, 1 */
#if (SUB_IS_INLINE)
__inline Word32 sub(Word32 var1, Word32 var2);
#else
Word16 sub(Word16 var1, Word16 var2);
#endif
/* Short division, 18 */
#if (DIV_S_IS_INLINE)
__inline Word32 div_s (Word32 var1, Word32 var2);
#else
Word16 div_s (Word16 var1, Word16 var2);
#endif
/* Short mult, 1 */
#if (MULT_IS_INLINE)
__inline Word32 mult (Word32 var1, Word32 var2);
#else
Word16 mult (Word16 var1, Word16 var2);
#endif
/* Short norm, 15 */
#if (NORM_S_IS_INLINE)
__inline Word32 norm_s (Word32 var1);
#else
Word16 norm_s (Word16 var1);
#endif
/* Long norm, 30 */
#if (NORM_L_IS_INLINE)
__inline Word32 norm_l (Word32 L_var1);
#else
Word16 norm_l (Word32 L_var1);
#endif
/* Round, 1 */
#if (ROUND_IS_INLINE)
__inline Word32 round16(Word32 L_var1);
#else
Word16 round16(Word32 L_var1);
#endif
/* Mac, 1 */
#if (L_MAC_IS_INLINE)
__inline Word32 L_mac (Word32 L_var3, Word32 var1, Word32 var2);
#else
Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);
#endif
#if (L_ADD_IS_INLINE)
__inline Word32 L_add (Word32 L_var1, Word32 L_var2);
#else
Word32 L_add (Word32 L_var1, Word32 L_var2);
#endif
/* Extract high, 1 */
#if (EXTRACT_H_IS_INLINE)
__inline Word32 extract_h (Word32 L_var1);
#else
Word16 extract_h (Word32 L_var1);
#endif
/* Extract low, 1 */
#if (EXTRACT_L_IS_INLINE)
__inline Word32 extract_l(Word32 L_var1);
#else
Word16 extract_l(Word32 L_var1);
#endif
/* Mult with round, 2 */
#if (MULT_R_IS_INLINE)
__inline Word32 mult_r(Word32 var1, Word32 var2);
#else
Word16 mult_r(Word16 var1, Word16 var2);
#endif
/* Shift right with round, 2 */
#if (SHR_R_IS_INLINE)
__inline Word32 shr_r (Word32 var1, Word32 var2);
#else
Word16 shr_r (Word16 var1, Word16 var2);
#endif
/* Mac with rounding,2 */
#if (MAC_R_IS_INLINE)
__inline Word32 mac_r (Word32 L_var3, Word32 var1, Word32 var2);
#else
Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2);
#endif
/* Msu with rounding,2 */
#if (MSU_R_IS_INLINE)
__inline Word32 msu_r (Word32 L_var3, Word32 var1, Word32 var2);
#else
Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2);
#endif
/* Long shift right with round, 3 */
#if (L_SHR_R_IS_INLINE)
__inline Word32 L_shr_r (Word32 L_var1, Word32 var2);
#else
Word32 L_shr_r (Word32 L_var1, Word16 var2);
#endif
#if ARMV4_INASM
__inline Word32 ASM_L_shr(Word32 L_var1, Word32 var2)
{
return L_var1 >> var2;
}
__inline Word32 ASM_L_shl(Word32 L_var1, Word32 var2)
{
Word32 result;
asm (
"MOV %[result], %[L_var1], ASL %[var2] \n"
"TEQ %[L_var1], %[result], ASR %[var2]\n"
"EORNE %[result], %[mask], %[L_var1], ASR #31\n"
:[result]"=&r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff)
:"cc"
);
return result;
}
__inline Word32 ASM_shr(Word32 L_var1, Word32 var2)
{
Word32 result;
asm (
"CMP %[var2], #15\n"
"MOVLT %[result], %[L_var1], ASR %[var2]\n"
"MOVGE %[result], %[L_var1], ASR #15\n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
:"cc"
);
return result;
}
__inline Word32 ASM_shl(Word32 L_var1, Word32 var2)
{
#if ARMV6_SAT
Word32 result;
asm (
"CMP %[var2], #16\n"
"MOVLT %[result], %[L_var1], ASL %[var2]\n"
"MOVGE %[result], %[L_var1], ASL #16\n"
"SSAT %[result], #16, %[result]\n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
:"cc"
);
return result;
#else
Word32 result;
Word32 tmp;
asm (
"CMP %[var2], #16\n"
"MOVLT %[result], %[L_var1], ASL %[var2]\n"
"MOVGE %[result], %[L_var1], ASL #16\n"
"MOV %[tmp], %[result], ASR #15\n"
"TEQ %[tmp], %[result], ASR #31 \n"
"EORNE %[result], %[mask], %[result],ASR #31"
:[result]"=&r"(result), [tmp]"=&r"(tmp)
:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff)
:"cc"
);
return result;
#endif
}
#endif
/*___________________________________________________________________________
| |
| definitions for inline basic arithmetic operators |
|___________________________________________________________________________|
*/
#if (SATRUATE_IS_INLINE)
__inline Word32 saturate(Word32 L_var1)
{
#if ARMV6_SAT
Word32 result;
asm (
"SSAT %[result], #16, %[L_var1]"
: [result]"=r"(result)
: [L_var1]"r"(L_var1)
);
return result;
#elif ARMV5TE_SAT
Word32 result;
Word32 tmp;
asm volatile (
"MOV %[tmp], %[L_var1],ASR#15\n"
"TEQ %[tmp], %[L_var1],ASR#31\n"
"EORNE %[result], %[mask],%[L_var1],ASR#31\n"
"MOVEQ %[result], %[L_var1]\n"
:[result]"=&r"(result), [tmp]"=&r"(tmp)
:[L_var1]"r"(L_var1), [mask]"r"(0x7fff)
:"cc"
);
return result;
#else
Word32 var_out;
//var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1));
if (L_var1 > 0X00007fffL)
{
var_out = MAX_16;
}
else if (L_var1 < (Word32) 0xffff8000L)
{
var_out = MIN_16;
}
else
{
var_out = extract_l(L_var1);
}
return (var_out);
#endif
}
#endif
/* Short shift left, 1 */
#if (SHL_IS_INLINE)
__inline Word32 shl (Word32 var1, Word32 var2)
{
#if ARMV5TE_SHL
if(var2>=0)
{
return ASM_shl( var1, var2);
}
else
{
return ASM_shr( var1, -var2);
}
#else
Word32 var_out;
Word32 result;
if (var2 < 0)
{
var_out = shr (var1, (Word16)-var2);
}
else
{
result = (Word32) var1 *((Word32) 1 << var2);
if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
{
var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
}
else
{
var_out = extract_l(result);
}
}
return (var_out);
#endif
}
#endif
/* Short shift right, 1 */
#if (SHR_IS_INLINE)
__inline Word32 shr (Word32 var1, Word32 var2)
{
#if ARMV5TE_SHR
if(var2>=0)
{
return ASM_shr( var1, var2);
}
else
{
return ASM_shl( var1, -var2);
}
#else
Word32 var_out;
if (var2 < 0)
{
var_out = shl (var1, (Word16)-var2);
}
else
{
if (var2 >= 15)
{
var_out = (Word16)((var1 < 0) ? -1 : 0);
}
else
{
if (var1 < 0)
{
var_out = (Word16)(~((~var1) >> var2));
}
else
{
var_out = (Word16)(var1 >> var2);
}
}
}
return (var_out);
#endif
}
#endif
#if (L_MULT_IS_INLINE)
__inline Word32 L_mult(Word32 var1, Word32 var2)
{
#if ARMV5TE_L_MULT
Word32 result;
asm (
"SMULBB %[result], %[var1], %[var2] \n"
"QADD %[result], %[result], %[result] \n"
:[result]"=r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
);
return result;
#else
Word32 L_var_out;
L_var_out = (Word32) var1 *(Word32) var2;
if (L_var_out != (Word32) 0x40000000L)
{
L_var_out <<= 1;
}
else
{
L_var_out = MAX_32;
}
return (L_var_out);
#endif
}
#endif
#if (L_MSU_IS_INLINE)
__inline Word32 L_msu (Word32 L_var3, Word32 var1, Word32 var2)
{
#if ARMV5TE_L_MSU
Word32 result;
asm (
"SMULBB %[result], %[var1], %[var2] \n"
"QDSUB %[result], %[L_var3], %[result]\n"
:[result]"=&r"(result)
:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
);
return result;
#else
Word32 L_var_out;
Word32 L_product;
L_product = L_mult(var1, var2);
L_var_out = L_sub(L_var3, L_product);
return (L_var_out);
#endif
}
#endif
#if (L_SUB_IS_INLINE)
__inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
{
#if ARMV5TE_L_SUB
Word32 result;
asm (
"QSUB %[result], %[L_var1], %[L_var2]\n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
);
return result;
#else
Word32 L_var_out;
L_var_out = L_var1 - L_var2;
if (((L_var1 ^ L_var2) & MIN_32) != 0)
{
if ((L_var_out ^ L_var1) & MIN_32)
{
L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
}
}
return (L_var_out);
#endif
}
#endif
#if (L_SHL_IS_INLINE)
__inline Word32 L_shl(Word32 L_var1, Word32 var2)
{
#if ARMV5TE_L_SHL
if(var2>=0)
{
return ASM_L_shl( L_var1, var2);
}
else
{
return ASM_L_shr( L_var1, -var2);
}
#else
if (var2 <= 0)
{
L_var1 = L_shr(L_var1, (Word16)-var2);
}
else
{
for (; var2 > 0; var2--)
{
if (L_var1 > (Word32) 0X3fffffffL)
{
return MAX_32;
}
else
{
if (L_var1 < (Word32) 0xc0000000L)
{
return MIN_32;
}
}
L_var1 <<= 1;
}
}
return (L_var1);
#endif
}
#endif
#if (L_SHR_IS_INLINE)
__inline Word32 L_shr (Word32 L_var1, Word32 var2)
{
#if ARMV5TE_L_SHR
if(var2>=0)
{
return ASM_L_shr( L_var1, var2);
}
else
{
return ASM_L_shl( L_var1, -var2);
}
#else
Word32 L_var_out;
if (var2 < 0)
{
L_var_out = L_shl (L_var1, (Word16)-var2);
}
else
{
if (var2 >= 31)
{
L_var_out = (L_var1 < 0L) ? -1 : 0;
}
else
{
if (L_var1 < 0)
{
L_var_out = ~((~L_var1) >> var2);
}
else
{
L_var_out = L_var1 >> var2;
}
}
}
return (L_var_out);
#endif
}
#endif
/* Short add, 1 */
#if (ADD_IS_INLINE)
__inline Word32 add (Word32 var1, Word32 var2)
{
#if ARMV5TE_ADD
Word32 result;
Word32 tmp;
asm (
"ADD %[result], %[var1], %[var2] \n"
"MOV %[tmp], %[result], ASR #15 \n"
"TEQ %[tmp], %[result], ASR #31 \n"
"EORNE %[result], %[mask], %[result], ASR #31"
:[result]"=&r"(result), [tmp]"=&r"(tmp)
:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
:"cc"
);
return result;
#else
Word32 var_out;
Word32 L_sum;
L_sum = (Word32) var1 + var2;
var_out = saturate(L_sum);
return (var_out);
#endif
}
#endif
/* Short sub, 1 */
#if (SUB_IS_INLINE)
__inline Word32 sub(Word32 var1, Word32 var2)
{
#if ARMV5TE_SUB
Word32 result;
Word32 tmp;
asm (
"SUB %[result], %[var1], %[var2] \n"
"MOV %[tmp], %[var1], ASR #15 \n"
"TEQ %[tmp], %[var1], ASR #31 \n"
"EORNE %[result], %[mask], %[result], ASR #31 \n"
:[result]"=&r"(result), [tmp]"=&r"(tmp)
:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
:"cc"
);
return result;
#else
Word32 var_out;
Word32 L_diff;
L_diff = (Word32) var1 - var2;
var_out = saturate(L_diff);
return (var_out);
#endif
}
#endif
/* Short division, 18 */
#if (DIV_S_IS_INLINE)
__inline Word32 div_s (Word32 var1, Word32 var2)
{
Word32 var_out = 0;
Word32 iteration;
Word32 L_num;
Word32 L_denom;
var_out = MAX_16;
if (var1!= var2)//var1!= var2
{
var_out = 0;
L_num = (Word32) var1;
L_denom = (Word32) var2;
//return (L_num<<15)/var2;
for (iteration = 0; iteration < 15; iteration++)
{
var_out <<= 1;
L_num <<= 1;
if (L_num >= L_denom)
{
L_num -= L_denom;
var_out++;
}
}
}
return (var_out);
}
#endif
/* Short mult, 1 */
#if (MULT_IS_INLINE)
__inline Word32 mult (Word32 var1, Word32 var2)
{
#if ARMV5TE_MULT && ARMV6_SAT
Word32 result;
asm (
"SMULBB %[result], %[var1], %[var2] \n"
"SSAT %[result], #16, %[result], ASR #15 \n"
:[result]"=r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
);
return result;
#elif ARMV5TE_MULT
Word32 result, tmp;
asm (
"SMULBB %[tmp], %[var1], %[var2] \n"
"MOV %[result], %[tmp], ASR #15\n"
"MOV %[tmp], %[result], ASR #15\n"
"TEQ %[tmp], %[result], ASR #31\n"
"EORNE %[result], %[mask], %[result], ASR #31 \n"
:[result]"=&r"(result), [tmp]"=&r"(tmp)
:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
:"cc"
);
return result;
#else
Word32 var_out;
Word32 L_product;
L_product = (Word32) var1 *(Word32) var2;
L_product = (L_product & (Word32) 0xffff8000L) >> 15;
if (L_product & (Word32) 0x00010000L)
L_product = L_product | (Word32) 0xffff0000L;
var_out = saturate(L_product);
return (var_out);
#endif
}
#endif
/* Short norm, 15 */
#if (NORM_S_IS_INLINE)
__inline Word32 norm_s (Word32 var1)
{
#if ARMV5TE_NORM_S
Word32 result;
Word32 tmp;
asm (
"RSBS %[tmp], %[var1], #0 \n"
"CLZLT %[result], %[var1]\n"
"CLZGT %[result], %[tmp]\n"
"SUBNE %[result], %[result], #17\n"
"MOVEQ %[result], #0\n"
"CMP %[var1], #-1\n"
"MOVEQ %[result], #15\n"
:[result]"=&r"(result), [tmp]"=&r"(tmp)
:[var1]"r"(var1)
:"cc"
);
return result;
#else
Word32 var_out;
if (var1 == 0)
{
var_out = 0;
}
else
{
if (var1 == -1)
{
var_out = 15;
}
else
{
if (var1 < 0)
{
var1 = (Word16)~var1;
}
for (var_out = 0; var1 < 0x4000; var_out++)
{
var1 <<= 1;
}
}
}
return (var_out);
#endif
}
#endif
/* Long norm, 30 */
#if (NORM_L_IS_INLINE)
__inline Word32 norm_l (Word32 L_var1)
{
#if ARMV5TE_NORM_L
Word32 result;
asm volatile(
"CMP %[L_var1], #0\n"
"CLZNE %[result], %[L_var1]\n"
"SUBNE %[result], %[result], #1\n"
"MOVEQ %[result], #0\n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1)
:"cc"
);
return result;
#else
//Word16 var_out;
//if (L_var1 == 0)
//{
// var_out = 0;
//}
//else
//{
// if (L_var1 == (Word32) 0xffffffffL)
// {
// var_out = 31;
// }
// else
// {
// if (L_var1 < 0)
// {
// L_var1 = ~L_var1;
// }
// for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
// {
// L_var1 <<= 1;
// }
// }
//}
//return (var_out);
Word16 a16;
Word16 r = 0 ;
if ( L_var1 < 0 ) {
L_var1 = ~L_var1;
}
if (0 == (L_var1 & 0x7fff8000)) {
a16 = extract_l(L_var1);
r += 16;
if (0 == (a16 & 0x7f80)) {
r += 8;
if (0 == (a16 & 0x0078)) {
r += 4;
if (0 == (a16 & 0x0006)) {
r += 2;
if (0 == (a16 & 0x0001)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x0004)) {
r += 1;
}
}
}
else {
if (0 == (a16 & 0x0060)) {
r += 2;
if (0 == (a16 & 0x0010)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x0040)) {
r += 1;
}
}
}
}
else {
if (0 == (a16 & 0x7800)) {
r += 4;
if (0 == (a16 & 0x0600)) {
r += 2;
if (0 == (a16 & 0x0100)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x0400)) {
r += 1;
}
}
}
else {
if (0 == (a16 & 0x6000)) {
r += 2;
if (0 == (a16 & 0x1000)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x4000)) {
r += 1;
}
}
}
}
}
else {
a16 = extract_h(L_var1);
if (0 == (a16 & 0x7f80)) {
r += 8;
if (0 == (a16 & 0x0078)) {
r += 4 ;
if (0 == (a16 & 0x0006)) {
r += 2;
if (0 == (a16 & 0x0001)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x0004)) {
r += 1;
}
}
}
else {
if (0 == (a16 & 0x0060)) {
r += 2;
if (0 == (a16 & 0x0010)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x0040)) {
r += 1;
}
}
}
}
else {
if (0 == (a16 & 0x7800)) {
r += 4;
if (0 == (a16 & 0x0600)) {
r += 2;
if (0 == (a16 & 0x0100)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x0400)) {
r += 1;
}
}
}
else {
if (0 == (a16 & 0x6000)) {
r += 2;
if (0 == (a16 & 0x1000)) {
r += 1;
}
}
else {
if (0 == (a16 & 0x4000)) {
return 1;
}
}
}
}
}
return r ;
#endif
}
#endif
/* Round, 1 */
#if (ROUND_IS_INLINE)
__inline Word32 round16(Word32 L_var1)
{
#if ARMV5TE_ROUND
Word32 result;
asm (
"QADD %[result], %[L_var1], %[bias]\n"
"MOV %[result], %[result], ASR #16 \n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [bias]"r"(0x8000)
);
return result;
#else
Word32 var_out;
Word32 L_rounded;
L_rounded = L_add (L_var1, (Word32) 0x00008000L);
var_out = extract_h (L_rounded);
return (var_out);
#endif
}
#endif
/* Mac, 1 */
#if (L_MAC_IS_INLINE)
__inline Word32 L_mac (Word32 L_var3, Word32 var1, Word32 var2)
{
#if ARMV5TE_L_MAC
Word32 result;
asm (
"SMULBB %[result], %[var1], %[var2]\n"
"QDADD %[result], %[L_var3], %[result]\n"
:[result]"=&r"(result)
: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
);
return result;
#else
Word32 L_var_out;
Word32 L_product;
L_product = L_mult(var1, var2);
L_var_out = L_add (L_var3, L_product);
return (L_var_out);
#endif
}
#endif
#if (L_ADD_IS_INLINE)
__inline Word32 L_add (Word32 L_var1, Word32 L_var2)
{
#if ARMV5TE_L_ADD
Word32 result;
asm (
"QADD %[result], %[L_var1], %[L_var2]\n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
);
return result;
#else
Word32 L_var_out;
L_var_out = L_var1 + L_var2;
if (((L_var1 ^ L_var2) & MIN_32) == 0)
{
if ((L_var_out ^ L_var1) & MIN_32)
{
L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
}
}
return (L_var_out);
#endif
}
#endif
#if (MULT_R_IS_INLINE)
__inline Word32 mult_r (Word32 var1, Word32 var2)
{
Word32 var_out;
Word32 L_product_arr;
L_product_arr = (Word32)var1 *(Word32)var2; /* product */
L_product_arr += (Word32)0x00004000L; /* round */
L_product_arr >>= 15; /* shift */
var_out = saturate(L_product_arr);
return (var_out);
}
#endif
#if (SHR_R_IS_INLINE)
__inline Word32 shr_r (Word32 var1, Word32 var2)
{
Word32 var_out;
if (var2 > 15)
{
var_out = 0;
}
else
{
var_out = shr(var1, var2);
if (var2 > 0)
{
if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
{
var_out++;
}
}
}
return (var_out);
}
#endif
#if (MAC_R_IS_INLINE)
__inline Word32 mac_r (Word32 L_var3, Word32 var1, Word32 var2)
{
Word32 var_out;
L_var3 = L_mac (L_var3, var1, var2);
var_out = (Word16)((L_var3 + 0x8000L) >> 16);
return (var_out);
}
#endif
#if (MSU_R_IS_INLINE)
__inline Word32 msu_r (Word32 L_var3, Word32 var1, Word32 var2)
{
Word32 var_out;
L_var3 = L_msu (L_var3, var1, var2);
var_out = (Word16)((L_var3 + 0x8000L) >> 16);
return (var_out);
}
#endif
#if (L_SHR_R_IS_INLINE)
__inline Word32 L_shr_r (Word32 L_var1, Word32 var2)
{
Word32 L_var_out;
if (var2 > 31)
{
L_var_out = 0;
}
else
{
L_var_out = L_shr(L_var1, var2);
if (var2 > 0)
{
if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
{
L_var_out++;
}
}
}
return (L_var_out);
}
#endif
#if (EXTRACT_H_IS_INLINE)
__inline Word32 extract_h (Word32 L_var1)
{
Word32 var_out;
var_out = (L_var1 >> 16);
return (var_out);
}
#endif
#if (EXTRACT_L_IS_INLINE)
__inline Word32 extract_l(Word32 L_var1)
{
return (Word16) L_var1;
}
#endif
#endif

1624
aacenc/external/aacenc/src/basicop2.c vendored Normal file
View file

@ -0,0 +1,1624 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: basicop2.c
Content: Basic arithmetic operators.
*******************************************************************************/
#include "typedef.h"
#include "basic_op.h"
/*___________________________________________________________________________
| |
| Functions |
|___________________________________________________________________________|
*/
/*___________________________________________________________________________
| |
| Function Name : saturate |
| |
| Purpose : |
| |
| Limit the 32 bit input to the range of a 16 bit word. |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!SATRUATE_IS_INLINE)
Word16 saturate(Word32 L_var1)
{
Word16 var_out;
if (L_var1 > 0X00007fffL)
{
var_out = MAX_16;
}
else if (L_var1 < (Word32) 0xffff8000L)
{
var_out = MIN_16;
}
else
{
var_out = extract_l(L_var1);
}
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : add |
| |
| Purpose : |
| |
| Performs the addition (var1+var2) with overflow control and saturation;|
| the 16 bit result is set at +32767 when overflow occurs or at -32768 |
| when underflow occurs. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!ADD_IS_INLINE)
Word16 add (Word16 var1, Word16 var2)
{
Word16 var_out;
Word32 L_sum;
L_sum = (Word32)var1 + (Word32)var2;
var_out = saturate(L_sum);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : sub |
| |
| Purpose : |
| |
| Performs the subtraction (var1+var2) with overflow control and satu- |
| ration; the 16 bit result is set at +32767 when overflow occurs or at |
| -32768 when underflow occurs. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!SUB_IS_INLINE)
Word16 sub(Word16 var1, Word16 var2)
{
Word16 var_out;
Word32 L_diff;
L_diff = (Word32) var1 - var2;
var_out = saturate(L_diff);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : abs_s |
| |
| Purpose : |
| |
| Absolute value of var1; abs_s(-32768) = 32767. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 0000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
//Word16 abs_s (Word16 var1)
//{
// Word16 var_out;
//
// if (var1 == MIN_16)
// {
// var_out = MAX_16;
// }
// else
// {
// if (var1 < 0)
// {
// var_out = (Word16)-var1;
// }
// else
// {
// var_out = var1;
// }
// }
//
// return (var_out);
//}
/*___________________________________________________________________________
| |
| Function Name : shl |
| |
| Purpose : |
| |
| Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
| the var2 LSB of the result. If var2 is negative, arithmetically shift |
| var1 right by -var2 with sign extension. Saturate the result in case of |
| underflows or overflows. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!SHL_IS_INLINE)
Word16 shl (Word16 var1, Word16 var2)
{
Word16 var_out;
Word32 result;
if (var2 < 0)
{
if (var2 < -16)
var2 = -16;
var_out = shr (var1, (Word16)-var2);
}
else
{
result = (Word32) var1 *((Word32) 1 << var2);
if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
{
//Overflow = 1;
var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
}
else
{
var_out = extract_l(result);
}
}
return (var_out);
}
#endif
// end
/*___________________________________________________________________________
| |
| Function Name : shr |
| |
| Purpose : |
| |
| Arithmetically shift the 16 bit input var1 right var2 positions with |
| sign extension. If var2 is negative, arithmetically shift var1 left by |
| -var2 with sign extension. Saturate the result in case of underflows or |
| overflows. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!SHR_IS_INLINE)
Word16 shr (Word16 var1, Word16 var2)
{
Word16 var_out;
if (var2 < 0)
{
if (var2 < -16)
var2 = -16;
var_out = shl (var1, (Word16)-var2);
}
else
{
if (var2 >= 15)
{
var_out = (Word16)((var1 < 0) ? -1 : 0);
}
else
{
if (var1 < 0)
{
var_out = (Word16)(~((~var1) >> var2));
}
else
{
var_out = (Word16)(var1 >> var2);
}
}
}
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : mult |
| |
| Purpose : |
| |
| Performs the multiplication of var1 by var2 and gives a 16 bit result |
| which is scaled i.e.: |
| mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and |
| mult(-32768,-32768) = 32767. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!MULT_IS_INLINE)
Word16 mult (Word16 var1, Word16 var2)
{
Word16 var_out;
Word32 L_product;
L_product = (Word32) var1 *(Word32) var2;
L_product = (L_product & (Word32) 0xffff8000L) >> 15;
if (L_product & (Word32) 0x00010000L)
L_product = L_product | (Word32) 0xffff0000L;
var_out = saturate(L_product);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_mult |
| |
| Purpose : |
| |
| L_mult is the 32 bit result of the multiplication of var1 times var2 |
| with one shift left i.e.: |
| L_mult(var1,var2) = L_shl((var1 times var2),1) and |
| L_mult(-32768,-32768) = 2147483647. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_MULT_IS_INLINE)
Word32 L_mult(Word16 var1, Word16 var2)
{
Word32 L_var_out;
L_var_out = (Word32) var1 *(Word32) var2;
if (L_var_out != (Word32) 0x40000000L)
{
L_var_out <<= 1;
}
else
{
L_var_out = MAX_32;
}
return (L_var_out);
}
#endif
// end
/*___________________________________________________________________________
| |
| Function Name : negate |
| |
| Purpose : |
| |
| Negate var1 with saturation, saturate in the case where input is -32768:|
| negate(var1) = sub(0,var1). |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
//Word16 negate (Word16 var1)
//{
// Word16 var_out;
//
// var_out = (Word16)((var1 == MIN_16) ? MAX_16 : -var1);
//
// return (var_out);
//}
/*___________________________________________________________________________
| |
| Function Name : extract_h |
| |
| Purpose : |
| |
| Return the 16 MSB of L_var1. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32 ) whose value falls in the |
| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!EXTRACT_H_IS_INLINE)
Word16 extract_h (Word32 L_var1)
{
Word16 var_out;
var_out = (Word16) (L_var1 >> 16);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : extract_l |
| |
| Purpose : |
| |
| Return the 16 LSB of L_var1. |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32 ) whose value falls in the |
| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!EXTRACT_L_IS_INLINE)
Word16 extract_l(Word32 L_var1)
{
Word16 var_out;
var_out = (Word16) L_var1;
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : round |
| |
| Purpose : |
| |
| Round the lower 16 bits of the 32 bit input number into the MS 16 bits |
| with saturation. Shift the resulting bits right by 16 and return the 16 |
| bit number: |
| round(L_var1) = extract_h(L_add(L_var1,32768)) |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32 ) whose value falls in the |
| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!ROUND_IS_INLINE)
Word16 round16(Word32 L_var1)
{
Word16 var_out;
Word32 L_rounded;
L_rounded = L_add (L_var1, (Word32) 0x00008000L);
var_out = extract_h (L_rounded);
return (var_out);
}
#endif
// end
/*___________________________________________________________________________
| |
| Function Name : L_mac |
| |
| Purpose : |
| |
| Multiply var1 by var2 and shift the result left by 1. Add the 32 bit |
| result to L_var3 with saturation, return a 32 bit result: |
| L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)). |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| L_var3 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_MSU_IS_INLINE)
Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
{
Word32 L_var_out;
Word32 L_product;
L_product = L_mult(var1, var2);
L_var_out = L_add (L_var3, L_product);
return (L_var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_msu |
| |
| Purpose : |
| |
| Multiply var1 by var2 and shift the result left by 1. Subtract the 32 |
| bit result to L_var3 with saturation, return a 32 bit result: |
| L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)). |
| |
| Complexity weight : 1 |
| |
| Inputs : |
| |
| L_var3 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_MSU_IS_INLINE)
Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
{
Word32 L_var_out;
Word32 L_product;
L_product = L_mult(var1, var2);
L_var_out = L_sub (L_var3, L_product);
return (L_var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_add |
| |
| Purpose : |
| |
| 32 bits addition of the two 32 bits variables (L_var1+L_var2) with |
| overflow control and saturation; the result is set at +2147483647 when |
| overflow occurs or at -2147483648 when underflow occurs. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var1 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| L_var2 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_ADD_IS_INLINE)
Word32 L_add (Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
L_var_out = L_var1 + L_var2;
if (((L_var1 ^ L_var2) & MIN_32) == 0)
{
if ((L_var_out ^ L_var1) & MIN_32)
{
L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
//Overflow = 1;
}
}
return (L_var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_sub |
| |
| Purpose : |
| |
| 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with |
| overflow control and saturation; the result is set at +2147483647 when |
| overflow occurs or at -2147483648 when underflow occurs. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var1 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| L_var2 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_SUB_IS_INLINE)
Word32 L_sub(Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
L_var_out = L_var1 - L_var2;
if (((L_var1 ^ L_var2) & MIN_32) != 0)
{
if ((L_var_out ^ L_var1) & MIN_32)
{
L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
//Overflow = 1;
}
}
return (L_var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_negate |
| |
| Purpose : |
| |
| Negate the 32 bit variable L_var1 with saturation; saturate in the case |
| where input is -2147483648 (0x8000 0000). |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var1 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
//Word32 L_negate (Word32 L_var1)
//{
// Word32 L_var_out;
//
// L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
//
// return (L_var_out);
//}
/*___________________________________________________________________________
| |
| Function Name : mult_r |
| |
| Purpose : |
| |
| Same as mult with rounding, i.e.: |
| mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and |
| mult_r(-32768,-32768) = 32767. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!MULT_R_IS_INLINE)
Word16 mult_r (Word16 var1, Word16 var2)
{
Word16 var_out;
Word32 L_product_arr;
L_product_arr = (Word32) var1 *(Word32) var2; /* product */
L_product_arr += (Word32) 0x00004000L; /* round */
L_product_arr &= (Word32) 0xffff8000L;
L_product_arr >>= 15; /* shift */
if (L_product_arr & (Word32) 0x00010000L) /* sign extend when necessary */
{
L_product_arr |= (Word32) 0xffff0000L;
}
var_out = saturate(L_product_arr);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_shl |
| |
| Purpose : |
| |
| Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero |
| fill the var2 LSB of the result. If var2 is negative, arithmetically |
| shift L_var1 right by -var2 with sign extension. Saturate the result in |
| case of underflows or overflows. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var1 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_SHL_IS_INLINE)
Word32 L_shl (Word32 L_var1, Word16 var2)
{
Word32 L_var_out = 0L;
if (var2 <= 0)
{
L_var1 = L_shr(L_var1, (Word16)-var2);
}
else
{
for (; var2 > 0; var2--)
{
if (L_var1 > (Word32) 0X3fffffffL)
{
return MAX_32;
}
else
{
if (L_var1 < (Word32) 0xc0000000L)
{
return MIN_32;
}
}
L_var1 <<= 1;
}
}
return (L_var1);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_shr |
| |
| Purpose : |
| |
| Arithmetically shift the 32 bit input L_var1 right var2 positions with |
| sign extension. If var2 is negative, arithmetically shift L_var1 left |
| by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
| in case of underflows or overflows. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var1 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_SHR_IS_INLINE)
Word32 L_shr (Word32 L_var1, Word16 var2)
{
Word32 L_var_out;
if (var2 < 0)
{
L_var_out = L_shl (L_var1, (Word16)-var2);
}
else
{
if (var2 >= 31)
{
L_var_out = (L_var1 < 0L) ? -1 : 0;
}
else
{
if (L_var1 < 0)
{
L_var_out = ~((~L_var1) >> var2);
}
else
{
L_var_out = L_var1 >> var2;
}
}
}
return (L_var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : shr_r |
| |
| Purpose : |
| |
| Same as shr(var1,var2) but with rounding. Saturate the result in case of|
| underflows or overflows : |
| - If var2 is greater than zero : |
| if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1)))) |
| is equal to zero |
| then |
| shr_r(var1,var2) = shr(var1,var2) |
| else |
| shr_r(var1,var2) = add(shr(var1,var2),1) |
| - If var2 is less than or equal to zero : |
| shr_r(var1,var2) = shr(var1,var2). |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!SHR_R_IS_INLINE)
Word16 shr_r (Word16 var1, Word16 var2)
{
Word16 var_out;
if (var2 > 15)
{
var_out = 0;
}
else
{
var_out = shr (var1, var2);
if (var2 > 0)
{
if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
{
var_out++;
}
}
}
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : mac_r |
| |
| Purpose : |
| |
| Multiply var1 by var2 and shift the result left by 1. Add the 32 bit |
| result to L_var3 with saturation. Round the LS 16 bits of the result |
| into the MS 16 bits with saturation and shift the result right by 16. |
| Return a 16 bit result. |
| mac_r(L_var3,var1,var2) = round(L_mac(L_var3,var1,var2)) |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var3 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!MAC_R_IS_INLINE)
Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
{
Word16 var_out;
L_var3 = L_mac (L_var3, var1, var2);
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
var_out = extract_h (L_var3);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : msu_r |
| |
| Purpose : |
| |
| Multiply var1 by var2 and shift the result left by 1. Subtract the 32 |
| bit result to L_var3 with saturation. Round the LS 16 bits of the res- |
| ult into the MS 16 bits with saturation and shift the result right by |
| 16. Return a 16 bit result. |
| msu_r(L_var3,var1,var2) = round(L_msu(L_var3,var1,var2)) |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| L_var3 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
#if (!MSU_R_IS_INLINE)
Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
{
Word16 var_out;
L_var3 = L_msu (L_var3, var1, var2);
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
var_out = extract_h (L_var3);
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_deposit_h |
| |
| Purpose : |
| |
| Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The |
| 16 LS bits of the output are zeroed. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= var_out <= 0x7fff 0000. |
|___________________________________________________________________________|
*/
//Word32 L_deposit_h (Word16 var1)
//{
// Word32 L_var_out;
//
// L_var_out = (Word32) var1 << 16;
//
// return (L_var_out);
//}
/*___________________________________________________________________________
| |
| Function Name : L_deposit_l |
| |
| Purpose : |
| |
| Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The |
| 16 MS bits of the output are sign extended. |
| |
| Complexity weight : 2 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. |
|___________________________________________________________________________|
*/
//Word32 L_deposit_l (Word16 var1)
//{
// Word32 L_var_out;
//
// L_var_out = (Word32) var1;
//
// return (L_var_out);
//}
/*___________________________________________________________________________
| |
| Function Name : L_shr_r |
| |
| Purpose : |
| |
| Same as L_shr(L_var1,var2) but with rounding. Saturate the result in |
| case of underflows or overflows : |
| - If var2 is greater than zero : |
| if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
| is equal to zero |
| then |
| L_shr_r(L_var1,var2) = L_shr(L_var1,var2) |
| else |
| L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1) |
| - If var2 is less than or equal to zero : |
| L_shr_r(L_var1,var2) = L_shr(L_var1,var2). |
| |
| Complexity weight : 3 |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
#if (!L_SHR_R_IS_INLINE)
Word32 L_shr_r (Word32 L_var1, Word16 var2)
{
Word32 L_var_out;
if (var2 > 31)
{
L_var_out = 0;
}
else
{
L_var_out = L_shr (L_var1, var2);
if (var2 > 0)
{
if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
{
L_var_out++;
}
}
}
return (L_var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : L_abs |
| |
| Purpose : |
| |
| Absolute value of L_var1; Saturate in case where the input is |
| -214783648 |
| |
| Complexity weight : 3 |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| L_var_out |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x0000 0000 <= var_out <= 0x7fff ffff. |
|___________________________________________________________________________|
*/
//Word32 L_abs (Word32 L_var1)
//{
// Word32 L_var_out;
//
// if (L_var1 == MIN_32)
// {
// L_var_out = MAX_32;
// }
// else
// {
// if (L_var1 < 0)
// {
// L_var_out = -L_var1;
// }
// else
// {
// L_var_out = L_var1;
// }
// }
//
// return (L_var_out);
//}
/*___________________________________________________________________________
| |
| Function Name : norm_s |
| |
| Purpose : |
| |
| Produces the number of left shift needed to normalize the 16 bit varia- |
| ble var1 for positive values on the interval with minimum of 16384 and |
| maximum of 32767, and for negative values on the interval with minimum |
| of -32768 and maximum of -16384; in order to normalize the result, the |
| following operation must be done : |
| norm_var1 = shl(var1,norm_s(var1)). |
| |
| Complexity weight : 15 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 0000 <= var_out <= 0x0000 000f. |
|___________________________________________________________________________|
*/
#if (!NORM_S_IS_INLINE)
Word16 norm_s (Word16 var1)
{
Word16 var_out;
if (var1 == 0)
{
var_out = 0;
}
else
{
if (var1 == -1)
{
var_out = 15;
}
else
{
if (var1 < 0)
{
var1 = (Word16)~var1;
}
for (var_out = 0; var1 < 0x4000; var_out++)
{
var1 <<= 1;
}
}
}
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : div_s |
| |
| Purpose : |
| |
| Produces a result which is the fractional integer division of var1 by |
| var2; var1 and var2 must be positive and var2 must be greater or equal |
| to var1; the result is positive (leading bit equal to 0) and truncated |
| to 16 bits. |
| If var1 = var2 then div(var1,var2) = 32767. |
| |
| Complexity weight : 18 |
| |
| Inputs : |
| |
| var1 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 0000 <= var1 <= var2 and var2 != 0. |
| |
| var2 |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : var1 <= var2 <= 0x0000 7fff and var2 != 0. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 0000 <= var_out <= 0x0000 7fff. |
| It's a Q15 value (point between b15 and b14). |
|___________________________________________________________________________|
*/
#if (!DIV_S_IS_INLINE)
Word16 div_s (Word16 var1, Word16 var2)
{
Word16 var_out = 0;
Word16 iteration;
Word32 L_num;
Word32 L_denom;
if (var1 == 0)
{
var_out = 0;
}
else
{
if (var1 == var2)
{
var_out = MAX_16;
}
else
{
L_num = L_deposit_l (var1);
L_denom = L_deposit_l (var2);
for (iteration = 0; iteration < 15; iteration++)
{
var_out <<= 1;
L_num <<= 1;
if (L_num >= L_denom)
{
L_num = L_sub(L_num, L_denom);
var_out = add (var_out, 1);
}
}
}
}
return (var_out);
}
#endif
/*___________________________________________________________________________
| |
| Function Name : norm_l |
| |
| Purpose : |
| |
| Produces the number of left shifts needed to normalize the 32 bit varia-|
| ble L_var1 for positive values on the interval with minimum of |
| 1073741824 and maximum of 2147483647, and for negative values on the in-|
| terval with minimum of -2147483648 and maximum of -1073741824; in order |
| to normalize the result, the following operation must be done : |
| norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). |
| |
| Complexity weight : 30 |
| |
| Inputs : |
| |
| L_var1 |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
| |
| Outputs : |
| |
| none |
| |
| Return Value : |
| |
| var_out |
| 16 bit short signed integer (Word16) whose value falls in the |
| range : 0x0000 0000 <= var_out <= 0x0000 001f. |
|___________________________________________________________________________|
*/
#if (!NORM_L_IS_INLINE)
Word16 norm_l (Word32 L_var1)
{
Word16 var_out;
if (L_var1 == 0)
{
var_out = 0;
}
else
{
if (L_var1 == (Word32) 0xffffffffL)
{
var_out = 31;
}
else
{
if (L_var1 < 0)
{
L_var1 = ~L_var1;
}
for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
{
L_var1 <<= 1;
}
}
}
return (var_out);
}
#endif

885
aacenc/external/aacenc/src/bit_cnt.c vendored Normal file
View file

@ -0,0 +1,885 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: bit_cnt.c
Content: Huffman Bitcounter & coder functions
*******************************************************************************/
#include "bit_cnt.h"
#include "aac_rom.h"
#define HI_LTAB(a) (a>>8)
#define LO_LTAB(a) (a & 0xff)
#define EXPAND(a) ((((Word32)(a&0xff00)) << 8)|(Word32)(a&0xff))
/*****************************************************************************
*
* function name: count1_2_3_4_5_6_7_8_9_10_11
* description: counts tables 1-11
* returns:
* input: quantized spectrum
* output: bitCount for tables 1-11
*
*****************************************************************************/
static void count1_2_3_4_5_6_7_8_9_10_11(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1,t2,t3,i;
Word32 bc1_2,bc3_4,bc5_6,bc7_8,bc9_10;
Word16 bc11,sc;
bc1_2=0;
bc3_4=0;
bc5_6=0;
bc7_8=0;
bc9_10=0;
bc11=0;
sc=0;
for(i=0;i<width;i+=4){
t0= values[i+0];
t1= values[i+1];
t2= values[i+2];
t3= values[i+3];
/* 1,2 */
bc1_2 = bc1_2 + EXPAND(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
/* 5,6 */
bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);
t0=ABS(t0);
t1=ABS(t1);
t2=ABS(t2);
t3=ABS(t3);
bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);
bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);
bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);
bc11 = bc11 + huff_ltab11[t0][t1];
bc11 = bc11 + huff_ltab11[t2][t3];
sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);
}
bitCount[1]=extract_h(bc1_2);
bitCount[2]=extract_l(bc1_2);
bitCount[3]=extract_h(bc3_4) + sc;
bitCount[4]=extract_l(bc3_4) + sc;
bitCount[5]=extract_h(bc5_6);
bitCount[6]=extract_l(bc5_6);
bitCount[7]=extract_h(bc7_8) + sc;
bitCount[8]=extract_l(bc7_8) + sc;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: count3_4_5_6_7_8_9_10_11
* description: counts tables 3-11
* returns:
* input: quantized spectrum
* output: bitCount for tables 3-11
*
*****************************************************************************/
static void count3_4_5_6_7_8_9_10_11(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1,t2,t3, i;
Word32 bc3_4,bc5_6,bc7_8,bc9_10;
Word16 bc11,sc;
bc3_4=0;
bc5_6=0;
bc7_8=0;
bc9_10=0;
bc11=0;
sc=0;
for(i=0;i<width;i+=4){
t0= values[i+0];
t1= values[i+1];
t2= values[i+2];
t3= values[i+3];
/*
5,6
*/
bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);
t0=ABS(t0);
t1=ABS(t1);
t2=ABS(t2);
t3=ABS(t3);
bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);
bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);
bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);
bc11 = bc11 + huff_ltab11[t0][t1];
bc11 = bc11 + huff_ltab11[t2][t3];
sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);
}
bitCount[1]=INVALID_BITCOUNT;
bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=extract_h(bc3_4) + sc;
bitCount[4]=extract_l(bc3_4) + sc;
bitCount[5]=extract_h(bc5_6);
bitCount[6]=extract_l(bc5_6);
bitCount[7]=extract_h(bc7_8) + sc;
bitCount[8]=extract_l(bc7_8) + sc;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: count5_6_7_8_9_10_11
* description: counts tables 5-11
* returns:
* input: quantized spectrum
* output: bitCount for tables 5-11
*
*****************************************************************************/
static void count5_6_7_8_9_10_11(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1,i;
Word32 bc5_6,bc7_8,bc9_10;
Word16 bc11,sc;
bc5_6=0;
bc7_8=0;
bc9_10=0;
bc11=0;
sc=0;
for(i=0;i<width;i+=2){
t0 = values[i+0];
t1 = values[i+1];
bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);
t0=ABS(t0);
t1=ABS(t1);
bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
bc11 = bc11 + huff_ltab11[t0][t1];
sc = sc + (t0>0) + (t1>0);
}
bitCount[1]=INVALID_BITCOUNT;
bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=INVALID_BITCOUNT;
bitCount[4]=INVALID_BITCOUNT;
bitCount[5]=extract_h(bc5_6);
bitCount[6]=extract_l(bc5_6);
bitCount[7]=extract_h(bc7_8) + sc;
bitCount[8]=extract_l(bc7_8) + sc;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: count7_8_9_10_11
* description: counts tables 7-11
* returns:
* input: quantized spectrum
* output: bitCount for tables 7-11
*
*****************************************************************************/
static void count7_8_9_10_11(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1, i;
Word32 bc7_8,bc9_10;
Word16 bc11,sc;
bc7_8=0;
bc9_10=0;
bc11=0;
sc=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);
bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);
bc11 = bc11 + huff_ltab11[t0][t1];
sc = sc + (t0>0) + (t1>0);
}
bitCount[1]=INVALID_BITCOUNT;
bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=INVALID_BITCOUNT;
bitCount[4]=INVALID_BITCOUNT;
bitCount[5]=INVALID_BITCOUNT;
bitCount[6]=INVALID_BITCOUNT;
bitCount[7]=extract_h(bc7_8) + sc;
bitCount[8]=extract_l(bc7_8) + sc;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: count9_10_11
* description: counts tables 9-11
* returns:
* input: quantized spectrum
* output: bitCount for tables 9-11
*
*****************************************************************************/
static void count9_10_11(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1,i;
Word32 bc9_10;
Word16 bc11,sc;
bc9_10=0;
bc11=0;
sc=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
bc9_10 += EXPAND(huff_ltab9_10[t0][t1]);
bc11 = bc11 + huff_ltab11[t0][t1];
sc = sc + (t0>0) + (t1>0);
}
bitCount[1]=INVALID_BITCOUNT;
bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=INVALID_BITCOUNT;
bitCount[4]=INVALID_BITCOUNT;
bitCount[5]=INVALID_BITCOUNT;
bitCount[6]=INVALID_BITCOUNT;
bitCount[7]=INVALID_BITCOUNT;
bitCount[8]=INVALID_BITCOUNT;
bitCount[9]=extract_h(bc9_10) + sc;
bitCount[10]=extract_l(bc9_10) + sc;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: count11
* description: counts table 11
* returns:
* input: quantized spectrum
* output: bitCount for table 11
*
*****************************************************************************/
static void count11(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1,i;
Word16 bc11,sc;
bc11=0;
sc=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
bc11 = bc11 + huff_ltab11[t0][t1];
sc = sc + (t0>0) + (t1>0);
}
bitCount[1]=INVALID_BITCOUNT;
bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=INVALID_BITCOUNT;
bitCount[4]=INVALID_BITCOUNT;
bitCount[5]=INVALID_BITCOUNT;
bitCount[6]=INVALID_BITCOUNT;
bitCount[7]=INVALID_BITCOUNT;
bitCount[8]=INVALID_BITCOUNT;
bitCount[9]=INVALID_BITCOUNT;
bitCount[10]=INVALID_BITCOUNT;
bitCount[11]=bc11 + sc;
}
/*****************************************************************************
*
* function name: countEsc
* description: counts table 11 (with Esc)
* returns:
* input: quantized spectrum
* output: bitCount for tables 11 (with Esc)
*
*****************************************************************************/
static void countEsc(const Word16 *values,
const Word16 width,
Word16 *bitCount)
{
Word32 t0,t1,t00,t01,i;
Word16 bc11,ec,sc;
bc11=0;
sc=0;
ec=0;
for(i=0;i<width;i+=2){
t0=ABS(values[i+0]);
t1=ABS(values[i+1]);
sc = sc + (t0>0) + (t1>0);
t00 = min(t0,16);
t01 = min(t1,16);
bc11 = bc11 + huff_ltab11[t00][t01];
if(t0 >= 16){
ec = ec + 5;
while(sub(t0=(t0 >> 1), 16) >= 0) {
ec = ec + 2;
}
}
if(t1 >= 16){
ec = ec + 5;
while(sub(t1=(t1 >> 1), 16) >= 0) {
ec = ec + 2;
}
}
}
bitCount[1]=INVALID_BITCOUNT;
bitCount[2]=INVALID_BITCOUNT;
bitCount[3]=INVALID_BITCOUNT;
bitCount[4]=INVALID_BITCOUNT;
bitCount[5]=INVALID_BITCOUNT;
bitCount[6]=INVALID_BITCOUNT;
bitCount[7]=INVALID_BITCOUNT;
bitCount[8]=INVALID_BITCOUNT;
bitCount[9]=INVALID_BITCOUNT;
bitCount[10]=INVALID_BITCOUNT;
bitCount[11]=bc11 + sc + ec;
}
typedef void (*COUNT_FUNCTION)(const Word16 *values,
const Word16 width,
Word16 *bitCount);
static COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV+1] =
{
count1_2_3_4_5_6_7_8_9_10_11, /* 0 */
count1_2_3_4_5_6_7_8_9_10_11, /* 1 */
count3_4_5_6_7_8_9_10_11, /* 2 */
count5_6_7_8_9_10_11, /* 3 */
count5_6_7_8_9_10_11, /* 4 */
count7_8_9_10_11, /* 5 */
count7_8_9_10_11, /* 6 */
count7_8_9_10_11, /* 7 */
count9_10_11, /* 8 */
count9_10_11, /* 9 */
count9_10_11, /* 10 */
count9_10_11, /* 11 */
count9_10_11, /* 12 */
count11, /* 13 */
count11, /* 14 */
count11, /* 15 */
countEsc /* 16 */
};
/*****************************************************************************
*
* function name: bitCount
* description: count bits
*
*****************************************************************************/
Word16 bitCount(const Word16 *values,
const Word16 width,
Word16 maxVal,
Word16 *bitCount)
{
/*
check if we can use codebook 0
*/
if(maxVal == 0)
bitCount[0] = 0;
else
bitCount[0] = INVALID_BITCOUNT;
maxVal = min(maxVal, CODE_BOOK_ESC_LAV);
countFuncTable[maxVal](values,width,bitCount);
return(0);
}
/*****************************************************************************
*
* function name: codeValues
* description: write huffum bits
*
*****************************************************************************/
Word16 codeValues(Word16 *values, Word16 width, Word16 codeBook, HANDLE_BIT_BUF hBitstream)
{
Word32 i, t0, t1, t2, t3, t00, t01;
UWord16 codeWord, codeLength;
Word16 sign, signLength;
switch (codeBook) {
case CODE_BOOK_ZERO_NO:
break;
case CODE_BOOK_1_NO:
for(i=0; i<width; i+=4) {
t0 = values[i+0];
t1 = values[i+1];
t2 = values[i+2];
t3 = values[i+3];
codeWord = huff_ctab1[t0+1][t1+1][t2+1][t3+1];
codeLength = HI_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
WriteBits(hBitstream, codeWord, codeLength);
}
break;
case CODE_BOOK_2_NO:
for(i=0; i<width; i+=4) {
t0 = values[i+0];
t1 = values[i+1];
t2 = values[i+2];
t3 = values[i+3];
codeWord = huff_ctab2[t0+1][t1+1][t2+1][t3+1];
codeLength = LO_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);
WriteBits(hBitstream,codeWord,codeLength);
}
break;
case CODE_BOOK_3_NO:
for(i=0; i<width; i+=4) {
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
t2 = values[i+2];
if(t2 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t2 < 0){
sign|=1;
t2=-t2;
}
}
t3 = values[i+3];
if(t3 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t3 < 0){
sign|=1;
t3=-t3;
}
}
codeWord = huff_ctab3[t0][t1][t2][t3];
codeLength = HI_LTAB(huff_ltab3_4[t0][t1][t2][t3]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
break;
case CODE_BOOK_4_NO:
for(i=0; i<width; i+=4) {
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
t2 = values[i+2];
if(t2 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t2 < 0){
sign|=1;
t2=-t2;
}
}
t3 = values[i+3];
if(t3 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t3 < 0){
sign|=1;
t3=-t3;
}
}
codeWord = huff_ctab4[t0][t1][t2][t3];
codeLength = LO_LTAB(huff_ltab3_4[t0][t1][t2][t3]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
break;
case CODE_BOOK_5_NO:
for(i=0; i<width; i+=2) {
t0 = values[i+0];
t1 = values[i+1];
codeWord = huff_ctab5[t0+4][t1+4];
codeLength = HI_LTAB(huff_ltab5_6[t0+4][t1+4]);
WriteBits(hBitstream,codeWord,codeLength);
}
break;
case CODE_BOOK_6_NO:
for(i=0; i<width; i+=2) {
t0 = values[i+0];
t1 = values[i+1];
codeWord = huff_ctab6[t0+4][t1+4];
codeLength = LO_LTAB(huff_ltab5_6[t0+4][t1+4]);
WriteBits(hBitstream,codeWord,codeLength);
}
break;
case CODE_BOOK_7_NO:
for(i=0; i<width; i+=2){
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
codeWord = huff_ctab7[t0][t1];
codeLength = HI_LTAB(huff_ltab7_8[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
break;
case CODE_BOOK_8_NO:
for(i=0; i<width; i+=2) {
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
codeWord = huff_ctab8[t0][t1];
codeLength = LO_LTAB(huff_ltab7_8[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
break;
case CODE_BOOK_9_NO:
for(i=0; i<width; i+=2) {
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
codeWord = huff_ctab9[t0][t1];
codeLength = HI_LTAB(huff_ltab9_10[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
break;
case CODE_BOOK_10_NO:
for(i=0; i<width; i+=2) {
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
codeWord = huff_ctab10[t0][t1];
codeLength = LO_LTAB(huff_ltab9_10[t0][t1]);
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
}
break;
case CODE_BOOK_ESC_NO:
for(i=0; i<width; i+=2) {
sign=0;
signLength=0;
t0 = values[i+0];
if(t0 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t0 < 0){
sign|=1;
t0=-t0;
}
}
t1 = values[i+1];
if(t1 != 0){
signLength = signLength + 1;
sign = sign << 1;
if(t1 < 0){
sign|=1;
t1=-t1;
}
}
t00 = min(t0,16);
t01 = min(t1,16);
codeWord = huff_ctab11[t00][t01];
codeLength = huff_ltab11[t00][t01];
WriteBits(hBitstream,codeWord,codeLength);
WriteBits(hBitstream,sign,signLength);
if(t0 >= 16){
Word16 n, p;
n=0;
p=t0;
while(sub(p=(p >> 1), 16) >= 0){
WriteBits(hBitstream,1,1);
n = n + 1;
}
WriteBits(hBitstream,0,1);
n = n + 4;
WriteBits(hBitstream,(t0 - (1 << n)),n);
}
if(t1 >= 16){
Word16 n, p;
n=0;
p=t1;
while(sub(p=(p >> 1), 16) >= 0){
WriteBits(hBitstream,1,1);
n = n + 1;
}
WriteBits(hBitstream,0,1);
n = n + 4;
WriteBits(hBitstream,(t1 - (1 << n)),n);
}
}
break;
default:
break;
}
return(0);
}
Word16 bitCountScalefactorDelta(Word16 delta)
{
return(huff_ltabscf[delta+CODE_BOOK_SCF_LAV]);
}
Word16 codeScalefactorDelta(Word16 delta, HANDLE_BIT_BUF hBitstream)
{
Word32 codeWord;
Word16 codeLength;
if(delta > CODE_BOOK_SCF_LAV || delta < -CODE_BOOK_SCF_LAV)
return(1);
codeWord = huff_ctabscf[delta + CODE_BOOK_SCF_LAV];
codeLength = huff_ltabscf[delta + CODE_BOOK_SCF_LAV];
WriteBits(hBitstream,codeWord,codeLength);
return(0);
}

106
aacenc/external/aacenc/src/bit_cnt.h vendored Normal file
View file

@ -0,0 +1,106 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: bit_cnt.h
Content: Huffman Bitcounter & coder structure and functions
*******************************************************************************/
#ifndef __BITCOUNT_H
#define __BITCOUNT_H
#include "bitbuffer.h"
#include "basic_op.h"
#define INVALID_BITCOUNT (MAX_16/4)
/*
code book number table
*/
enum codeBookNo{
CODE_BOOK_ZERO_NO= 0,
CODE_BOOK_1_NO= 1,
CODE_BOOK_2_NO= 2,
CODE_BOOK_3_NO= 3,
CODE_BOOK_4_NO= 4,
CODE_BOOK_5_NO= 5,
CODE_BOOK_6_NO= 6,
CODE_BOOK_7_NO= 7,
CODE_BOOK_8_NO= 8,
CODE_BOOK_9_NO= 9,
CODE_BOOK_10_NO= 10,
CODE_BOOK_ESC_NO= 11,
CODE_BOOK_RES_NO= 12,
CODE_BOOK_PNS_NO= 13
};
/*
code book index table
*/
enum codeBookNdx{
CODE_BOOK_ZERO_NDX=0,
CODE_BOOK_1_NDX,
CODE_BOOK_2_NDX,
CODE_BOOK_3_NDX,
CODE_BOOK_4_NDX,
CODE_BOOK_5_NDX,
CODE_BOOK_6_NDX,
CODE_BOOK_7_NDX,
CODE_BOOK_8_NDX,
CODE_BOOK_9_NDX,
CODE_BOOK_10_NDX,
CODE_BOOK_ESC_NDX,
CODE_BOOK_RES_NDX,
CODE_BOOK_PNS_NDX,
NUMBER_OF_CODE_BOOKS
};
/*
code book lav table
*/
enum codeBookLav{
CODE_BOOK_ZERO_LAV=0,
CODE_BOOK_1_LAV=1,
CODE_BOOK_2_LAV=1,
CODE_BOOK_3_LAV=2,
CODE_BOOK_4_LAV=2,
CODE_BOOK_5_LAV=4,
CODE_BOOK_6_LAV=4,
CODE_BOOK_7_LAV=7,
CODE_BOOK_8_LAV=7,
CODE_BOOK_9_LAV=12,
CODE_BOOK_10_LAV=12,
CODE_BOOK_ESC_LAV=16,
CODE_BOOK_SCF_LAV=60,
CODE_BOOK_PNS_LAV=60
};
Word16 bitCount(const Word16 *aQuantSpectrum,
const Word16 noOfSpecLines,
Word16 maxVal,
Word16 *bitCountLut);
Word16 codeValues(Word16 *values, Word16 width, Word16 codeBook, HANDLE_BIT_BUF hBitstream);
Word16 bitCountScalefactorDelta(Word16 delta);
Word16 codeScalefactorDelta(Word16 scalefactor, HANDLE_BIT_BUF hBitstream);
#endif

150
aacenc/external/aacenc/src/bitbuffer.c vendored Normal file
View file

@ -0,0 +1,150 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: bitbuffer.c
Content: Bit Buffer Management functions
*******************************************************************************/
#include "bitbuffer.h"
/*****************************************************************************
*
* function name: CreateBitBuffer
* description: create and init Bit Buffer Management
*
*****************************************************************************/
HANDLE_BIT_BUF CreateBitBuffer(HANDLE_BIT_BUF hBitBuf,
UWord8 *pBitBufBase,
Word16 bitBufSize)
{
assert(bitBufSize*8 <= 32768);
hBitBuf->pBitBufBase = pBitBufBase;
hBitBuf->pBitBufEnd = pBitBufBase + bitBufSize - 1;
hBitBuf->pWriteNext = pBitBufBase;
hBitBuf->cache = 0;
hBitBuf->wBitPos = 0;
hBitBuf->cntBits = 0;
hBitBuf->size = (bitBufSize << 3);
hBitBuf->isValid = 1;
return hBitBuf;
}
/*****************************************************************************
*
* function name: DeleteBitBuffer
* description: uninit Bit Buffer Management
*
*****************************************************************************/
void DeleteBitBuffer(HANDLE_BIT_BUF *hBitBuf)
{
if(*hBitBuf)
(*hBitBuf)->isValid = 0;
*hBitBuf = NULL;
}
/*****************************************************************************
*
* function name: ResetBitBuf
* description: reset Bit Buffer Management
*
*****************************************************************************/
void ResetBitBuf(HANDLE_BIT_BUF hBitBuf,
UWord8 *pBitBufBase,
Word16 bitBufSize)
{
hBitBuf->pBitBufBase = pBitBufBase;
hBitBuf->pBitBufEnd = pBitBufBase + bitBufSize - 1;
hBitBuf->pWriteNext = pBitBufBase;
hBitBuf->wBitPos = 0;
hBitBuf->cntBits = 0;
hBitBuf->cache = 0;
}
/*****************************************************************************
*
* function name: CopyBitBuf
* description: copy Bit Buffer Management
*
*****************************************************************************/
void CopyBitBuf(HANDLE_BIT_BUF hBitBufSrc,
HANDLE_BIT_BUF hBitBufDst)
{
*hBitBufDst = *hBitBufSrc;
}
/*****************************************************************************
*
* function name: GetBitsAvail
* description: get available bits
*
*****************************************************************************/
Word16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf)
{
return hBitBuf->cntBits;
}
/*****************************************************************************
*
* function name: WriteBits
* description: write bits to the buffer
*
*****************************************************************************/
Word16 WriteBits(HANDLE_BIT_BUF hBitBuf,
UWord32 writeValue,
Word16 noBitsToWrite)
{
Word16 wBitPos;
assert(noBitsToWrite <= (Word16)sizeof(Word32)*8);
if(noBitsToWrite == 0)
return noBitsToWrite;
hBitBuf->cntBits += noBitsToWrite;
wBitPos = hBitBuf->wBitPos;
wBitPos += noBitsToWrite;
writeValue &= ~(0xffffffff << noBitsToWrite); // Mask out everything except the lowest noBitsToWrite bits
writeValue <<= 32 - wBitPos;
writeValue |= hBitBuf->cache;
while (wBitPos >= 8)
{
UWord8 tmp;
tmp = (UWord8)((writeValue >> 24) & 0xFF);
*hBitBuf->pWriteNext++ = tmp;
writeValue <<= 8;
wBitPos -= 8;
}
hBitBuf->wBitPos = wBitPos;
hBitBuf->cache = writeValue;
return noBitsToWrite;
}

89
aacenc/external/aacenc/src/bitbuffer.h vendored Normal file
View file

@ -0,0 +1,89 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: bitbuffer.h
Content: Bit Buffer Management structure and functions
*******************************************************************************/
#ifndef BITBUFFER_H
#define BITBUFFER_H
#include "typedef.h"
enum direction
{
forwardDirection,
backwardDirection
};
/*!
The pointer 'pReadNext' points to the next available word, where bits can be read from. The pointer
'pWriteNext' points to the next available word, where bits can be written to. The pointer pBitBufBase
points to the start of the bitstream buffer and the pointer pBitBufEnd points to the end of the bitstream
buffer. The two pointers are used as lower-bound respectively upper-bound address for the modulo addressing
mode.
The element cntBits contains the currently available bits in the bit buffer. It will be incremented when
bits are written to the bitstream buffer and decremented when bits are read from the bitstream buffer.
*/
struct BIT_BUF
{
UWord8 *pBitBufBase; /*!< pointer points to first position in bitstream buffer */
UWord8 *pBitBufEnd; /*!< pointer points to last position in bitstream buffer */
UWord8 *pWriteNext; /*!< pointer points to next available word in bitstream buffer to write */
UWord32 cache;
Word16 wBitPos; /*!< 31<=wBitPos<=0*/
Word16 cntBits; /*!< number of available bits in the bitstream buffer
write bits to bitstream buffer => increment cntBits
read bits from bitstream buffer => decrement cntBits */
Word16 size; /*!< size of bitbuffer in bits */
Word16 isValid; /*!< indicates whether the instance has been initialized */
}; /* size Word16: 8 */
/*! Define pointer to bit buffer structure */
typedef struct BIT_BUF *HANDLE_BIT_BUF;
HANDLE_BIT_BUF CreateBitBuffer(HANDLE_BIT_BUF hBitBuf,
UWord8 *pBitBufBase,
Word16 bitBufSize);
void DeleteBitBuffer(HANDLE_BIT_BUF *hBitBuf);
Word16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf);
Word16 WriteBits(HANDLE_BIT_BUF hBitBuf,
UWord32 writeValue,
Word16 noBitsToWrite);
void ResetBitBuf(HANDLE_BIT_BUF hBitBuf,
UWord8 *pBitBufBase,
Word16 bitBufSize);
#define GetNrBitsAvailable(hBitBuf) ( (hBitBuf)->cntBits)
#define GetNrBitsRead(hBitBuf) ((hBitBuf)->size-(hBitBuf)->cntBits)
#endif /* BITBUFFER_H */

693
aacenc/external/aacenc/src/bitenc.c vendored Normal file
View file

@ -0,0 +1,693 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: bitenc.c
Content: Bitstream encoder functions
*******************************************************************************/
#include "bitenc.h"
#include "bit_cnt.h"
#include "dyn_bits.h"
#include "qc_data.h"
#include "interface.h"
#define UNUSED(x) (void)(x)
static const Word16 globalGainOffset = 100;
static const Word16 icsReservedBit = 0;
/*****************************************************************************
*
* function name: encodeSpectralData
* description: encode spectral data
* returns: spectral bits used
*
*****************************************************************************/
static Word32 encodeSpectralData(Word16 *sfbOffset,
SECTION_DATA *sectionData,
Word16 *quantSpectrum,
HANDLE_BIT_BUF hBitStream)
{
Word16 i,sfb;
Word16 dbgVal;
SECTION_INFO* psectioninfo;
dbgVal = GetBitsAvail(hBitStream);
for(i=0; i<sectionData->noOfSections; i++) {
psectioninfo = &(sectionData->sectionInfo[i]);
/*
huffencode spectral data for this section
*/
for(sfb=psectioninfo->sfbStart;
sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;
sfb++) {
codeValues(quantSpectrum+sfbOffset[sfb],
sfbOffset[sfb+1] - sfbOffset[sfb],
psectioninfo->codeBook,
hBitStream);
}
}
return(GetBitsAvail(hBitStream)-dbgVal);
}
/*****************************************************************************
*
* function name:encodeGlobalGain
* description: encodes Global Gain (common scale factor)
* returns: none
*
*****************************************************************************/
static void encodeGlobalGain(Word16 globalGain,
Word16 logNorm,
Word16 scalefac,
HANDLE_BIT_BUF hBitStream)
{
WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);
}
/*****************************************************************************
*
* function name:encodeIcsInfo
* description: encodes Ics Info
* returns: none
*
*****************************************************************************/
static void encodeIcsInfo(Word16 blockType,
Word16 windowShape,
Word16 groupingMask,
SECTION_DATA *sectionData,
HANDLE_BIT_BUF hBitStream)
{
WriteBits(hBitStream,icsReservedBit,1);
WriteBits(hBitStream,blockType,2);
WriteBits(hBitStream,windowShape,1);
switch(blockType){
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);
/* No predictor data present */
WriteBits(hBitStream, 0, 1);
break;
case SHORT_WINDOW:
WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);
/*
Write grouping bits
*/
WriteBits(hBitStream,groupingMask,TRANS_FAC-1);
break;
}
}
/*****************************************************************************
*
* function name: encodeSectionData
* description: encode section data (common Huffman codebooks for adjacent
* SFB's)
* returns: none
*
*****************************************************************************/
static Word32 encodeSectionData(SECTION_DATA *sectionData,
HANDLE_BIT_BUF hBitStream)
{
Word16 sectEscapeVal=0,sectLenBits=0;
Word16 sectLen;
Word16 i;
Word16 dbgVal=GetBitsAvail(hBitStream);
switch(sectionData->blockType)
{
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
sectEscapeVal = SECT_ESC_VAL_LONG;
sectLenBits = SECT_BITS_LONG;
break;
case SHORT_WINDOW:
sectEscapeVal = SECT_ESC_VAL_SHORT;
sectLenBits = SECT_BITS_SHORT;
break;
}
for(i=0;i<sectionData->noOfSections;i++) {
WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
sectLen = sectionData->sectionInfo[i].sfbCnt;
while(sectLen >= sectEscapeVal) {
WriteBits(hBitStream,sectEscapeVal,sectLenBits);
sectLen = sectLen - sectEscapeVal;
}
WriteBits(hBitStream,sectLen,sectLenBits);
}
return(GetBitsAvail(hBitStream)-dbgVal);
}
/*****************************************************************************
*
* function name: encodeScaleFactorData
* description: encode DPCM coded scale factors
* returns: none
*
*****************************************************************************/
static Word32 encodeScaleFactorData(UWord16 *maxValueInSfb,
SECTION_DATA *sectionData,
Word16 *scalefac,
HANDLE_BIT_BUF hBitStream)
{
Word16 i,j,lastValScf,deltaScf;
Word16 dbgVal = GetBitsAvail(hBitStream);
SECTION_INFO* psectioninfo;
lastValScf=scalefac[sectionData->firstScf];
for(i=0;i<sectionData->noOfSections;i++){
psectioninfo = &(sectionData->sectionInfo[i]);
if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
for (j=psectioninfo->sfbStart;
j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){
if(maxValueInSfb[j] == 0) {
deltaScf = 0;
}
else {
deltaScf = lastValScf - scalefac[j];
lastValScf = scalefac[j];
}
if(codeScalefactorDelta(deltaScf,hBitStream)){
return(1);
}
}
}
}
return(GetBitsAvail(hBitStream)-dbgVal);
}
/*****************************************************************************
*
* function name:encodeMsInfo
* description: encodes MS-Stereo Info
* returns: none
*
*****************************************************************************/
static void encodeMSInfo(Word16 sfbCnt,
Word16 grpSfb,
Word16 maxSfb,
Word16 msDigest,
Word16 *jsFlags,
HANDLE_BIT_BUF hBitStream)
{
Word16 sfb, sfbOff;
switch(msDigest)
{
case MS_NONE:
WriteBits(hBitStream,SI_MS_MASK_NONE,2);
break;
case MS_ALL:
WriteBits(hBitStream,SI_MS_MASK_ALL,2);
break;
case MS_SOME:
WriteBits(hBitStream,SI_MS_MASK_SOME,2);
for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
for(sfb=0; sfb<maxSfb; sfb++) {
if(jsFlags[sfbOff+sfb] & MS_ON) {
WriteBits(hBitStream,1,1);
}
else{
WriteBits(hBitStream,0,1);
}
}
}
break;
}
}
/*****************************************************************************
*
* function name: encodeTnsData
* description: encode TNS data (filter order, coeffs, ..)
* returns: none
*
*****************************************************************************/
static void encodeTnsData(TNS_INFO tnsInfo,
Word16 blockType,
HANDLE_BIT_BUF hBitStream) {
Word16 i,k;
Flag tnsPresent;
Word16 numOfWindows;
Word16 coefBits;
Flag isShort;
if (blockType==2) {
isShort = 1;
numOfWindows = TRANS_FAC;
}
else {
isShort = 0;
numOfWindows = 1;
}
tnsPresent=0;
for (i=0; i<numOfWindows; i++) {
if (tnsInfo.tnsActive[i]) {
tnsPresent=1;
}
}
if (tnsPresent==0) {
WriteBits(hBitStream,0,1);
}
else{ /* there is data to be written*/
WriteBits(hBitStream,1,1); /*data_present */
for (i=0; i<numOfWindows; i++) {
WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));
if (tnsInfo.tnsActive[i]) {
WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);
WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));
WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));
if (tnsInfo.order[i]){
WriteBits(hBitStream, FILTER_DIRECTION, 1);
if(tnsInfo.coefRes[i] == 4) {
coefBits = 3;
for(k=0; k<tnsInfo.order[i]; k++) {
if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
coefBits = 4;
break;
}
}
}
else {
coefBits = 2;
for(k=0; k<tnsInfo.order[i]; k++) {
if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
coefBits = 3;
break;
}
}
}
WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
for (k=0; k<tnsInfo.order[i]; k++ ) {
static const Word16 rmask[] = {0,1,3,7,15};
WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
}
}
}
}
}
}
/*****************************************************************************
*
* function name: encodeGainControlData
* description: unsupported
* returns: none
*
*****************************************************************************/
static void encodeGainControlData(HANDLE_BIT_BUF hBitStream)
{
WriteBits(hBitStream,0,1);
}
/*****************************************************************************
*
* function name: encodePulseData
* description: not supported yet (dummy)
* returns: none
*
*****************************************************************************/
static void encodePulseData(HANDLE_BIT_BUF hBitStream)
{
WriteBits(hBitStream,0,1);
}
/*****************************************************************************
*
* function name: WriteIndividualChannelStream
* description: management of write process of individual channel stream
* returns: none
*
*****************************************************************************/
static void
writeIndividualChannelStream(Flag commonWindow,
Word16 mdctScale,
Word16 windowShape,
Word16 groupingMask,
Word16 *sfbOffset,
Word16 scf[],
UWord16 *maxValueInSfb,
Word16 globalGain,
Word16 quantSpec[],
SECTION_DATA *sectionData,
HANDLE_BIT_BUF hBitStream,
TNS_INFO tnsInfo)
{
Word16 logNorm;
logNorm = LOG_NORM_PCM - (mdctScale + 1);
encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);
if(!commonWindow) {
encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
}
encodeSectionData(sectionData, hBitStream);
encodeScaleFactorData(maxValueInSfb,
sectionData,
scf,
hBitStream);
encodePulseData(hBitStream);
encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);
encodeGainControlData(hBitStream);
encodeSpectralData(sfbOffset,
sectionData,
quantSpec,
hBitStream);
}
/*****************************************************************************
*
* function name: writeSingleChannelElement
* description: write single channel element to bitstream
* returns: none
*
*****************************************************************************/
static Word16 writeSingleChannelElement(Word16 instanceTag,
Word16 *sfbOffset,
QC_OUT_CHANNEL* qcOutChannel,
HANDLE_BIT_BUF hBitStream,
TNS_INFO tnsInfo)
{
WriteBits(hBitStream,ID_SCE,3);
WriteBits(hBitStream,instanceTag,4);
writeIndividualChannelStream(0,
qcOutChannel->mdctScale,
qcOutChannel->windowShape,
qcOutChannel->groupingMask,
sfbOffset,
qcOutChannel->scf,
qcOutChannel->maxValueInSfb,
qcOutChannel->globalGain,
qcOutChannel->quantSpec,
&(qcOutChannel->sectionData),
hBitStream,
tnsInfo
);
return(0);
}
/*****************************************************************************
*
* function name: writeChannelPairElement
* description:
* returns: none
*
*****************************************************************************/
static Word16 writeChannelPairElement(Word16 instanceTag,
Word16 msDigest,
Word16 msFlags[MAX_GROUPED_SFB],
Word16 *sfbOffset[2],
QC_OUT_CHANNEL qcOutChannel[2],
HANDLE_BIT_BUF hBitStream,
TNS_INFO tnsInfo[2])
{
WriteBits(hBitStream,ID_CPE,3);
WriteBits(hBitStream,instanceTag,4);
WriteBits(hBitStream,1,1); /* common window */
encodeIcsInfo(qcOutChannel[0].sectionData.blockType,
qcOutChannel[0].windowShape,
qcOutChannel[0].groupingMask,
&(qcOutChannel[0].sectionData),
hBitStream);
encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,
qcOutChannel[0].sectionData.sfbPerGroup,
qcOutChannel[0].sectionData.maxSfbPerGroup,
msDigest,
msFlags,
hBitStream);
writeIndividualChannelStream(1,
qcOutChannel[0].mdctScale,
qcOutChannel[0].windowShape,
qcOutChannel[0].groupingMask,
sfbOffset[0],
qcOutChannel[0].scf,
qcOutChannel[0].maxValueInSfb,
qcOutChannel[0].globalGain,
qcOutChannel[0].quantSpec,
&(qcOutChannel[0].sectionData),
hBitStream,
tnsInfo[0]);
writeIndividualChannelStream(1,
qcOutChannel[1].mdctScale,
qcOutChannel[1].windowShape,
qcOutChannel[1].groupingMask,
sfbOffset[1],
qcOutChannel[1].scf,
qcOutChannel[1].maxValueInSfb,
qcOutChannel[1].globalGain,
qcOutChannel[1].quantSpec,
&(qcOutChannel[1].sectionData),
hBitStream,
tnsInfo[1]);
return(0);
}
/*****************************************************************************
*
* function name: writeFillElement
* description: write fill elements to bitstream
* returns: none
*
*****************************************************************************/
static void writeFillElement( const UWord8 *ancBytes,
Word16 totFillBits,
HANDLE_BIT_BUF hBitStream)
{
Word16 i;
Word16 cnt,esc_count;
/*
Write fill Element(s):
amount of a fill element can be 7+X*8 Bits, X element of [0..270]
*/
while(totFillBits >= (3+4)) {
cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));
WriteBits(hBitStream,ID_FIL,3);
WriteBits(hBitStream,cnt,4);
totFillBits = totFillBits - (3+4);
if (cnt == (1<<4)-1) {
esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
WriteBits(hBitStream,esc_count,8);
totFillBits = (totFillBits - 8);
cnt = cnt + (esc_count - 1);
}
for(i=0;i<cnt;i++) {
if(ancBytes)
WriteBits(hBitStream, *ancBytes++,8);
else
WriteBits(hBitStream,0,8);
totFillBits = totFillBits - 8;
}
}
}
/*****************************************************************************
*
* function name: WriteBitStream
* description: main function of write bitsteam process
* returns: 0 if success
*
*****************************************************************************/
Word16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
ELEMENT_INFO elInfo,
QC_OUT *qcOut,
PSY_OUT *psyOut,
Word16 *globUsedBits,
const UWord8 *ancBytes,
Word16 sampindex
) /* returns error code */
{
Word16 bitMarkUp;
Word16 elementUsedBits;
Word16 frameBits=0;
UNUSED(ancBytes);
/* struct bitbuffer bsWriteCopy; */
bitMarkUp = GetBitsAvail(hBitStream);
if(qcOut->qcElement.adtsUsed) /* write adts header*/
{
WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
WriteBits(hBitStream, 0, 2); /* layer == 0 */
WriteBits(hBitStream, 1, 1); /* protection absent */
WriteBits(hBitStream, 1, 2); /* profile */
WriteBits(hBitStream, sampindex, 4); /* sampling rate */
WriteBits(hBitStream, 0, 1); /* private bit */
WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */
/* simply using numChannels only works for
6 channels or less, else a channel
configuration should be written */
WriteBits(hBitStream, 0, 1); /* original/copy */
WriteBits(hBitStream, 0, 1); /* home */
/* Variable ADTS header */
WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
WriteBits(hBitStream, 0, 1); /* copyr. id. start */
WriteBits(hBitStream, *globUsedBits >> 3, 13);
WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
}
*globUsedBits=0;
{
Word16 *sfbOffset[2];
TNS_INFO tnsInfo[2];
elementUsedBits = 0;
switch (elInfo.elType) {
case ID_SCE: /* single channel */
sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
writeSingleChannelElement(elInfo.instanceTag,
sfbOffset[0],
&qcOut->qcChannel[elInfo.ChannelIndex[0]],
hBitStream,
tnsInfo[0]);
break;
case ID_CPE: /* channel pair */
{
Word16 msDigest;
Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
sfbOffset[0] =
psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
sfbOffset[1] =
psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;
tnsInfo[0]=
psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
tnsInfo[1]=
psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;
writeChannelPairElement(elInfo.instanceTag,
msDigest,
msFlags,
sfbOffset,
&qcOut->qcChannel[elInfo.ChannelIndex[0]],
hBitStream,
tnsInfo);
}
break;
default:
return(1);
} /* switch */
elementUsedBits = elementUsedBits - bitMarkUp;
bitMarkUp = GetBitsAvail(hBitStream);
frameBits = frameBits + elementUsedBits + bitMarkUp;
}
writeFillElement(NULL,
qcOut->totFillBits,
hBitStream);
WriteBits(hBitStream,ID_END,3);
/* byte alignement */
WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
*globUsedBits = *globUsedBits- bitMarkUp;
bitMarkUp = GetBitsAvail(hBitStream);
*globUsedBits = *globUsedBits + bitMarkUp;
frameBits = frameBits + *globUsedBits;
if (frameBits != (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
qcOut->totFillBits + qcOut->alignBits)) {
return(-1);
}
return(0);
}

50
aacenc/external/aacenc/src/bitenc.h vendored Normal file
View file

@ -0,0 +1,50 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: bitenc.h
Content: Bitstream encoder structure and functions
*******************************************************************************/
#ifndef _BITENC_H
#define _BITENC_H
#include "qc_data.h"
#include "tns.h"
#include "channel_map.h"
#include "interface.h"
struct BITSTREAMENCODER_INIT
{
Word16 nChannels;
Word32 bitrate;
Word32 sampleRate;
Word16 profile;
};
Word16 WriteBitstream (HANDLE_BIT_BUF hBitstream,
ELEMENT_INFO elInfo,
QC_OUT *qcOut,
PSY_OUT *psyOut,
Word16 *globUsedBits,
const UWord8 *ancBytes,
Word16 samplerate
);
#endif /* _BITENC_H */

View file

@ -0,0 +1,404 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: block_switch.c
Content: Block switching functions
*******************************************************************************/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "psy_const.h"
#include "block_switch.h"
#define ENERGY_SHIFT (8 - 1)
/**************** internal function prototypes ***********/
static Word32
SrchMaxWithIndex(const Word32 *in, Word16 *index, Word16 n);
Word32
CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
Word16 *timeSignal,
Word16 chIncrement,
Word16 windowLen);
/****************** Constants *****************************/
/*
IIR high pass coeffs
*/
const Word32 hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
0xbec8b439, 0x609d4952 /* -0.5095f, 0.7548f */
};
static const Word32 accWindowNrgFac = 0x26666666; /* factor for accumulating filtered window energies 0.3 */
static const Word32 oneMinusAccWindowNrgFac = 0x5999999a; /* 0.7 */
static const Word32 invAttackRatioHighBr = 0x0ccccccd; /* inverted lower ratio limit for attacks 0.1*/
static const Word32 invAttackRatioLowBr = 0x072b020c; /* 0.056 */
static const Word32 minAttackNrg = 0x00001e84; /* minimum energy for attacks 1e+6 */
/****************** Routines ****************************/
/*****************************************************************************
*
* function name: InitBlockSwitching
* description: init Block Switching parameter.
* returns: TRUE if success
*
**********************************************************************************/
Word16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
const Word32 bitRate, const Word16 nChannels)
{
/* select attackRatio */
if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) ||
(sub(nChannels,1)>0 && bitRate > (nChannels * 16000))) {
blockSwitchingControl->invAttackRatio = invAttackRatioHighBr;
}
else {
blockSwitchingControl->invAttackRatio = invAttackRatioLowBr;
}
return(TRUE);
}
static Word16 suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = {
/* Attack in Window 0 */ {1, 3, 3, 1},
/* Attack in Window 1 */ {1, 1, 3, 3},
/* Attack in Window 2 */ {2, 1, 3, 2},
/* Attack in Window 3 */ {3, 1, 3, 1},
/* Attack in Window 4 */ {3, 1, 1, 3},
/* Attack in Window 5 */ {3, 2, 1, 2},
/* Attack in Window 6 */ {3, 3, 1, 1},
/* Attack in Window 7 */ {3, 3, 1, 1}
};
/*****************************************************************************
*
* function name: BlockSwitching
* description: detect this frame whether there is an attack
* returns: TRUE if success
*
**********************************************************************************/
Word16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
Word16 *timeSignal,
Word32 sampleRate,
Word16 chIncrement)
{
Word32 i, w;
Word32 enM1, enMax;
/* Reset grouping info */
for (i=0; i<TRANS_FAC; i++) {
blockSwitchingControl->groupLen[i] = 0;
}
/* Search for position and amplitude of attack in last frame (1 windows delay) */
blockSwitchingControl->maxWindowNrg = SrchMaxWithIndex( &blockSwitchingControl->windowNrg[0][BLOCK_SWITCH_WINDOWS-1],
&blockSwitchingControl->attackIndex,
BLOCK_SWITCH_WINDOWS);
blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex;
/* Set grouping info */
blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
for (i=0; i<MAX_NO_OF_GROUPS; i++) {
blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i];
}
/* if the samplerate is less than 16000, it should be all the short block, avoid pre&post echo */
if(sampleRate >= 16000) {
/* Save current window energy as last window energy */
for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w];
blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w];
}
/* Calculate unfiltered and filtered energies in subwindows and combine to segments */
CalcWindowEnergy(blockSwitchingControl, timeSignal, chIncrement, BLOCK_SWITCH_WINDOW_LEN);
/* reset attack */
blockSwitchingControl->attack = FALSE;
enMax = 0;
enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1];
for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
Word32 enM1_Tmp, accWindowNrg_Tmp, windowNrgF_Tmp;
Word16 enM1_Shf, accWindowNrg_Shf, windowNrgF_Shf;
accWindowNrg_Shf = norm_l(blockSwitchingControl->accWindowNrg);
enM1_Shf = norm_l(enM1);
windowNrgF_Shf = norm_l(blockSwitchingControl->windowNrgF[1][w]);
accWindowNrg_Tmp = blockSwitchingControl->accWindowNrg << accWindowNrg_Shf;
enM1_Tmp = enM1 << enM1_Shf;
windowNrgF_Tmp = blockSwitchingControl->windowNrgF[1][w] << windowNrgF_Shf;
/* a sliding average of the previous energies */
blockSwitchingControl->accWindowNrg = (fixmul(oneMinusAccWindowNrgFac, accWindowNrg_Tmp) >> accWindowNrg_Shf) +
(fixmul(accWindowNrgFac, enM1_Tmp) >> enM1_Shf);
/* if the energy with the ratio is bigger than the average, and the attack and short block */
if ((fixmul(windowNrgF_Tmp, blockSwitchingControl->invAttackRatio) >> windowNrgF_Shf) >
blockSwitchingControl->accWindowNrg ) {
blockSwitchingControl->attack = TRUE;
blockSwitchingControl->lastAttackIndex = w;
}
enM1 = blockSwitchingControl->windowNrgF[1][w];
enMax = max(enMax, enM1);
}
if (enMax < minAttackNrg) {
blockSwitchingControl->attack = FALSE;
}
}
else
{
blockSwitchingControl->attack = TRUE;
}
/* Check if attack spreads over frame border */
if ((!blockSwitchingControl->attack) && (blockSwitchingControl->lastattack)) {
if (blockSwitchingControl->attackIndex == TRANS_FAC-1) {
blockSwitchingControl->attack = TRUE;
}
blockSwitchingControl->lastattack = FALSE;
}
else {
blockSwitchingControl->lastattack = blockSwitchingControl->attack;
}
blockSwitchingControl->windowSequence = blockSwitchingControl->nextwindowSequence;
if (blockSwitchingControl->attack) {
blockSwitchingControl->nextwindowSequence = SHORT_WINDOW;
}
else {
blockSwitchingControl->nextwindowSequence = LONG_WINDOW;
}
/* update short block group */
if (blockSwitchingControl->nextwindowSequence == SHORT_WINDOW) {
if (blockSwitchingControl->windowSequence== LONG_WINDOW) {
blockSwitchingControl->windowSequence = START_WINDOW;
}
if (blockSwitchingControl->windowSequence == STOP_WINDOW) {
blockSwitchingControl->windowSequence = SHORT_WINDOW;
blockSwitchingControl->noOfGroups = 3;
blockSwitchingControl->groupLen[0] = 3;
blockSwitchingControl->groupLen[1] = 3;
blockSwitchingControl->groupLen[2] = 2;
}
}
/* update block type */
if (blockSwitchingControl->nextwindowSequence == LONG_WINDOW) {
if (blockSwitchingControl->windowSequence == SHORT_WINDOW) {
blockSwitchingControl->nextwindowSequence = STOP_WINDOW;
}
}
return(TRUE);
}
/*****************************************************************************
*
* function name: SrchMaxWithIndex
* description: search for the biggest value in an array
* returns: the max value
*
**********************************************************************************/
static Word32 SrchMaxWithIndex(const Word32 in[], Word16 *index, Word16 n)
{
Word32 max;
Word32 i, idx;
/* Search maximum value in array and return index and value */
max = 0;
idx = 0;
for (i = 0; i < n; i++) {
if (in[i+1] > max) {
max = in[i+1];
idx = i;
}
}
*index = idx;
return(max);
}
/*****************************************************************************
*
* function name: CalcWindowEnergy
* description: calculate the energy before iir-filter and after irr-filter
* returns: TRUE if success
*
**********************************************************************************/
#ifndef ARMV5E
Word32 CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
Word16 *timeSignal,
Word16 chIncrement,
Word16 windowLen)
{
Word32 w, i, tidx;
Word32 accuUE, accuFE;
Word32 tempUnfiltered;
Word32 tempFiltered;
Word32 states0, states1;
Word32 Coeff0, Coeff1;
states0 = blockSwitchingControl->iirStates[0];
states1 = blockSwitchingControl->iirStates[1];
Coeff0 = hiPassCoeff[0];
Coeff1 = hiPassCoeff[1];
tidx = 0;
for (w=0; w < BLOCK_SWITCH_WINDOWS; w++) {
accuUE = 0;
accuFE = 0;
for(i=0; i<windowLen; i++) {
Word32 accu1, accu2, accu3;
Word32 out;
tempUnfiltered = timeSignal[tidx];
tidx = tidx + chIncrement;
accu1 = L_mpy_ls(Coeff1, tempUnfiltered);
accu2 = fixmul( Coeff0, states1 );
accu3 = accu1 - states0;
out = accu3 - accu2;
states0 = accu1;
states1 = out;
tempFiltered = extract_h(out);
accuUE += (tempUnfiltered * tempUnfiltered) >> ENERGY_SHIFT;
accuFE += (tempFiltered * tempFiltered) >> ENERGY_SHIFT;
}
blockSwitchingControl->windowNrg[1][w] = accuUE;
blockSwitchingControl->windowNrgF[1][w] = accuFE;
}
blockSwitchingControl->iirStates[0] = states0;
blockSwitchingControl->iirStates[1] = states1;
return(TRUE);
}
#endif
static Word16 synchronizedBlockTypeTable[4][4] = {
/* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW */
/* LONG_WINDOW */{LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW},
/* START_WINDOW */{START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW},
/* SHORT_WINDOW */{SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW},
/* STOP_WINDOW */{STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW}
};
/*****************************************************************************
*
* function name: SyncBlockSwitching
* description: update block type and group value
* returns: TRUE if success
*
**********************************************************************************/
Word16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight,
const Word16 nChannels)
{
Word16 i;
Word16 patchType = LONG_WINDOW;
if (nChannels == 1) { /* Mono */
if (blockSwitchingControlLeft->windowSequence != SHORT_WINDOW) {
blockSwitchingControlLeft->noOfGroups = 1;
blockSwitchingControlLeft->groupLen[0] = 1;
for (i=1; i<TRANS_FAC; i++) {
blockSwitchingControlLeft->groupLen[i] = 0;
}
}
}
else { /* Stereo common Window */
patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence];
patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence];
/* Set synchronized Blocktype */
blockSwitchingControlLeft->windowSequence = patchType;
blockSwitchingControlRight->windowSequence = patchType;
/* Synchronize grouping info */
if(patchType != SHORT_WINDOW) { /* Long Blocks */
/* Set grouping info */
blockSwitchingControlLeft->noOfGroups = 1;
blockSwitchingControlRight->noOfGroups = 1;
blockSwitchingControlLeft->groupLen[0] = 1;
blockSwitchingControlRight->groupLen[0] = 1;
for (i=1; i<TRANS_FAC; i++) {
blockSwitchingControlLeft->groupLen[i] = 0;
blockSwitchingControlRight->groupLen[i] = 0;
}
}
else {
if (blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) {
/* Left Channel wins */
blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups;
for (i=0; i<TRANS_FAC; i++) {
blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i];
}
}
else {
/* Right Channel wins */
blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups;
for (i=0; i<TRANS_FAC; i++) {
blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i];
}
}
}
} /*endif Mono or Stereo */
return(TRUE);
}

View file

@ -0,0 +1,72 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: block_switch.h
Content: Block switching structure and functions
*******************************************************************************/
#ifndef _BLOCK_SWITCH_H
#define _BLOCK_SWITCH_H
#include "typedef.h"
/****************** Defines ******************************/
#define BLOCK_SWITCHING_IIR_LEN 2 /* Length of HighPass-FIR-Filter for Attack-Detection */
#define BLOCK_SWITCH_WINDOWS TRANS_FAC /* number of windows for energy calculation */
#define BLOCK_SWITCH_WINDOW_LEN FRAME_LEN_SHORT /* minimal granularity of energy calculation */
/****************** Structures ***************************/
typedef struct{
Word32 invAttackRatio;
Word16 windowSequence;
Word16 nextwindowSequence;
Flag attack;
Flag lastattack;
Word16 attackIndex;
Word16 lastAttackIndex;
Word16 noOfGroups;
Word16 groupLen[TRANS_FAC];
Word32 windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows (last and current) */
Word32 windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy in segments (last and current) */
Word32 iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */
Word32 maxWindowNrg; /* max energy in subwindows */
Word32 accWindowNrg; /* recursively accumulated windowNrgF */
}BLOCK_SWITCHING_CONTROL;
Word16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
const Word32 bitRate, const Word16 nChannels);
Word16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
Word16 *timeSignal,
Word32 sampleRate,
Word16 chIncrement);
Word16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight,
const Word16 noOfChannels);
#endif /* #ifndef _BLOCK_SWITCH_H */

123
aacenc/external/aacenc/src/channel_map.c vendored Normal file
View file

@ -0,0 +1,123 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: channel_map.c
Content: channel mapping functions
*******************************************************************************/
#include "channel_map.h"
#include "bitenc.h"
#include "psy_const.h"
#include "qc_data.h"
static const Word16 maxChannelBits = MAXBITS_COEF;
static Word16 initElement(ELEMENT_INFO* elInfo, ELEMENT_TYPE elType)
{
Word16 error=0;
elInfo->elType=elType;
switch(elInfo->elType) {
case ID_SCE:
elInfo->nChannelsInEl=1;
elInfo->ChannelIndex[0]=0;
elInfo->instanceTag=0;
break;
case ID_CPE:
elInfo->nChannelsInEl=2;
elInfo->ChannelIndex[0]=0;
elInfo->ChannelIndex[1]=1;
elInfo->instanceTag=0;
break;
default:
error=1;
}
return error;
}
Word16 InitElementInfo (Word16 nChannels, ELEMENT_INFO* elInfo)
{
Word16 error;
error = 0;
switch(nChannels) {
case 1:
initElement(elInfo, ID_SCE);
break;
case 2:
initElement(elInfo, ID_CPE);
break;
default:
error=4;
}
return error;
}
Word16 InitElementBits(ELEMENT_BITS *elementBits,
ELEMENT_INFO elInfo,
Word32 bitrateTot,
Word16 averageBitsTot,
Word16 staticBitsTot)
{
Word16 error;
error = 0;
switch(elInfo.nChannelsInEl) {
case 1:
elementBits->chBitrate = bitrateTot;
elementBits->averageBits = averageBitsTot - staticBitsTot;
elementBits->maxBits = maxChannelBits;
elementBits->maxBitResBits = maxChannelBits - averageBitsTot;
elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);
elementBits->bitResLevel = elementBits->maxBitResBits;
elementBits->relativeBits = 0x4000; /* 1.0f/2 */
break;
case 2:
elementBits->chBitrate = bitrateTot >> 1;
elementBits->averageBits = averageBitsTot - staticBitsTot;
elementBits->maxBits = maxChannelBits << 1;
elementBits->maxBitResBits = (maxChannelBits << 1) - averageBitsTot;
elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);
elementBits->bitResLevel = elementBits->maxBitResBits;
elementBits->relativeBits = 0x4000; /* 1.0f/2 */
break;
default:
error = 1;
}
return error;
}

View file

@ -0,0 +1,37 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: channel_map.h
Content: channel mapping functions
*******************************************************************************/
#ifndef _CHANNEL_MAP_H
#define _CHANNEL_MAP_H
#include "psy_const.h"
#include "qc_data.h"
Word16 InitElementInfo (Word16 nChannels, ELEMENT_INFO* elInfo);
Word16 InitElementBits(ELEMENT_BITS *elementBits,
ELEMENT_INFO elInfo,
Word32 bitrateTot,
Word16 averageBitsTot,
Word16 staticBitsTot);
#endif /* CHANNEL_MAP_H */

89
aacenc/external/aacenc/src/cmnMemory.c vendored Normal file
View file

@ -0,0 +1,89 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: cmnMemory.c
Content: sample code for memory operator implementation
*******************************************************************************/
#include "cmnMemory.h"
#include <stdlib.h>
#include <string.h>
//VO_MEM_OPERATOR g_memOP;
#define UNUSED(x) (void)(x)
VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
{
UNUSED(uID);
if (!pMemInfo)
return VO_ERR_INVALID_ARG;
pMemInfo->VBuffer = malloc (pMemInfo->Size);
return 0;
}
VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem)
{
UNUSED(uID);
free (pMem);
return 0;
}
VO_U32 cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)
{
UNUSED(uID);
memset (pBuff, uValue, uSize);
return 0;
}
VO_U32 cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
UNUSED(uID);
memcpy (pDest, pSource, uSize);
return 0;
}
VO_U32 cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)
{
UNUSED(uID);
UNUSED(pBuffer);
UNUSED(uSize);
return 0;
}
VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize)
{
UNUSED(uID);
return memcmp(pBuffer1, pBuffer2, uSize);
}
VO_U32 cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
UNUSED(uID);
memmove (pDest, pSource, uSize);
return 0;
}

106
aacenc/external/aacenc/src/cmnMemory.h vendored Normal file
View file

@ -0,0 +1,106 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: cmnMemory.h
Content: memory operator implementation header file
*******************************************************************************/
#ifndef __cmnMemory_H__
#define __cmnMemory_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "voMem.h"
//extern VO_MEM_OPERATOR g_memOP;
/**
* Allocate memory
* \param uID [in] module ID
* \param uSize [in] size of memory
* \return value is the allocated memory address. NULL is failed.
*/
VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo);
/**
* Free up memory
* \param uID [in] module ID
* \param pMem [in] address of memory
* \return value 0, if succeeded.
*/
VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pBuffer);
/**
* memory set function
* \param uID [in] module ID
* \param pBuff [in/out] address of memory
* \param uValue [in] the value to be set
* \param uSize [in] the size to be set
* \return value 0, if succeeded.
*/
VO_U32 cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize);
/**
* memory copy function
* \param uID [in] module ID
* \param pDest [in/out] address of destination memory
* \param pSource [in] address of source memory
* \param uSize [in] the size to be copied
* \return value 0, if succeeded.
*/
VO_U32 cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);
/**
* memory check function
* \param uID [in] module ID
* \param pBuff [in] address of buffer to be checked
* \param uSize [in] the size to be checked
* \return value 0, if succeeded.
*/
VO_U32 cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize);
/**
* memory compare function
* \param uID [in] module ID
* \param pBuffer1 [in] address of buffer 1 to be compared
* \param pBuffer2 [in] address of buffer 2 to be compared
* \param uSize [in] the size to be compared
* \return value: same as standard C run-time memcmp() function.
*/
VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize);
/**
* memory move function
* \param uID [in] module ID
* \param pDest [in/out] address of destination memory
* \param pSource [in] address of source memory
* \param uSize [in] the size to be moved
* \return value 0, if succeeded.
*/
VO_U32 cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // __cmnMemory_H__

36
aacenc/external/aacenc/src/config.h vendored Normal file
View file

@ -0,0 +1,36 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: config.h
Content: aac encoder parameter
*******************************************************************************/
#ifndef _AACENC_CONFIG_H_
#define _AACENC_CONFIG_H_
#define MAX_CHANNELS 2
#define AACENC_BLOCKSIZE 1024 /*! encoder only takes BLOCKSIZE samples at a time */
#define AACENC_TRANS_FAC 8 /*! encoder short long ratio */
#define MAXBITS_COEF 6144
#define MINBITS_COEF 744
#endif

544
aacenc/external/aacenc/src/dyn_bits.c vendored Normal file
View file

@ -0,0 +1,544 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: dyn_bits.c
Content: Noiseless coder module functions
*******************************************************************************/
#include "aac_rom.h"
#include "dyn_bits.h"
#include "bit_cnt.h"
#include "psy_const.h"
/*****************************************************************************
*
* function name: buildBitLookUp
* description: count bits using all possible tables
*
*****************************************************************************/
static void
buildBitLookUp(const Word16 *quantSpectrum,
const Word16 maxSfb,
const Word16 *sfbOffset,
const UWord16 *sfbMax,
Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
SECTION_INFO * sectionInfo)
{
Word32 i;
for (i=0; i<maxSfb; i++) {
Word16 sfbWidth, maxVal;
sectionInfo[i].sfbCnt = 1;
sectionInfo[i].sfbStart = i;
sectionInfo[i].sectionBits = INVALID_BITCOUNT;
sectionInfo[i].codeBook = -1;
sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
maxVal = sfbMax[i];
bitCount(quantSpectrum + sfbOffset[i], sfbWidth, maxVal, bitLookUp[i]);
}
}
/*****************************************************************************
*
* function name: findBestBook
* description: essential helper functions
*
*****************************************************************************/
static Word16
findBestBook(const Word16 *bc, Word16 *book)
{
Word32 minBits, j;
minBits = INVALID_BITCOUNT;
for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
if (bc[j] < minBits) {
minBits = bc[j];
*book = j;
}
}
return extract_l(minBits);
}
static Word16
findMinMergeBits(const Word16 *bc1, const Word16 *bc2)
{
Word32 minBits, j, sum;
minBits = INVALID_BITCOUNT;
for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
sum = bc1[j] + bc2[j];
if (sum < minBits) {
minBits = sum;
}
}
return extract_l(minBits);
}
static void
mergeBitLookUp(Word16 *bc1, const Word16 *bc2)
{
Word32 j;
for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
bc1[j] = min(bc1[j] + bc2[j], INVALID_BITCOUNT);
}
}
static Word16
findMaxMerge(const Word16 mergeGainLookUp[MAX_SFB_LONG],
const SECTION_INFO *sectionInfo,
const Word16 maxSfb, Word16 *maxNdx)
{
Word32 i, maxMergeGain;
maxMergeGain = 0;
for (i=0; i+sectionInfo[i].sfbCnt < maxSfb; i += sectionInfo[i].sfbCnt) {
if (mergeGainLookUp[i] > maxMergeGain) {
maxMergeGain = mergeGainLookUp[i];
*maxNdx = i;
}
}
return extract_l(maxMergeGain);
}
static Word16
CalcMergeGain(const SECTION_INFO *sectionInfo,
Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
const Word16 *sideInfoTab,
const Word16 ndx1,
const Word16 ndx2)
{
Word32 SplitBits;
Word32 MergeBits;
Word32 MergeGain;
/*
Bit amount for splitted sections
*/
SplitBits = sectionInfo[ndx1].sectionBits + sectionInfo[ndx2].sectionBits;
MergeBits = sideInfoTab[sectionInfo[ndx1].sfbCnt + sectionInfo[ndx2].sfbCnt] +
findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2]);
MergeGain = (SplitBits - MergeBits);
return extract_l(MergeGain);
}
/*
sectioning Stage 0:find minimum codbooks
*/
static void
gmStage0(SECTION_INFO * sectionInfo,
Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
const Word16 maxSfb)
{
Word32 i;
for (i=0; i<maxSfb; i++) {
/* Side-Info bits will be calculated in Stage 1! */
if (sectionInfo[i].sectionBits == INVALID_BITCOUNT) {
sectionInfo[i].sectionBits = findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
}
}
}
/*
sectioning Stage 1:merge all connected regions with the same code book and
calculate side info
*/
static void
gmStage1(SECTION_INFO * sectionInfo,
Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
const Word16 maxSfb,
const Word16 *sideInfoTab)
{
SECTION_INFO * sectionInfo_s;
SECTION_INFO * sectionInfo_e;
Word32 mergeStart, mergeEnd;
mergeStart = 0;
do {
sectionInfo_s = sectionInfo + mergeStart;
for (mergeEnd=mergeStart+1; mergeEnd<maxSfb; mergeEnd++) {
sectionInfo_e = sectionInfo + mergeEnd;
if (sectionInfo_s->codeBook != sectionInfo_e->codeBook)
break;
sectionInfo_s->sfbCnt += 1;
sectionInfo_s->sectionBits += sectionInfo_e->sectionBits;
mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
}
sectionInfo_s->sectionBits += sideInfoTab[sectionInfo_s->sfbCnt];
sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart; /* speed up prev search */
mergeStart = mergeEnd;
} while (mergeStart - maxSfb < 0);
}
/*
sectioning Stage 2:greedy merge algorithm, merge connected sections with
maximum bit gain until no more gain is possible
*/
static void
gmStage2(SECTION_INFO *sectionInfo,
Word16 mergeGainLookUp[MAX_SFB_LONG],
Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
const Word16 maxSfb,
const Word16 *sideInfoTab)
{
Word16 i;
for (i=0; i+sectionInfo[i].sfbCnt<maxSfb; i+=sectionInfo[i].sfbCnt) {
mergeGainLookUp[i] = CalcMergeGain(sectionInfo,
bitLookUp,
sideInfoTab,
i,
(i + sectionInfo[i].sfbCnt));
}
while (TRUE) {
Word16 maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast;
maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);
if (maxMergeGain <= 0)
break;
maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;
sectionInfo[maxNdx].sfbCnt = sectionInfo[maxNdx].sfbCnt + sectionInfo[maxNdxNext].sfbCnt;
sectionInfo[maxNdx].sectionBits = sectionInfo[maxNdx].sectionBits +
(sectionInfo[maxNdxNext].sectionBits - maxMergeGain);
mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
if (maxNdx != 0) {
maxNdxLast = sectionInfo[maxNdx - 1].sfbStart;
mergeGainLookUp[maxNdxLast] = CalcMergeGain(sectionInfo,
bitLookUp,
sideInfoTab,
maxNdxLast,
maxNdx);
}
maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;
sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart;
if (maxNdxNext - maxSfb < 0) {
mergeGainLookUp[maxNdx] = CalcMergeGain(sectionInfo,
bitLookUp,
sideInfoTab,
maxNdx,
maxNdxNext);
}
}
}
/*
count bits used by the noiseless coder
*/
static void
noiselessCounter(SECTION_DATA *sectionData,
Word16 mergeGainLookUp[MAX_SFB_LONG],
Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
const Word16 *quantSpectrum,
const UWord16 *maxValueInSfb,
const Word16 *sfbOffset,
const Word32 blockType)
{
Word32 grpNdx, i;
const Word16 *sideInfoTab = NULL;
SECTION_INFO *sectionInfo;
/*
use appropriate side info table
*/
switch (blockType)
{
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
sideInfoTab = sideInfoTabLong;
break;
case SHORT_WINDOW:
sideInfoTab = sideInfoTabShort;
break;
}
sectionData->noOfSections = 0;
sectionData->huffmanBits = 0;
sectionData->sideInfoBits = 0;
if (sectionData->maxSfbPerGroup == 0)
return;
/*
loop trough groups
*/
for (grpNdx=0; grpNdx<sectionData->sfbCnt; grpNdx+=sectionData->sfbPerGroup) {
sectionInfo = sectionData->sectionInfo + sectionData->noOfSections;
buildBitLookUp(quantSpectrum,
sectionData->maxSfbPerGroup,
sfbOffset + grpNdx,
maxValueInSfb + grpNdx,
bitLookUp,
sectionInfo);
/*
0.Stage
*/
gmStage0(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup);
/*
1.Stage
*/
gmStage1(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab);
/*
2.Stage
*/
gmStage2(sectionInfo,
mergeGainLookUp,
bitLookUp,
sectionData->maxSfbPerGroup,
sideInfoTab);
/*
compress output, calculate total huff and side bits
*/
for (i=0; i<sectionData->maxSfbPerGroup; i+=sectionInfo[i].sfbCnt) {
findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
sectionInfo[i].sfbStart = sectionInfo[i].sfbStart + grpNdx;
sectionData->huffmanBits = (sectionData->huffmanBits +
(sectionInfo[i].sectionBits - sideInfoTab[sectionInfo[i].sfbCnt]));
sectionData->sideInfoBits = (sectionData->sideInfoBits + sideInfoTab[sectionInfo[i].sfbCnt]);
sectionData->sectionInfo[sectionData->noOfSections] = sectionInfo[i];
sectionData->noOfSections = sectionData->noOfSections + 1;
}
}
}
/*******************************************************************************
*
* functionname: scfCount
* returns : ---
* description : count bits used by scalefactors.
*
********************************************************************************/
static void scfCount(const Word16 *scalefacGain,
const UWord16 *maxValueInSfb,
SECTION_DATA * sectionData)
{
SECTION_INFO *psectionInfo;
SECTION_INFO *psectionInfom;
/* counter */
Word32 i = 0; /* section counter */
Word32 j = 0; /* sfb counter */
Word32 k = 0; /* current section auxiliary counter */
Word32 m = 0; /* other section auxiliary counter */
Word32 n = 0; /* other sfb auxiliary counter */
/* further variables */
Word32 lastValScf = 0;
Word32 deltaScf = 0;
Flag found = 0;
Word32 scfSkipCounter = 0;
sectionData->scalefacBits = 0;
if (scalefacGain == NULL) {
return;
}
lastValScf = 0;
sectionData->firstScf = 0;
psectionInfo = sectionData->sectionInfo;
for (i=0; i<sectionData->noOfSections; i++) {
if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO) {
sectionData->firstScf = psectionInfo->sfbStart;
lastValScf = scalefacGain[sectionData->firstScf];
break;
}
psectionInfo += 1;
}
psectionInfo = sectionData->sectionInfo;
for (i=0; i<sectionData->noOfSections; i++, psectionInfo += 1) {
if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO
&& psectionInfo->codeBook != CODE_BOOK_PNS_NO) {
for (j = psectionInfo->sfbStart;
j < (psectionInfo->sfbStart + psectionInfo->sfbCnt); j++) {
/* check if we can repeat the last value to save bits */
if (maxValueInSfb[j] == 0) {
found = 0;
if (scfSkipCounter == 0) {
/* end of section */
if (j - ((psectionInfo->sfbStart + psectionInfo->sfbCnt) - 1) == 0) {
found = 0;
}
else {
for (k = j + 1; k < psectionInfo->sfbStart + psectionInfo->sfbCnt; k++) {
if (maxValueInSfb[k] != 0) {
int tmp = L_abs(scalefacGain[k] - lastValScf);
found = 1;
if ( tmp < CODE_BOOK_SCF_LAV) {
/* save bits */
deltaScf = 0;
}
else {
/* do not save bits */
deltaScf = lastValScf - scalefacGain[j];
lastValScf = scalefacGain[j];
scfSkipCounter = 0;
}
break;
}
/* count scalefactor skip */
scfSkipCounter = scfSkipCounter + 1;
}
}
psectionInfom = psectionInfo + 1;
/* search for the next maxValueInSfb[] != 0 in all other sections */
for (m = i + 1; (m < sectionData->noOfSections) && (found == 0); m++) {
if ((psectionInfom->codeBook != CODE_BOOK_ZERO_NO) &&
(psectionInfom->codeBook != CODE_BOOK_PNS_NO)) {
for (n = psectionInfom->sfbStart;
n < (psectionInfom->sfbStart + psectionInfom->sfbCnt); n++) {
if (maxValueInSfb[n] != 0) {
found = 1;
if ( (abs_s(scalefacGain[n] - lastValScf) < CODE_BOOK_SCF_LAV)) {
deltaScf = 0;
}
else {
deltaScf = (lastValScf - scalefacGain[j]);
lastValScf = scalefacGain[j];
scfSkipCounter = 0;
}
break;
}
/* count scalefactor skip */
scfSkipCounter = scfSkipCounter + 1;
}
}
psectionInfom += 1;
}
if (found == 0) {
deltaScf = 0;
scfSkipCounter = 0;
}
}
else {
deltaScf = 0;
scfSkipCounter = scfSkipCounter - 1;
}
}
else {
deltaScf = lastValScf - scalefacGain[j];
lastValScf = scalefacGain[j];
}
sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);
}
}
}
}
typedef Word16 (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
Word16
dynBitCount(const Word16 *quantSpectrum,
const UWord16 *maxValueInSfb,
const Word16 *scalefac,
const Word16 blockType,
const Word16 sfbCnt,
const Word16 maxSfbPerGroup,
const Word16 sfbPerGroup,
const Word16 *sfbOffset,
SECTION_DATA *sectionData)
{
sectionData->blockType = blockType;
sectionData->sfbCnt = sfbCnt;
sectionData->sfbPerGroup = sfbPerGroup;
if(sfbPerGroup)
sectionData->noOfGroups = sfbCnt/sfbPerGroup;
else
sectionData->noOfGroups = 0x7fff;
sectionData->maxSfbPerGroup = maxSfbPerGroup;
noiselessCounter(sectionData,
sectionData->mergeGainLookUp,
(lookUpTable)sectionData->bitLookUp,
quantSpectrum,
maxValueInSfb,
sfbOffset,
blockType);
scfCount(scalefac,
maxValueInSfb,
sectionData);
return (sectionData->huffmanBits + sectionData->sideInfoBits +
sectionData->scalefacBits);
}

82
aacenc/external/aacenc/src/dyn_bits.h vendored Normal file
View file

@ -0,0 +1,82 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: dyn_bits.h
Content: Noiseless coder module structure and functions
*******************************************************************************/
#ifndef __DYN_BITS_H
#define __DYN_BITS_H
#include "psy_const.h"
#include "tns.h"
#include "bit_cnt.h"
#define MAX_SECTIONS MAX_GROUPED_SFB
#define SECT_ESC_VAL_LONG 31
#define SECT_ESC_VAL_SHORT 7
#define CODE_BOOK_BITS 4
#define SECT_BITS_LONG 5
#define SECT_BITS_SHORT 3
typedef struct
{
Word16 codeBook;
Word16 sfbStart;
Word16 sfbCnt;
Word16 sectionBits;
}
SECTION_INFO;
typedef struct
{
Word16 blockType;
Word16 noOfGroups;
Word16 sfbCnt;
Word16 maxSfbPerGroup;
Word16 sfbPerGroup;
Word16 noOfSections;
SECTION_INFO sectionInfo[MAX_SECTIONS];
Word16 sideInfoBits; /* sectioning bits */
Word16 huffmanBits; /* huffman coded bits */
Word16 scalefacBits; /* scalefac coded bits */
Word16 firstScf; /* first scf to be coded */
Word16 bitLookUp[MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)];
Word16 mergeGainLookUp[MAX_SFB_LONG];
}
SECTION_DATA; /* Word16 size: 10 + 60(MAX_SECTIONS)*4(SECTION_INFO) + 51(MAX_SFB_LONG)*12(CODE_BOOK_ESC_NDX+1) + 51(MAX_SFB_LONG) = 913 */
Word16 BCInit(void);
Word16 dynBitCount(const Word16 *quantSpectrum,
const UWord16 *maxValueInSfb,
const Word16 *scalefac,
const Word16 blockType,
const Word16 sfbCnt,
const Word16 maxSfbPerGroup,
const Word16 sfbPerGroup,
const Word16 *sfbOffset,
SECTION_DATA *sectionData);
#endif

188
aacenc/external/aacenc/src/grp_data.c vendored Normal file
View file

@ -0,0 +1,188 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: grp_data.c
Content: Short block grouping function
*******************************************************************************/
#include "basic_op.h"
#include "psy_const.h"
#include "interface.h"
#include "grp_data.h"
/*****************************************************************************
*
* function name: groupShortData
* description: group short data for next quantization and coding
*
**********************************************************************************/
void
groupShortData(Word32 *mdctSpectrum,
Word32 *tmpSpectrum,
SFB_THRESHOLD *sfbThreshold,
SFB_ENERGY *sfbEnergy,
SFB_ENERGY *sfbEnergyMS,
SFB_ENERGY *sfbSpreadedEnergy,
const Word16 sfbCnt,
const Word16 *sfbOffset,
const Word16 *sfbMinSnr,
Word16 *groupedSfbOffset,
Word16 *maxSfbPerGroup,
Word16 *groupedSfbMinSnr,
const Word16 noOfGroups,
const Word16 *groupLen)
{
Word32 i, j;
Word32 line;
Word32 sfb;
Word32 grp;
Word32 wnd;
Word32 offset;
Word32 highestSfb;
/* for short: regroup and */
/* cumulate energies und thresholds group-wise . */
/* calculate sfbCnt */
highestSfb = 0;
for (wnd=0; wnd<TRANS_FAC; wnd++) {
for (sfb=sfbCnt - 1; sfb>=highestSfb; sfb--) {
for (line=(sfbOffset[sfb + 1] - 1); line>=sfbOffset[sfb]; line--) {
if (mdctSpectrum[wnd*FRAME_LEN_SHORT+line] != 0) break;
}
if (line >= sfbOffset[sfb]) break;
}
highestSfb = max(highestSfb, sfb);
}
if (highestSfb < 0) {
highestSfb = 0;
}
*maxSfbPerGroup = highestSfb + 1;
/* calculate sfbOffset */
i = 0;
offset = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
groupedSfbOffset[i] = offset + sfbOffset[sfb] * groupLen[grp];
i += 1;
}
offset += groupLen[grp] * FRAME_LEN_SHORT;
}
groupedSfbOffset[i] = FRAME_LEN_LONG;
i += 1;
/* calculate minSnr */
i = 0;
offset = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
groupedSfbMinSnr[i] = sfbMinSnr[sfb];
i += 1;
}
offset += groupLen[grp] * FRAME_LEN_SHORT;
}
/* sum up sfbThresholds */
wnd = 0;
i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
Word32 thresh = sfbThreshold->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
thresh = L_add(thresh, sfbThreshold->sfbShort[wnd+j][sfb]);
}
sfbThreshold->sfbLong[i] = thresh;
i += 1;
}
wnd += groupLen[grp];
}
/* sum up sfbEnergies left/right */
wnd = 0;
i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
Word32 energy = sfbEnergy->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
energy = L_add(energy, sfbEnergy->sfbShort[wnd+j][sfb]);
}
sfbEnergy->sfbLong[i] = energy;
i += 1;
}
wnd += groupLen[grp];
}
/* sum up sfbEnergies mid/side */
wnd = 0;
i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
Word32 energy = sfbEnergyMS->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
energy = L_add(energy, sfbEnergyMS->sfbShort[wnd+j][sfb]);
}
sfbEnergyMS->sfbLong[i] = energy;
i += 1;
}
wnd += groupLen[grp];
}
/* sum up sfbSpreadedEnergies */
wnd = 0;
i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
Word32 energy = sfbSpreadedEnergy->sfbShort[wnd][sfb];
for (j=1; j<groupLen[grp]; j++) {
energy = L_add(energy, sfbSpreadedEnergy->sfbShort[wnd+j][sfb]);
}
sfbSpreadedEnergy->sfbLong[i] = energy;
i += 1;
}
wnd += groupLen[grp];
}
/* re-group spectrum */
wnd = 0;
i = 0;
for (grp = 0; grp < noOfGroups; grp++) {
for (sfb = 0; sfb < sfbCnt; sfb++) {
for (j = 0; j < groupLen[grp]; j++) {
Word16 lineOffset = FRAME_LEN_SHORT * (wnd + j);
for (line = lineOffset + sfbOffset[sfb]; line < lineOffset + sfbOffset[sfb+1]; line++) {
tmpSpectrum[i] = mdctSpectrum[line];
i = i + 1;
}
}
}
wnd += groupLen[grp];
}
for(i=0;i<FRAME_LEN_LONG;i+=4) {
mdctSpectrum[i] = tmpSpectrum[i];
mdctSpectrum[i+1] = tmpSpectrum[i+1];
mdctSpectrum[i+2] = tmpSpectrum[i+2];
mdctSpectrum[i+3] = tmpSpectrum[i+3];
}
}

44
aacenc/external/aacenc/src/grp_data.h vendored Normal file
View file

@ -0,0 +1,44 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: grp_data.h
Content: Short block grouping function
*******************************************************************************/
#ifndef __GRP_DATA_H__
#define __GRP_DATA_H__
#include "psy_data.h"
#include "typedefs.h"
void
groupShortData(Word32 *mdctSpectrum,
Word32 *tmpSpectrum,
SFB_THRESHOLD *sfbThreshold,
SFB_ENERGY *sfbEnergy,
SFB_ENERGY *sfbEnergyMS,
SFB_ENERGY *sfbSpreadedEnergy,
const Word16 sfbCnt,
const Word16 *sfbOffset,
const Word16 *sfbMinSnr,
Word16 *groupedSfbOffset,
Word16 *maxSfbPerGroup,
Word16 *groupedSfbMinSnr,
const Word16 noOfGroups,
const Word16 *groupLen);
#endif /* _INTERFACE_H */

112
aacenc/external/aacenc/src/interface.c vendored Normal file
View file

@ -0,0 +1,112 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: interface.c
Content: Interface psychoaccoustic/quantizer functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "psy_const.h"
#include "interface.h"
/*****************************************************************************
*
* function name: BuildInterface
* description: update output parameter
*
**********************************************************************************/
void BuildInterface(Word32 *groupedMdctSpectrum,
const Word16 mdctScale,
SFB_THRESHOLD *groupedSfbThreshold,
SFB_ENERGY *groupedSfbEnergy,
SFB_ENERGY *groupedSfbSpreadedEnergy,
const SFB_ENERGY_SUM sfbEnergySumLR,
const SFB_ENERGY_SUM sfbEnergySumMS,
const Word16 windowSequence,
const Word16 windowShape,
const Word16 groupedSfbCnt,
const Word16 *groupedSfbOffset,
const Word16 maxSfbPerGroup,
const Word16 *groupedSfbMinSnr,
const Word16 noOfGroups,
const Word16 *groupLen,
PSY_OUT_CHANNEL *psyOutCh)
{
Word32 j;
Word32 grp;
Word32 mask;
Word16 *tmpV;
/*
copy values to psyOut
*/
psyOutCh->maxSfbPerGroup = maxSfbPerGroup;
psyOutCh->sfbCnt = groupedSfbCnt;
if(noOfGroups)
psyOutCh->sfbPerGroup = groupedSfbCnt/ noOfGroups;
else
psyOutCh->sfbPerGroup = 0x7fff;
psyOutCh->windowSequence = windowSequence;
psyOutCh->windowShape = windowShape;
psyOutCh->mdctScale = mdctScale;
psyOutCh->mdctSpectrum = groupedMdctSpectrum;
psyOutCh->sfbEnergy = groupedSfbEnergy->sfbLong;
psyOutCh->sfbThreshold = groupedSfbThreshold->sfbLong;
psyOutCh->sfbSpreadedEnergy = groupedSfbSpreadedEnergy->sfbLong;
tmpV = psyOutCh->sfbOffsets;
for(j=0; j<groupedSfbCnt + 1; j++) {
*tmpV++ = groupedSfbOffset[j];
}
tmpV = psyOutCh->sfbMinSnr;
for(j=0;j<groupedSfbCnt; j++) {
*tmpV++ = groupedSfbMinSnr[j];
}
/* generate grouping mask */
mask = 0;
for (grp = 0; grp < noOfGroups; grp++) {
mask = mask << 1;
for (j=1; j<groupLen[grp]; j++) {
mask = mask << 1;
mask |= 1;
}
}
psyOutCh->groupingMask = mask;
if (windowSequence != SHORT_WINDOW) {
psyOutCh->sfbEnSumLR = sfbEnergySumLR.sfbLong;
psyOutCh->sfbEnSumMS = sfbEnergySumMS.sfbLong;
}
else {
Word32 i;
Word32 accuSumMS=0;
Word32 accuSumLR=0;
const Word32 *pSumMS = sfbEnergySumMS.sfbShort;
const Word32 *pSumLR = sfbEnergySumLR.sfbShort;
for (i=TRANS_FAC; i; i--) {
accuSumLR = L_add(accuSumLR, *pSumLR); pSumLR++;
accuSumMS = L_add(accuSumMS, *pSumMS); pSumMS++;
}
psyOutCh->sfbEnSumMS = accuSumMS;
psyOutCh->sfbEnSumLR = accuSumLR;
}
}

106
aacenc/external/aacenc/src/interface.h vendored Normal file
View file

@ -0,0 +1,106 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: interface.h
Content: psychoaccoustic/quantizer structures and interface
*******************************************************************************/
#ifndef _INTERFACE_H
#define _INTERFACE_H
#include "config.h"
#include "psy_const.h"
#include "psy_data.h"
#include "typedefs.h"
enum
{
MS_NONE = 0,
MS_SOME = 1,
MS_ALL = 2
};
enum
{
MS_ON = 1
};
struct TOOLSINFO {
Word16 msDigest;
Word16 msMask[MAX_GROUPED_SFB];
};
typedef struct {
Word16 sfbCnt;
Word16 sfbPerGroup;
Word16 maxSfbPerGroup;
Word16 windowSequence;
Word16 windowShape;
Word16 groupingMask;
Word16 sfbOffsets[MAX_GROUPED_SFB+1];
Word16 mdctScale;
Word32 *sfbEnergy;
Word32 *sfbSpreadedEnergy;
Word32 *sfbThreshold;
Word32 *mdctSpectrum;
Word32 sfbEnSumLR;
Word32 sfbEnSumMS;
Word32 sfbDist[MAX_GROUPED_SFB];
Word32 sfbDistNew[MAX_GROUPED_SFB];
Word16 sfbMinSnr[MAX_GROUPED_SFB];
Word16 minSfMaxQuant[MAX_GROUPED_SFB];
Word16 minScfCalculated[MAX_GROUPED_SFB];
Word16 prevScfLast[MAX_GROUPED_SFB];
Word16 prevScfNext[MAX_GROUPED_SFB];
Word16 deltaPeLast[MAX_GROUPED_SFB];
TNS_INFO tnsInfo;
} PSY_OUT_CHANNEL; /* Word16 size: 14 + 60(MAX_GROUPED_SFB) + 112(TNS_INFO) = 186 */
typedef struct {
struct TOOLSINFO toolsInfo;
Word16 groupedSfbOffset[MAX_CHANNELS][MAX_GROUPED_SFB+1]; /* plus one for last dummy offset ! */
Word16 groupedSfbMinSnr[MAX_CHANNELS][MAX_GROUPED_SFB];
} PSY_OUT_ELEMENT;
typedef struct {
/* information shared by both channels */
PSY_OUT_ELEMENT psyOutElement;
/* information specific to each channel */
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS];
}PSY_OUT;
void BuildInterface(Word32 *mdctSpectrum,
const Word16 mdctScale,
SFB_THRESHOLD *sfbThreshold,
SFB_ENERGY *sfbEnergy,
SFB_ENERGY *sfbSpreadedEnergy,
const SFB_ENERGY_SUM sfbEnergySumLR,
const SFB_ENERGY_SUM sfbEnergySumMS,
const Word16 windowSequence,
const Word16 windowShape,
const Word16 sfbCnt,
const Word16 *sfbOffset,
const Word16 maxSfbPerGroup,
const Word16 *groupedSfbMinSnr,
const Word16 noOfGroups,
const Word16 *groupLen,
PSY_OUT_CHANNEL *psyOutCh);
#endif /* _INTERFACE_H */

145
aacenc/external/aacenc/src/line_pe.c vendored Normal file
View file

@ -0,0 +1,145 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: line_pe.c
Content: Perceptual entropie module functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "typedef.h"
#include "line_pe.h"
static const Word16 C1_I = 12; /* log(8.0)/log(2) *4 */
static const Word32 C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
static const Word16 C3_I = 573; /* (1-C2/C1) *1024 */
/*****************************************************************************
*
* function name: prepareSfbPe
* description: constants that do not change during successive pe calculations
*
**********************************************************************************/
void prepareSfbPe(PE_DATA *peData,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels,
const Word16 peOffset)
{
Word32 sfbGrp, sfb;
Word32 ch;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];
for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
}
}
}
peData->offset = peOffset;
}
/*****************************************************************************
*
* function name: calcSfbPe
* description: constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
*
**********************************************************************************/
void calcSfbPe(PE_DATA *peData,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
const Word16 nChannels)
{
Word32 ch;
Word32 sfbGrp, sfb;
Word32 nLines4;
Word32 ldThr, ldRatio;
Word32 pe, constPart, nActiveLines;
peData->pe = peData->offset;
peData->constPart = 0;
peData->nActiveLines = 0;
for(ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
const Word32 *sfbThreshold = psyOutChan->sfbThreshold;
pe = 0;
constPart = 0;
nActiveLines = 0;
for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
Word32 nrg = sfbEnergy[sfbGrp+sfb];
Word32 thres = sfbThreshold[sfbGrp+sfb];
Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];
if (nrg > thres) {
ldThr = iLog4(thres);
ldRatio = sfbLDEn - ldThr;
nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
/* sfbPe = nl*log2(en/thr)*/
if (ldRatio >= C1_I) {
peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;
}
else {
/* sfbPe = nl*(c2 + c3*log2(en/thr))*/
peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(
(C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);
peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(
(C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);
nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;
}
peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
}
else {
peChanData->sfbPe[sfbGrp+sfb] = 0;
peChanData->sfbConstPart[sfbGrp+sfb] = 0;
peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
}
pe = pe + peChanData->sfbPe[sfbGrp+sfb];
constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
}
}
peChanData->pe = saturate(pe);
peChanData->constPart = saturate(constPart);
peChanData->nActiveLines = saturate(nActiveLines);
pe += peData->pe;
peData->pe = saturate(pe);
constPart += peData->constPart;
peData->constPart = saturate(constPart);
nActiveLines += peData->nActiveLines;
peData->nActiveLines = saturate(nActiveLines);
}
}

75
aacenc/external/aacenc/src/line_pe.h vendored Normal file
View file

@ -0,0 +1,75 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: line_pe.h
Content: Perceptual entropie module structure and functions
*******************************************************************************/
#ifndef __LINE_PE_H
#define __LINE_PE_H
#include "psy_const.h"
#include "interface.h"
typedef struct {
Word16 sfbLdEnergy[MAX_GROUPED_SFB]; /* 4*log(sfbEnergy)/log(2) */
Word16 sfbNLines4[MAX_GROUPED_SFB]; /* 4*number of relevant lines in sfb */
Word16 sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */
Word16 sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */
Word16 sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */
Word16 pe; /* sum of sfbPe */
Word16 constPart; /* sum of sfbConstPart */
Word16 nActiveLines; /* sum of sfbNActiveLines */
} PE_CHANNEL_DATA; /* size Word16: 303 */
typedef struct {
PE_CHANNEL_DATA peChannelData[MAX_CHANNELS];
Word16 pe;
Word16 constPart;
Word16 nActiveLines;
Word16 offset;
Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB];
Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB];
Word32 sfbPeFactors[MAX_CHANNELS][MAX_GROUPED_SFB];
} PE_DATA; /* size Word16: 303 + 4 + 120 + 240 = 667 */
void prepareSfbPe(PE_DATA *peData,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels,
const Word16 peOffset);
void calcSfbPe(PE_DATA *peData,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
const Word16 nChannels);
#endif

112
aacenc/external/aacenc/src/memalign.c vendored Normal file
View file

@ -0,0 +1,112 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: mem_align.c
Content: Memory alloc alignments functions
*******************************************************************************/
#include "memalign.h"
#ifdef _MSC_VER
#include <stddef.h>
#else
#include <stdint.h>
#endif
/*****************************************************************************
*
* function name: mem_malloc
* description: malloc the alignments memory
* returns: the point of the memory
*
**********************************************************************************/
void *
mem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment, unsigned int CodecID)
{
int ret;
unsigned char *mem_ptr;
VO_MEM_INFO MemInfo;
if (!alignment) {
MemInfo.Flag = 0;
MemInfo.Size = size + 1;
ret = pMemop->Alloc(CodecID, &MemInfo);
if(ret != 0)
return 0;
mem_ptr = (unsigned char *)MemInfo.VBuffer;
pMemop->Set(CodecID, mem_ptr, 0, size + 1);
*mem_ptr = (unsigned char)1;
return ((void *)(mem_ptr+1));
} else {
unsigned char *tmp;
MemInfo.Flag = 0;
MemInfo.Size = size + alignment;
ret = pMemop->Alloc(CodecID, &MemInfo);
if(ret != 0)
return 0;
tmp = (unsigned char *)MemInfo.VBuffer;
pMemop->Set(CodecID, tmp, 0, size + alignment);
mem_ptr =
(unsigned char *) ((intptr_t) (tmp + alignment - 1) &
(~((intptr_t) (alignment - 1))));
if (mem_ptr == tmp)
mem_ptr += alignment;
*(mem_ptr - 1) = (unsigned char) (mem_ptr - tmp);
return ((void *)mem_ptr);
}
return(0);
}
/*****************************************************************************
*
* function name: mem_free
* description: free the memory
*
*******************************************************************************/
void
mem_free(VO_MEM_OPERATOR *pMemop, void *mem_ptr, unsigned int CodecID)
{
unsigned char *ptr;
if (mem_ptr == 0)
return;
ptr = mem_ptr;
ptr -= *(ptr - 1);
pMemop->Free(CodecID, ptr);
}

35
aacenc/external/aacenc/src/memalign.h vendored Normal file
View file

@ -0,0 +1,35 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: memalign.h
Content: Memory alloc alignments functions
*******************************************************************************/
#ifndef __VO_AACENC_MEM_ALIGN_H__
#define __VO_AACENC_MEM_ALIGN_H__
#include "voMem.h"
#include "typedef.h"
extern void *mem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment, unsigned int CodecID);
extern void mem_free(VO_MEM_OPERATOR *pMemop, void *mem_ptr, unsigned int CodecID);
#endif /* __VO_MEM_ALIGN_H__ */

138
aacenc/external/aacenc/src/ms_stereo.c vendored Normal file
View file

@ -0,0 +1,138 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: ms_stereo.c
Content: MS stereo processing function
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "psy_const.h"
#include "ms_stereo.h"
/********************************************************************************
*
* function name: MsStereoProcessing
* description: detect use ms stereo or not
* if ((min(thrLn, thrRn)*min(thrLn, thrRn))/(enMn*enSn))
* >= ((thrLn *thrRn)/(enLn*enRn)) then ms stereo
*
**********************************************************************************/
void MsStereoProcessing(Word32 *sfbEnergyLeft,
Word32 *sfbEnergyRight,
const Word32 *sfbEnergyMid,
const Word32 *sfbEnergySide,
Word32 *mdctSpectrumLeft,
Word32 *mdctSpectrumRight,
Word32 *sfbThresholdLeft,
Word32 *sfbThresholdRight,
Word32 *sfbSpreadedEnLeft,
Word32 *sfbSpreadedEnRight,
Word16 *msDigest,
Word16 *msMask,
const Word16 sfbCnt,
const Word16 sfbPerGroup,
const Word16 maxSfbPerGroup,
const Word16 *sfbOffset) {
Word32 sfb,sfboffs, j;
Word32 msMaskTrueSomewhere = 0;
Word32 msMaskFalseSomewhere = 0;
for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) {
for (sfboffs=0;sfboffs<maxSfbPerGroup;sfboffs++) {
Word32 temp;
Word32 pnlr,pnms;
Word32 minThreshold;
Word32 thrL, thrR, nrgL, nrgR;
Word32 idx, shift;
idx = sfb + sfboffs;
thrL = sfbThresholdLeft[idx];
thrR = sfbThresholdRight[idx];
nrgL = sfbEnergyLeft[idx];
nrgR = sfbEnergyRight[idx];
minThreshold = min(thrL, thrR);
nrgL = max(nrgL,thrL) + 1;
shift = norm_l(nrgL);
nrgL = Div_32(thrL << shift, nrgL << shift);
nrgR = max(nrgR,thrR) + 1;
shift = norm_l(nrgR);
nrgR = Div_32(thrR << shift, nrgR << shift);
pnlr = fixmul(nrgL, nrgR);
nrgL = sfbEnergyMid[idx];
nrgR = sfbEnergySide[idx];
nrgL = max(nrgL,minThreshold) + 1;
shift = norm_l(nrgL);
nrgL = Div_32(minThreshold << shift, nrgL << shift);
nrgR = max(nrgR,minThreshold) + 1;
shift = norm_l(nrgR);
nrgR = Div_32(minThreshold << shift, nrgR << shift);
pnms = fixmul(nrgL, nrgR);
temp = (pnlr + 1) / ((pnms >> 8) + 1);
temp = pnms - pnlr;
if( temp > 0 ){
msMask[idx] = 1;
msMaskTrueSomewhere = 1;
for (j=sfbOffset[idx]; j<sfbOffset[idx+1]; j++) {
Word32 left, right;
left = (mdctSpectrumLeft[j] >> 1);
right = (mdctSpectrumRight[j] >> 1);
mdctSpectrumLeft[j] = left + right;
mdctSpectrumRight[j] = left - right;
}
sfbThresholdLeft[idx] = minThreshold;
sfbThresholdRight[idx] = minThreshold;
sfbEnergyLeft[idx] = sfbEnergyMid[idx];
sfbEnergyRight[idx] = sfbEnergySide[idx];
sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;
sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];
}
else {
msMask[idx] = 0;
msMaskFalseSomewhere = 1;
}
}
if ( msMaskTrueSomewhere ) {
if(msMaskFalseSomewhere ) {
*msDigest = SI_MS_MASK_SOME;
} else {
*msDigest = SI_MS_MASK_ALL;
}
} else {
*msDigest = SI_MS_MASK_NONE;
}
}
}

45
aacenc/external/aacenc/src/ms_stereo.h vendored Normal file
View file

@ -0,0 +1,45 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: ms_stereo.h
Content: Declaration MS stereo processing structure and functions
*******************************************************************************/
#ifndef __MS_STEREO_H__
#define __MS_STEREO_H__
#include "typedef.h"
void MsStereoProcessing(Word32 *sfbEnergyLeft,
Word32 *sfbEnergyRight,
const Word32 *sfbEnergyMid,
const Word32 *sfbEnergySide,
Word32 *mdctSpectrumLeft,
Word32 *mdctSpectrumRight,
Word32 *sfbThresholdLeft,
Word32 *sfbThresholdRight,
Word32 *sfbSpreadedEnLeft,
Word32 *sfbSpreadedEnRight,
Word16 *msDigest,
Word16 *msMask,
const Word16 sfbCnt,
const Word16 sfbPerGroup,
const Word16 maxSfbPerGroup,
const Word16 *sfbOffset);
#endif

363
aacenc/external/aacenc/src/oper_32b.c vendored Normal file
View file

@ -0,0 +1,363 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: oper_32b.c
Content: This file contains operations in double precision.
*******************************************************************************/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#define UNUSED(x) (void)(x)
/*****************************************************************************
* *
* Function L_Extract() *
* *
* Extract from a 32 bit integer two 16 bit DPF. *
* *
* Arguments: *
* *
* L_32 : 32 bit integer. *
* 0x8000 0000 <= L_32 <= 0x7fff ffff. *
* hi : b16 to b31 of L_32 *
* lo : (L_32 - hi<<16)>>1 *
*****************************************************************************
*/
void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)
{
*hi = extract_h (L_32);
*lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384));
return;
}
/*****************************************************************************
* *
* Function L_Comp() *
* *
* Compose from two 16 bit DPF a 32 bit integer. *
* *
* L_32 = hi<<16 + lo<<1 *
* *
* Arguments: *
* *
* hi msb *
* lo lsf (with sign) *
* *
* Return Value : *
* *
* 32 bit long signed integer (Word32) whose value falls in the *
* range : 0x8000 0000 <= L_32 <= 0x7fff fff0. *
* *
*****************************************************************************
*/
Word32 L_Comp (Word16 hi, Word16 lo)
{
Word32 L_32;
L_32 = L_deposit_h (hi);
return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */
}
/*****************************************************************************
* Function Mpy_32() *
* *
* Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
* *
* L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
* *
* This operation can also be viewed as the multiplication of two Q31 *
* number and the result is also in Q31. *
* *
* Arguments: *
* *
* hi1 hi part of first number *
* lo1 lo part of first number *
* hi2 hi part of second number *
* lo2 lo part of second number *
* *
*****************************************************************************
*/
Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
{
Word32 L_32;
L_32 = L_mult (hi1, hi2);
L_32 = L_mac (L_32, mult (hi1, lo2), 1);
L_32 = L_mac (L_32, mult (lo1, hi2), 1);
return (L_32);
}
/*****************************************************************************
* Function Mpy_32_16() *
* *
* Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
* by 2**15 *
* *
* *
* L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
* *
* Arguments: *
* *
* hi hi part of 32 bit number. *
* lo lo part of 32 bit number. *
* n 16 bit number. *
* *
*****************************************************************************
*/
Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
{
Word32 L_32;
L_32 = L_mult (hi, n);
L_32 = L_mac (L_32, mult (lo, n), 1);
return (L_32);
}
/*****************************************************************************
* *
* Function Name : Div_32 *
* *
* Purpose : *
* Fractional integer division of two 32 bit numbers. *
* L_num / L_denom. *
* L_num and L_denom must be positive and L_num < L_denom. *
* L_denom = denom_hi<<16 + denom_lo<<1 *
* denom_hi is a normalize number. *
* *
* Inputs : *
* *
* L_num *
* 32 bit long signed integer (Word32) whose value falls in the *
* range : 0x0000 0000 < L_num < L_denom *
* *
* L_denom = denom_hi<<16 + denom_lo<<1 (DPF) *
* *
* denom_hi *
* 16 bit positive normalized integer whose value falls in the *
* range : 0x4000 < hi < 0x7fff *
* denom_lo *
* 16 bit positive integer whose value falls in the *
* range : 0 < lo < 0x7fff *
* *
* Return Value : *
* *
* L_div *
* 32 bit long signed integer (Word32) whose value falls in the *
* range : 0x0000 0000 <= L_div <= 0x7fff ffff. *
* *
* Algorithm: *
* *
* - find = 1/L_denom. *
* First approximation: approx = 1 / denom_hi *
* 1/L_denom = approx * (2.0 - L_denom * approx ) *
* *
* - result = L_num * (1/L_denom) *
*****************************************************************************
*/
Word32 Div_32 (Word32 L_num, Word32 denom)
{
Word16 approx;
Word32 L_32;
/* First approximation: 1 / L_denom = 1/denom_hi */
approx = div_s ((Word16) 0x3fff, denom >> 16);
/* 1/L_denom = approx * (2.0 - L_denom * approx) */
L_32 = L_mpy_ls (denom, approx);
L_32 = L_sub ((Word32) 0x7fffffffL, L_32);
L_32 = L_mpy_ls (L_32, approx);
/* L_num * (1/L_denom) */
L_32 = MULHIGH(L_32, L_num);
L_32 = L_shl (L_32, 3);
return (L_32);
}
/*!
\brief calculates the log dualis times 4 of argument
iLog4(x) = (Word32)(4 * log(value)/log(2.0))
\return ilog4 value
*/
Word16 iLog4(Word32 value)
{
Word16 iLog4;
if(value != 0){
Word32 tmp;
Word16 tmp16;
iLog4 = norm_l(value);
tmp = (value << iLog4);
tmp16 = round16(tmp);
tmp = L_mult(tmp16, tmp16);
tmp16 = round16(tmp);
tmp = L_mult(tmp16, tmp16);
tmp16 = round16(tmp);
iLog4 = (-(iLog4 << 2) - norm_s(tmp16)) - 1;
}
else {
iLog4 = -128; /* -(INT_BITS*4); */
}
return iLog4;
}
#define step(shift) \
if ((0x40000000l >> shift) + root <= value) \
{ \
value -= (0x40000000l >> shift) + root; \
root = (root >> 1) | (0x40000000l >> shift); \
} else { \
root = root >> 1; \
}
Word32 rsqrt(Word32 value, /*!< Operand to square root (0.0 ... 1) */
Word32 accuracy) /*!< Number of valid bits that will be calculated */
{
Word32 root = 0;
Word32 scale;
UNUSED(accuracy);
if(value < 0)
return 0;
scale = norm_l(value);
if(scale & 1) scale--;
value <<= scale;
step( 0); step( 2); step( 4); step( 6);
step( 8); step(10); step(12); step(14);
step(16); step(18); step(20); step(22);
step(24); step(26); step(28); step(30);
scale >>= 1;
if (root < value)
++root;
root >>= scale;
return root* 46334;
}
static const Word32 pow2Table[POW2_TABLE_SIZE] = {
0x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da,
0x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6,
0x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073,
0x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a,
0x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492,
0x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac,
0x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359,
0x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2,
0x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac,
0x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba,
0x72dc8374, 0x728d015d, 0x723db650, 0x71eea226,
0x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368,
0x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710,
0x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9,
0x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057,
0x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398,
0x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485,
0x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c,
0x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6,
0x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065,
0x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92,
0x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad,
0x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41,
0x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb,
0x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65,
0x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b,
0x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12,
0x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26,
0x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7,
0x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c,
0x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61,
0x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea,
0x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c,
0x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474,
0x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83,
0x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef,
0x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70,
0x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4,
0x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd,
0x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0,
0x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786,
0x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b,
0x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c,
0x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c,
0x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00,
0x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c,
0x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c,
0x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8,
0x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d,
0x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b,
0x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0,
0x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee,
0x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6,
0x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b,
0x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0,
0x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a,
0x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d,
0x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead,
0x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580,
0x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517,
0x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da,
0x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839,
0x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8,
0x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9
};
/*!
\brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y
avoids integer division
\return
*/
Word32 pow2_xy(Word32 x, Word32 y)
{
UWord32 iPart;
UWord32 fPart;
Word32 res;
Word32 tmp;
tmp = -x;
iPart = tmp / y;
fPart = tmp - iPart*y;
iPart = min(iPart,INT_BITS-1);
res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart;
return(res);
}

89
aacenc/external/aacenc/src/oper_32b.h vendored Normal file
View file

@ -0,0 +1,89 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: oper_32b.h
Content: Double precision operations
*******************************************************************************/
#ifndef __OPER_32b_H
#define __OPER_32b_H
#include "typedef.h"
#ifdef __cplusplus
extern "C" {
#endif
#define POW2_TABLE_BITS 8
#define POW2_TABLE_SIZE (1<<POW2_TABLE_BITS)
void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo);
Word32 L_Comp (Word16 hi, Word16 lo);
Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);
Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n);
Word32 Div_32 (Word32 L_num, Word32 denom);
Word16 iLog4(Word32 value);
Word32 rsqrt(Word32 value, Word32 accuracy);
Word32 pow2_xy(Word32 x, Word32 y);
__inline Word32 L_mpy_ls(Word32 L_var2, Word16 var1)
{
unsigned short swLow1;
Word16 swHigh1;
Word32 l_var_out;
swLow1 = (unsigned short)(L_var2);
swHigh1 = (Word16)(L_var2 >> 16);
l_var_out = (long)swLow1 * (long)var1 >> 15;
l_var_out += swHigh1 * var1 << 1;
return(l_var_out);
}
__inline Word32 L_mpy_wx(Word32 L_var2, Word16 var1)
{
#if ARMV5TE_L_MPY_LS
Word32 result;
asm volatile(
"SMULWB %[result], %[L_var2], %[var1] \n"
:[result]"=r"(result)
:[L_var2]"r"(L_var2), [var1]"r"(var1)
);
return result;
#else
unsigned short swLow1;
Word16 swHigh1;
Word32 l_var_out;
swLow1 = (unsigned short)(L_var2);
swHigh1 = (Word16)(L_var2 >> 16);
l_var_out = (long)swLow1 * (long)var1 >> 16;
l_var_out += swHigh1 * var1;
return(l_var_out);
#endif
}
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,113 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: pre_echo_control.c
Content: Pre echo control functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "oper_32b.h"
#include "pre_echo_control.h"
/*****************************************************************************
*
* function name:InitPreEchoControl
* description: init pre echo control parameter
*
*****************************************************************************/
void InitPreEchoControl(Word32 *pbThresholdNm1,
Word16 numPb,
Word32 *pbThresholdQuiet)
{
Word16 pb;
for(pb=0; pb<numPb; pb++) {
pbThresholdNm1[pb] = pbThresholdQuiet[pb];
}
}
/*****************************************************************************
*
* function name:PreEchoControl
* description: update shreshold to avoid pre echo
* thr(n) = max(rpmin*thrq(n), min(thrq(n), rpelev*thrq1(n)))
*
*
*****************************************************************************/
void PreEchoControl(Word32 *pbThresholdNm1,
Word16 numPb,
Word32 maxAllowedIncreaseFactor,
Word16 minRemainingThresholdFactor,
Word32 *pbThreshold,
Word16 mdctScale,
Word16 mdctScalenm1)
{
Word32 i;
Word32 tmpThreshold1, tmpThreshold2;
Word32 scaling;
/* maxAllowedIncreaseFactor is hard coded to 2 */
(void)maxAllowedIncreaseFactor;
scaling = ((mdctScale - mdctScalenm1) << 1);
if ( scaling > 0 ) {
for(i = 0; i < numPb; i++) {
tmpThreshold1 = pbThresholdNm1[i] >> (scaling-1);
tmpThreshold2 = L_mpy_ls(pbThreshold[i], minRemainingThresholdFactor);
/* copy thresholds to internal memory */
pbThresholdNm1[i] = pbThreshold[i];
if(pbThreshold[i] > tmpThreshold1) {
pbThreshold[i] = tmpThreshold1;
}
if(tmpThreshold2 > pbThreshold[i]) {
pbThreshold[i] = tmpThreshold2;
}
}
}
else {
scaling = -scaling;
for(i = 0; i < numPb; i++) {
tmpThreshold1 = pbThresholdNm1[i] << 1;
tmpThreshold2 = L_mpy_ls(pbThreshold[i], minRemainingThresholdFactor);
/* copy thresholds to internal memory */
pbThresholdNm1[i] = pbThreshold[i];
if(((pbThreshold[i] >> scaling) > tmpThreshold1)) {
pbThreshold[i] = tmpThreshold1 << scaling;
}
if(tmpThreshold2 > pbThreshold[i]) {
pbThreshold[i] = tmpThreshold2;
}
}
}
}

View file

@ -0,0 +1,42 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: pre_echo_control.h
Content: Pre echo control functions
*******************************************************************************/
#ifndef __PRE_ECHO_CONTROL_H
#define __PRE_ECHO_CONTROL_H
#include "typedefs.h"
void InitPreEchoControl(Word32 *pbThresholdnm1,
Word16 numPb,
Word32 *pbThresholdQuiet);
void PreEchoControl(Word32 *pbThresholdNm1,
Word16 numPb,
Word32 maxAllowedIncreaseFactor,
Word16 minRemainingThresholdFactor,
Word32 *pbThreshold,
Word16 mdctScale,
Word16 mdctScalenm1);
#endif

View file

@ -0,0 +1,505 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: psy_configuration.c
Content: Psychoaccoustic configuration functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "psy_configuration.h"
#include "adj_thr.h"
#include "aac_rom.h"
#define BARC_SCALE 100 /* integer barc values are scaled with 100 */
#define LOG2_1000 301 /* log2*1000 */
#define PI2_1000 1571 /* pi/2*1000*/
#define ATAN_COEF1 3560 /* 1000/0.280872f*/
#define ATAN_COEF2 281 /* 1000*0.280872f*/
typedef struct{
Word32 sampleRate;
const UWord8 *paramLong;
const UWord8 *paramShort;
}SFB_INFO_TAB;
static const Word16 ABS_LEV = 20;
static const Word16 BARC_THR_QUIET[] = {15, 10, 7, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3, 5, 10, 20, 30};
static const Word16 max_bark = 24; /* maximum bark-value */
static const Word16 maskLow = 30; /* in 1dB/bark */
static const Word16 maskHigh = 15; /* in 1*dB/bark */
static const Word16 c_ratio = 0x0029; /* pow(10.0f, -(29.0f/10.0f)) */
static const Word16 maskLowSprEnLong = 30; /* in 1dB/bark */
static const Word16 maskHighSprEnLong = 20; /* in 1dB/bark */
static const Word16 maskHighSprEnLongLowBr = 15; /* in 1dB/bark */
static const Word16 maskLowSprEnShort = 20; /* in 1dB/bark */
static const Word16 maskHighSprEnShort = 15; /* in 1dB/bark */
static const Word16 c_minRemainingThresholdFactor = 0x0148; /* 0.01 *(1 << 15)*/
static const Word32 c_maxsnr = 0x66666666; /* upper limit is -1 dB */
static const Word32 c_minsnr = 0x00624dd3; /* lower limit is -25 dB */
static const Word32 c_maxClipEnergyLong = 0x77359400; /* 2.0e9f*/
static const Word32 c_maxClipEnergyShort = 0x01dcd650; /* 2.0e9f/(AACENC_TRANS_FAC*AACENC_TRANS_FAC)*/
Word32 GetSRIndex(Word32 sampleRate)
{
if (92017 <= sampleRate) return 0;
if (75132 <= sampleRate) return 1;
if (55426 <= sampleRate) return 2;
if (46009 <= sampleRate) return 3;
if (37566 <= sampleRate) return 4;
if (27713 <= sampleRate) return 5;
if (23004 <= sampleRate) return 6;
if (18783 <= sampleRate) return 7;
if (13856 <= sampleRate) return 8;
if (11502 <= sampleRate) return 9;
if (9391 <= sampleRate) return 10;
return 11;
}
/*********************************************************************************
*
* function name: atan_1000
* description: calculates 1000*atan(x/1000)
* based on atan approx for x > 0
* atan(x) = x/((float)1.0f+(float)0.280872f*x*x) if x < 1
* = pi/2 - x/((float)0.280872f +x*x) if x >= 1
* return: 1000*atan(x/1000)
*
**********************************************************************************/
static Word16 atan_1000(Word32 val)
{
Word32 y;
if(L_sub(val, 1000) < 0) {
y = extract_l(((1000 * val) / (1000 + ((val * val) / ATAN_COEF1))));
}
else {
y = PI2_1000 - ((1000 * val) / (ATAN_COEF2 + ((val * val) / 1000)));
}
return extract_l(y);
}
/*****************************************************************************
*
* function name: BarcLineValue
* description: Calculates barc value for one frequency line
* returns: barc value of line * BARC_SCALE
* input: number of lines in transform, index of line to check, Fs
* output:
*
*****************************************************************************/
static Word16 BarcLineValue(Word16 noOfLines, Word16 fftLine, Word32 samplingFreq)
{
Word32 center_freq, temp, bvalFFTLine;
/* center frequency of fft line */
center_freq = (fftLine * samplingFreq) / (noOfLines << 1);
temp = atan_1000((center_freq << 2) / (3*10));
bvalFFTLine =
(26600 * atan_1000((center_freq*76) / 100) + 7*temp*temp) / (2*1000*1000 / BARC_SCALE);
return saturate(bvalFFTLine);
}
/*****************************************************************************
*
* function name: initThrQuiet
* description: init thredhold in quiet
*
*****************************************************************************/
static void initThrQuiet(Word16 numPb,
const Word16 *pbOffset,
Word16 *pbBarcVal,
Word32 *pbThresholdQuiet) {
Word16 i;
Word16 barcThrQuiet;
for(i=0; i<numPb; i++) {
Word16 bv1, bv2;
if (i>0)
bv1 = (pbBarcVal[i] + pbBarcVal[i-1]) >> 1;
else
bv1 = pbBarcVal[i] >> 1;
if (i < (numPb - 1))
bv2 = (pbBarcVal[i] + pbBarcVal[i+1]) >> 1;
else {
bv2 = pbBarcVal[i];
}
bv1 = min((bv1 / BARC_SCALE), max_bark);
bv2 = min((bv2 / BARC_SCALE), max_bark);
barcThrQuiet = min(BARC_THR_QUIET[bv1], BARC_THR_QUIET[bv2]);
/*
we calculate
pow(10.0f,(float)(barcThrQuiet - ABS_LEV)*0.1)*(float)ABS_LOW*(pbOffset[i+1] - pbOffset[i]);
*/
pbThresholdQuiet[i] = pow2_xy((((barcThrQuiet - ABS_LEV) * 100) +
LOG2_1000*(14+2*LOG_NORM_PCM)), LOG2_1000) * (pbOffset[i+1] - pbOffset[i]);
}
}
/*****************************************************************************
*
* function name: initSpreading
* description: init energy spreading parameter
*
*****************************************************************************/
static void initSpreading(Word16 numPb,
Word16 *pbBarcValue,
Word16 *pbMaskLoFactor,
Word16 *pbMaskHiFactor,
Word16 *pbMaskLoFactorSprEn,
Word16 *pbMaskHiFactorSprEn,
const Word32 bitrate,
const Word16 blockType)
{
Word16 i;
Word16 maskLowSprEn, maskHighSprEn;
if (sub(blockType, SHORT_WINDOW) != 0) {
maskLowSprEn = maskLowSprEnLong;
if (bitrate > 22000)
maskHighSprEn = maskHighSprEnLong;
else
maskHighSprEn = maskHighSprEnLongLowBr;
}
else {
maskLowSprEn = maskLowSprEnShort;
maskHighSprEn = maskHighSprEnShort;
}
for(i=0; i<numPb; i++) {
if (i > 0) {
Word32 dbVal;
Word16 dbark = pbBarcValue[i] - pbBarcValue[i-1];
/*
we calulate pow(10.0f, -0.1*dbVal/BARC_SCALE)
*/
dbVal = (maskHigh * dbark);
pbMaskHiFactor[i] = round16(pow2_xy(L_negate(dbVal), (Word32)LOG2_1000)); /* 0.301 log10(2) */
dbVal = (maskLow * dbark);
pbMaskLoFactor[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
dbVal = (maskHighSprEn * dbark);
pbMaskHiFactorSprEn[i] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
dbVal = (maskLowSprEn * dbark);
pbMaskLoFactorSprEn[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
}
else {
pbMaskHiFactor[i] = 0;
pbMaskLoFactor[numPb-1] = 0;
pbMaskHiFactorSprEn[i] = 0;
pbMaskLoFactorSprEn[numPb-1] = 0;
}
}
}
/*****************************************************************************
*
* function name: initBarcValues
* description: init bark value
*
*****************************************************************************/
static void initBarcValues(Word16 numPb,
const Word16 *pbOffset,
Word16 numLines,
Word32 samplingFrequency,
Word16 *pbBval)
{
Word16 i;
Word16 pbBval0, pbBval1;
pbBval0 = 0;
for(i=0; i<numPb; i++){
pbBval1 = BarcLineValue(numLines, pbOffset[i+1], samplingFrequency);
pbBval[i] = (pbBval0 + pbBval1) >> 1;
pbBval0 = pbBval1;
}
}
/*****************************************************************************
*
* function name: initMinSnr
* description: calculate min snr parameter
* minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)
*
*****************************************************************************/
static void initMinSnr(const Word32 bitrate,
const Word32 samplerate,
const Word16 numLines,
const Word16 *sfbOffset,
const Word16 *pbBarcVal,
const Word16 sfbActive,
Word16 *sfbMinSnr)
{
Word16 sfb;
Word16 barcWidth;
Word16 pePerWindow;
Word32 pePart;
Word32 snr;
Word16 pbVal0, pbVal1, shift;
/* relative number of active barks */
pePerWindow = bits2pe(extract_l((bitrate * numLines) / samplerate));
pbVal0 = 0;
for (sfb=0; sfb<sfbActive; sfb++) {
pbVal1 = (pbBarcVal[sfb] << 1) - pbVal0;
barcWidth = pbVal1 - pbVal0;
pbVal0 = pbVal1;
/* allow at least 2.4% of pe for each active barc */
pePart = ((pePerWindow * 24) * (max_bark * barcWidth)) /
(pbBarcVal[sfbActive-1] * (sfbOffset[sfb+1] - sfbOffset[sfb]));
pePart = min(pePart, 8400);
pePart = max(pePart, 1400);
/* minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)*/
/* we add an offset of 2^16 to the pow functions */
/* 0xc000 = 1.5*(1 << 15)*/
snr = pow2_xy((pePart - 16*1000),1000) - 0x0000c000;
if(snr > 0x00008000)
{
shift = norm_l(snr);
snr = Div_32(0x00008000 << shift, snr << shift);
}
else
{
snr = 0x7fffffff;
}
/* upper limit is -1 dB */
snr = min(snr, c_maxsnr);
/* lower limit is -25 dB */
snr = max(snr, c_minsnr);
sfbMinSnr[sfb] = round16(snr);
}
}
/*****************************************************************************
*
* function name: InitPsyConfigurationLong
* description: init long block psychoacoustic configuration
*
*****************************************************************************/
Word16 InitPsyConfigurationLong(Word32 bitrate,
Word32 samplerate,
Word16 bandwidth,
PSY_CONFIGURATION_LONG *psyConf)
{
Word32 samplerateindex;
Word16 sfbBarcVal[MAX_SFB_LONG];
Word16 sfb;
/*
init sfb table
*/
samplerateindex = GetSRIndex(samplerate);
psyConf->sfbCnt = sfBandTotalLong[samplerateindex];
psyConf->sfbOffset = sfBandTabLong + sfBandTabLongOffset[samplerateindex];
psyConf->sampRateIdx = samplerateindex;
/*
calculate barc values for each pb
*/
initBarcValues(psyConf->sfbCnt,
psyConf->sfbOffset,
psyConf->sfbOffset[psyConf->sfbCnt],
samplerate,
sfbBarcVal);
/*
init thresholds in quiet
*/
initThrQuiet(psyConf->sfbCnt,
psyConf->sfbOffset,
sfbBarcVal,
psyConf->sfbThresholdQuiet);
/*
calculate spreading function
*/
initSpreading(psyConf->sfbCnt,
sfbBarcVal,
psyConf->sfbMaskLowFactor,
psyConf->sfbMaskHighFactor,
psyConf->sfbMaskLowFactorSprEn,
psyConf->sfbMaskHighFactorSprEn,
bitrate,
LONG_WINDOW);
/*
init ratio
*/
psyConf->ratio = c_ratio;
psyConf->maxAllowedIncreaseFactor = 2;
psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor; /* 0.01 *(1 << 15)*/
psyConf->clipEnergy = c_maxClipEnergyLong;
psyConf->lowpassLine = extract_l((bandwidth<<1) * FRAME_LEN_LONG / samplerate);
for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
if (sub(psyConf->sfbOffset[sfb], psyConf->lowpassLine) >= 0)
break;
}
psyConf->sfbActive = sfb;
/*
calculate minSnr
*/
initMinSnr(bitrate,
samplerate,
psyConf->sfbOffset[psyConf->sfbCnt],
psyConf->sfbOffset,
sfbBarcVal,
psyConf->sfbActive,
psyConf->sfbMinSnr);
return(0);
}
/*****************************************************************************
*
* function name: InitPsyConfigurationShort
* description: init short block psychoacoustic configuration
*
*****************************************************************************/
Word16 InitPsyConfigurationShort(Word32 bitrate,
Word32 samplerate,
Word16 bandwidth,
PSY_CONFIGURATION_SHORT *psyConf)
{
Word32 samplerateindex;
Word16 sfbBarcVal[MAX_SFB_SHORT];
Word16 sfb;
/*
init sfb table
*/
samplerateindex = GetSRIndex(samplerate);
psyConf->sfbCnt = sfBandTotalShort[samplerateindex];
psyConf->sfbOffset = sfBandTabShort + sfBandTabShortOffset[samplerateindex];
psyConf->sampRateIdx = samplerateindex;
/*
calculate barc values for each pb
*/
initBarcValues(psyConf->sfbCnt,
psyConf->sfbOffset,
psyConf->sfbOffset[psyConf->sfbCnt],
samplerate,
sfbBarcVal);
/*
init thresholds in quiet
*/
initThrQuiet(psyConf->sfbCnt,
psyConf->sfbOffset,
sfbBarcVal,
psyConf->sfbThresholdQuiet);
/*
calculate spreading function
*/
initSpreading(psyConf->sfbCnt,
sfbBarcVal,
psyConf->sfbMaskLowFactor,
psyConf->sfbMaskHighFactor,
psyConf->sfbMaskLowFactorSprEn,
psyConf->sfbMaskHighFactorSprEn,
bitrate,
SHORT_WINDOW);
/*
init ratio
*/
psyConf->ratio = c_ratio;
psyConf->maxAllowedIncreaseFactor = 2;
psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;
psyConf->clipEnergy = c_maxClipEnergyShort;
psyConf->lowpassLine = extract_l(((bandwidth << 1) * FRAME_LEN_SHORT) / samplerate);
for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)
break;
}
psyConf->sfbActive = sfb;
/*
calculate minSnr
*/
initMinSnr(bitrate,
samplerate,
psyConf->sfbOffset[psyConf->sfbCnt],
psyConf->sfbOffset,
sfbBarcVal,
psyConf->sfbActive,
psyConf->sfbMinSnr);
return(0);
}

View file

@ -0,0 +1,107 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: psy_configuration.h
Content: Psychoaccoustic configuration structure and functions
*******************************************************************************/
#ifndef _PSY_CONFIGURATION_H
#define _PSY_CONFIGURATION_H
#include "typedefs.h"
#include "psy_const.h"
#include "tns.h"
typedef struct{
Word16 sfbCnt;
Word16 sfbActive; /* number of sf bands containing energy after lowpass */
const Word16 *sfbOffset;
Word32 sfbThresholdQuiet[MAX_SFB_LONG];
Word16 maxAllowedIncreaseFactor; /* preecho control */
Word16 minRemainingThresholdFactor;
Word16 lowpassLine;
Word16 sampRateIdx;
Word32 clipEnergy; /* for level dependend tmn */
Word16 ratio;
Word16 sfbMaskLowFactor[MAX_SFB_LONG];
Word16 sfbMaskHighFactor[MAX_SFB_LONG];
Word16 sfbMaskLowFactorSprEn[MAX_SFB_LONG];
Word16 sfbMaskHighFactorSprEn[MAX_SFB_LONG];
Word16 sfbMinSnr[MAX_SFB_LONG]; /* minimum snr (formerly known as bmax) */
TNS_CONFIG tnsConf;
}PSY_CONFIGURATION_LONG; /*Word16 size: 8 + 52 + 102 + 51 + 51 + 51 + 51 + 47 = 515 */
typedef struct{
Word16 sfbCnt;
Word16 sfbActive; /* number of sf bands containing energy after lowpass */
const Word16 *sfbOffset;
Word32 sfbThresholdQuiet[MAX_SFB_SHORT];
Word16 maxAllowedIncreaseFactor; /* preecho control */
Word16 minRemainingThresholdFactor;
Word16 lowpassLine;
Word16 sampRateIdx;
Word32 clipEnergy; /* for level dependend tmn */
Word16 ratio;
Word16 sfbMaskLowFactor[MAX_SFB_SHORT];
Word16 sfbMaskHighFactor[MAX_SFB_SHORT];
Word16 sfbMaskLowFactorSprEn[MAX_SFB_SHORT];
Word16 sfbMaskHighFactorSprEn[MAX_SFB_SHORT];
Word16 sfbMinSnr[MAX_SFB_SHORT]; /* minimum snr (formerly known as bmax) */
TNS_CONFIG tnsConf;
}PSY_CONFIGURATION_SHORT; /*Word16 size: 8 + 16 + 16 + 16 + 16 + 16 + 16 + 16 + 47 = 167 */
/* Returns the sample rate index */
Word32 GetSRIndex(Word32 sampleRate);
Word16 InitPsyConfigurationLong(Word32 bitrate,
Word32 samplerate,
Word16 bandwidth,
PSY_CONFIGURATION_LONG *psyConf);
Word16 InitPsyConfigurationShort(Word32 bitrate,
Word32 samplerate,
Word16 bandwidth,
PSY_CONFIGURATION_SHORT *psyConf);
#endif /* _PSY_CONFIGURATION_H */

80
aacenc/external/aacenc/src/psy_const.h vendored Normal file
View file

@ -0,0 +1,80 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: psy_const.h
Content: Global psychoacoustic constants structures
*******************************************************************************/
#ifndef _PSYCONST_H
#define _PSYCONST_H
#include "config.h"
#define TRUE 1
#define FALSE 0
#define FRAME_LEN_LONG AACENC_BLOCKSIZE
#define TRANS_FAC 8
#define FRAME_LEN_SHORT (FRAME_LEN_LONG/TRANS_FAC)
/* Block types */
enum
{
LONG_WINDOW = 0,
START_WINDOW,
SHORT_WINDOW,
STOP_WINDOW
};
/* Window shapes */
enum
{
SINE_WINDOW = 0,
KBD_WINDOW = 1
};
/*
MS stuff
*/
enum
{
SI_MS_MASK_NONE = 0,
SI_MS_MASK_SOME = 1,
SI_MS_MASK_ALL = 2
};
#define MAX_NO_OF_GROUPS 4
#define MAX_SFB_SHORT 15 /* 15 for a memory optimized implementation, maybe 16 for convenient debugging */
#define MAX_SFB_LONG 51 /* 51 for a memory optimized implementation, maybe 64 for convenient debugging */
#define MAX_SFB (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = MAX_SFB_LONG */
#define MAX_GROUPED_SFB (MAX_NO_OF_GROUPS*MAX_SFB_SHORT > MAX_SFB_LONG ? \
MAX_NO_OF_GROUPS*MAX_SFB_SHORT : MAX_SFB_LONG)
#define BLOCK_SWITCHING_OFFSET (1*1024+3*128+64+128)
#define BLOCK_SWITCHING_DATA_SIZE FRAME_LEN_LONG
#define TRANSFORM_OFFSET_LONG 0
#define TRANSFORM_OFFSET_SHORT 448
#define LOG_NORM_PCM -15
#define NUM_SAMPLE_RATES 12
#endif /* _PSYCONST_H */

66
aacenc/external/aacenc/src/psy_data.h vendored Normal file
View file

@ -0,0 +1,66 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: psy_data.h
Content: Psychoacoustic data and structures
*******************************************************************************/
#ifndef _PSY_DATA_H
#define _PSY_DATA_H
#include "block_switch.h"
#include "tns.h"
/*
the structs can be implemented as unions
*/
typedef struct{
Word32 sfbLong[MAX_GROUPED_SFB];
Word32 sfbShort[TRANS_FAC][MAX_SFB_SHORT];
}SFB_THRESHOLD; /* Word16 size: 260 */
typedef struct{
Word32 sfbLong[MAX_GROUPED_SFB];
Word32 sfbShort[TRANS_FAC][MAX_SFB_SHORT];
}SFB_ENERGY; /* Word16 size: 260 */
typedef struct{
Word32 sfbLong;
Word32 sfbShort[TRANS_FAC];
}SFB_ENERGY_SUM; /* Word16 size: 18 */
typedef struct{
BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */
Word16 *mdctDelayBuffer; /* mdct delay buffer [BLOCK_SWITCHING_OFFSET]*/
Word32 sfbThresholdnm1[MAX_SFB]; /* PreEchoControl */
Word16 mdctScalenm1; /* scale of last block's mdct (PreEchoControl) */
SFB_THRESHOLD sfbThreshold; /* adapt */
SFB_ENERGY sfbEnergy; /* sfb Energy */
SFB_ENERGY sfbEnergyMS;
SFB_ENERGY_SUM sfbEnergySum;
SFB_ENERGY_SUM sfbEnergySumMS;
SFB_ENERGY sfbSpreadedEnergy;
Word32 *mdctSpectrum; /* mdct spectrum [FRAME_LEN_LONG] */
Word16 mdctScale; /* scale of mdct */
}PSY_DATA; /* Word16 size: 4 + 87 + 102 + 360 + 360 + 360 + 18 + 18 + 360 = 1669 */
#endif /* _PSY_DATA_H */

815
aacenc/external/aacenc/src/psy_main.c vendored Normal file
View file

@ -0,0 +1,815 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: psy_main.c
Content: Psychoacoustic major functions
*******************************************************************************/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "psy_const.h"
#include "block_switch.h"
#include "transform.h"
#include "spreading.h"
#include "pre_echo_control.h"
#include "band_nrg.h"
#include "psy_configuration.h"
#include "psy_data.h"
#include "ms_stereo.h"
#include "interface.h"
#include "psy_main.h"
#include "grp_data.h"
#include "tns_func.h"
#include "memalign.h"
#define UNUSED(x) (void)(x)
/* long start short stop */
static Word16 blockType2windowShape[] = {KBD_WINDOW,SINE_WINDOW,SINE_WINDOW,KBD_WINDOW};
/*
forward definitions
*/
static Word16 advancePsychLong(PSY_DATA* psyData,
TNS_DATA* tnsData,
PSY_CONFIGURATION_LONG *hPsyConfLong,
PSY_OUT_CHANNEL* psyOutChannel,
Word32 *pScratchTns,
const TNS_DATA *tnsData2,
const Word16 ch);
static Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS],
const PSY_CONFIGURATION_LONG *hPsyConfLong);
static Word16 advancePsychShort(PSY_DATA* psyData,
TNS_DATA* tnsData,
const PSY_CONFIGURATION_SHORT *hPsyConfShort,
PSY_OUT_CHANNEL* psyOutChannel,
Word32 *pScratchTns,
const TNS_DATA *tnsData2,
const Word16 ch);
static Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS],
const PSY_CONFIGURATION_SHORT *hPsyConfShort);
/*****************************************************************************
*
* function name: PsyNew
* description: allocates memory for psychoacoustic
* returns: an error code
* input: pointer to a psych handle
*
*****************************************************************************/
Word16 PsyNew(PSY_KERNEL *hPsy, Word32 nChan, VO_MEM_OPERATOR *pMemOP)
{
Word16 i;
Word32 *mdctSpectrum;
Word32 *scratchTNS;
Word16 *mdctDelayBuffer;
mdctSpectrum = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC);
if(NULL == mdctSpectrum)
return 1;
scratchTNS = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC);
if(NULL == scratchTNS)
{
return 1;
}
mdctDelayBuffer = (Word16 *)mem_malloc(pMemOP, nChan * BLOCK_SWITCHING_OFFSET * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
if(NULL == mdctDelayBuffer)
{
return 1;
}
for (i=0; i<nChan; i++){
hPsy->psyData[i].mdctDelayBuffer = mdctDelayBuffer + i*BLOCK_SWITCHING_OFFSET;
hPsy->psyData[i].mdctSpectrum = mdctSpectrum + i*FRAME_LEN_LONG;
}
hPsy->pScratchTns = scratchTNS;
return 0;
}
/*****************************************************************************
*
* function name: PsyDelete
* description: allocates memory for psychoacoustic
* returns: an error code
*
*****************************************************************************/
Word16 PsyDelete(PSY_KERNEL *hPsy, VO_MEM_OPERATOR *pMemOP)
{
Word32 nch;
if(hPsy)
{
if(hPsy->psyData[0].mdctDelayBuffer)
mem_free(pMemOP, hPsy->psyData[0].mdctDelayBuffer, VO_INDEX_ENC_AAC);
if(hPsy->psyData[0].mdctSpectrum)
mem_free(pMemOP, hPsy->psyData[0].mdctSpectrum, VO_INDEX_ENC_AAC);
for (nch=0; nch<MAX_CHANNELS; nch++){
hPsy->psyData[nch].mdctDelayBuffer = NULL;
hPsy->psyData[nch].mdctSpectrum = NULL;
}
if(hPsy->pScratchTns)
{
mem_free(pMemOP, hPsy->pScratchTns, VO_INDEX_ENC_AAC);
hPsy->pScratchTns = NULL;
}
}
return 0;
}
/*****************************************************************************
*
* function name: PsyOutNew
* description: allocates memory for psyOut struc
* returns: an error code
* input: pointer to a psych handle
*
*****************************************************************************/
Word16 PsyOutNew(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP)
{
pMemOP->Set(VO_INDEX_ENC_AAC, hPsyOut, 0, sizeof(PSY_OUT));
/*
alloc some more stuff, tbd
*/
return 0;
}
/*****************************************************************************
*
* function name: PsyOutDelete
* description: allocates memory for psychoacoustic
* returns: an error code
*
*****************************************************************************/
Word16 PsyOutDelete(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP)
{
UNUSED(hPsyOut);
UNUSED(pMemOP);
return 0;
}
/*****************************************************************************
*
* function name: psyMainInit
* description: initializes psychoacoustic
* returns: an error code
*
*****************************************************************************/
Word16 psyMainInit(PSY_KERNEL *hPsy,
Word32 sampleRate,
Word32 bitRate,
Word16 channels,
Word16 tnsMask,
Word16 bandwidth)
{
Word16 ch, err;
Word32 channelBitRate = bitRate/channels;
err = InitPsyConfigurationLong(channelBitRate,
sampleRate,
bandwidth,
&(hPsy->psyConfLong));
if (!err) {
hPsy->sampleRateIdx = hPsy->psyConfLong.sampRateIdx;
err = InitTnsConfigurationLong(bitRate, sampleRate, channels,
&hPsy->psyConfLong.tnsConf, &hPsy->psyConfLong, tnsMask&2);
}
if (!err)
err = InitPsyConfigurationShort(channelBitRate,
sampleRate,
bandwidth,
&hPsy->psyConfShort);
if (!err) {
err = InitTnsConfigurationShort(bitRate, sampleRate, channels,
&hPsy->psyConfShort.tnsConf, &hPsy->psyConfShort, tnsMask&1);
}
if (!err)
for(ch=0;ch < channels;ch++){
InitBlockSwitching(&hPsy->psyData[ch].blockSwitchingControl,
bitRate, channels);
InitPreEchoControl(hPsy->psyData[ch].sfbThresholdnm1,
hPsy->psyConfLong.sfbCnt,
hPsy->psyConfLong.sfbThresholdQuiet);
hPsy->psyData[ch].mdctScalenm1 = 0;
}
return(err);
}
/*****************************************************************************
*
* function name: psyMain
* description: psychoacoustic main function
* returns: an error code
*
* This function assumes that enough input data is in the modulo buffer.
*
*****************************************************************************/
Word16 psyMain(Word16 nChannels,
ELEMENT_INFO *elemInfo,
Word16 *timeSignal,
PSY_DATA psyData[MAX_CHANNELS],
TNS_DATA tnsData[MAX_CHANNELS],
PSY_CONFIGURATION_LONG *hPsyConfLong,
PSY_CONFIGURATION_SHORT *hPsyConfShort,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word32 *pScratchTns,
Word32 sampleRate)
{
Word16 maxSfbPerGroup[MAX_CHANNELS];
Word16 mdctScalingArray[MAX_CHANNELS];
Word16 ch; /* counts through channels */
Word16 sfb; /* counts through scalefactor bands */
Word16 line; /* counts through lines */
Word16 channels;
Word16 maxScale;
channels = elemInfo->nChannelsInEl;
maxScale = 0;
/* block switching */
for(ch = 0; ch < channels; ch++) {
BlockSwitching(&psyData[ch].blockSwitchingControl,
timeSignal+elemInfo->ChannelIndex[ch],
sampleRate,
nChannels);
}
/* synch left and right block type */
SyncBlockSwitching(&psyData[0].blockSwitchingControl,
&psyData[1].blockSwitchingControl,
channels);
/* transform
and get maxScale (max mdctScaling) for all channels */
for(ch=0; ch<channels; ch++) {
Transform_Real(psyData[ch].mdctDelayBuffer,
timeSignal+elemInfo->ChannelIndex[ch],
nChannels,
psyData[ch].mdctSpectrum,
&(mdctScalingArray[ch]),
psyData[ch].blockSwitchingControl.windowSequence);
maxScale = max(maxScale, mdctScalingArray[ch]);
}
/* common scaling for all channels */
for (ch=0; ch<channels; ch++) {
Word16 scaleDiff = maxScale - mdctScalingArray[ch];
if (scaleDiff > 0) {
Word32 *Spectrum = psyData[ch].mdctSpectrum;
for(line=0; line<FRAME_LEN_LONG; line++) {
*Spectrum = (*Spectrum) >> scaleDiff;
Spectrum++;
}
}
psyData[ch].mdctScale = maxScale;
}
for (ch=0; ch<channels; ch++) {
if(psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) {
/* update long block parameter */
advancePsychLong(&psyData[ch],
&tnsData[ch],
hPsyConfLong,
&psyOutChannel[ch],
pScratchTns,
&tnsData[1 - ch],
ch);
/* determine maxSfb */
for (sfb=hPsyConfLong->sfbCnt-1; sfb>=0; sfb--) {
for (line=hPsyConfLong->sfbOffset[sfb+1] - 1; line>=hPsyConfLong->sfbOffset[sfb]; line--) {
if (psyData[ch].mdctSpectrum[line] != 0) break;
}
if (line >= hPsyConfLong->sfbOffset[sfb]) break;
}
maxSfbPerGroup[ch] = sfb + 1;
/* Calc bandwise energies for mid and side channel
Do it only if 2 channels exist */
if (ch == 1)
advancePsychLongMS(psyData, hPsyConfLong);
}
else {
advancePsychShort(&psyData[ch],
&tnsData[ch],
hPsyConfShort,
&psyOutChannel[ch],
pScratchTns,
&tnsData[1 - ch],
ch);
/* Calc bandwise energies for mid and side channel
Do it only if 2 channels exist */
if (ch == 1)
advancePsychShortMS (psyData, hPsyConfShort);
}
}
/* group short data */
for(ch=0; ch<channels; ch++) {
if (psyData[ch].blockSwitchingControl.windowSequence == SHORT_WINDOW) {
groupShortData(psyData[ch].mdctSpectrum,
pScratchTns,
&psyData[ch].sfbThreshold,
&psyData[ch].sfbEnergy,
&psyData[ch].sfbEnergyMS,
&psyData[ch].sfbSpreadedEnergy,
hPsyConfShort->sfbCnt,
hPsyConfShort->sfbOffset,
hPsyConfShort->sfbMinSnr,
psyOutElement->groupedSfbOffset[ch],
&maxSfbPerGroup[ch],
psyOutElement->groupedSfbMinSnr[ch],
psyData[ch].blockSwitchingControl.noOfGroups,
psyData[ch].blockSwitchingControl.groupLen);
}
}
#if (MAX_CHANNELS>1)
/*
stereo Processing
*/
if (channels == 2) {
psyOutElement->toolsInfo.msDigest = MS_NONE;
maxSfbPerGroup[0] = maxSfbPerGroup[1] = max(maxSfbPerGroup[0], maxSfbPerGroup[1]);
if (psyData[0].blockSwitchingControl.windowSequence != SHORT_WINDOW)
MsStereoProcessing(psyData[0].sfbEnergy.sfbLong,
psyData[1].sfbEnergy.sfbLong,
psyData[0].sfbEnergyMS.sfbLong,
psyData[1].sfbEnergyMS.sfbLong,
psyData[0].mdctSpectrum,
psyData[1].mdctSpectrum,
psyData[0].sfbThreshold.sfbLong,
psyData[1].sfbThreshold.sfbLong,
psyData[0].sfbSpreadedEnergy.sfbLong,
psyData[1].sfbSpreadedEnergy.sfbLong,
(Word16*)&psyOutElement->toolsInfo.msDigest,
(Word16*)psyOutElement->toolsInfo.msMask,
hPsyConfLong->sfbCnt,
hPsyConfLong->sfbCnt,
maxSfbPerGroup[0],
(const Word16*)hPsyConfLong->sfbOffset);
else
MsStereoProcessing(psyData[0].sfbEnergy.sfbLong,
psyData[1].sfbEnergy.sfbLong,
psyData[0].sfbEnergyMS.sfbLong,
psyData[1].sfbEnergyMS.sfbLong,
psyData[0].mdctSpectrum,
psyData[1].mdctSpectrum,
psyData[0].sfbThreshold.sfbLong,
psyData[1].sfbThreshold.sfbLong,
psyData[0].sfbSpreadedEnergy.sfbLong,
psyData[1].sfbSpreadedEnergy.sfbLong,
(Word16*)&psyOutElement->toolsInfo.msDigest,
(Word16*)psyOutElement->toolsInfo.msMask,
psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt,
hPsyConfShort->sfbCnt,
maxSfbPerGroup[0],
(const Word16*)psyOutElement->groupedSfbOffset[0]);
}
#endif /* (MAX_CHANNELS>1) */
/*
build output
*/
for(ch=0;ch<channels;ch++) {
if (psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW)
BuildInterface(psyData[ch].mdctSpectrum,
psyData[ch].mdctScale,
&psyData[ch].sfbThreshold,
&psyData[ch].sfbEnergy,
&psyData[ch].sfbSpreadedEnergy,
psyData[ch].sfbEnergySum,
psyData[ch].sfbEnergySumMS,
psyData[ch].blockSwitchingControl.windowSequence,
blockType2windowShape[psyData[ch].blockSwitchingControl.windowSequence],
hPsyConfLong->sfbCnt,
hPsyConfLong->sfbOffset,
maxSfbPerGroup[ch],
hPsyConfLong->sfbMinSnr,
psyData[ch].blockSwitchingControl.noOfGroups,
psyData[ch].blockSwitchingControl.groupLen,
&psyOutChannel[ch]);
else
BuildInterface(psyData[ch].mdctSpectrum,
psyData[ch].mdctScale,
&psyData[ch].sfbThreshold,
&psyData[ch].sfbEnergy,
&psyData[ch].sfbSpreadedEnergy,
psyData[ch].sfbEnergySum,
psyData[ch].sfbEnergySumMS,
SHORT_WINDOW,
SINE_WINDOW,
psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt,
psyOutElement->groupedSfbOffset[ch],
maxSfbPerGroup[ch],
psyOutElement->groupedSfbMinSnr[ch],
psyData[ch].blockSwitchingControl.noOfGroups,
psyData[ch].blockSwitchingControl.groupLen,
&psyOutChannel[ch]);
}
return(0); /* no error */
}
/*****************************************************************************
*
* function name: advancePsychLong
* description: psychoacoustic for long blocks
*
*****************************************************************************/
static Word16 advancePsychLong(PSY_DATA* psyData,
TNS_DATA* tnsData,
PSY_CONFIGURATION_LONG *hPsyConfLong,
PSY_OUT_CHANNEL* psyOutChannel,
Word32 *pScratchTns,
const TNS_DATA* tnsData2,
const Word16 ch)
{
Word32 i;
Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */
Word32 clipEnergy = hPsyConfLong->clipEnergy >> normEnergyShift;
Word32 *data0, *data1, tdata;
/* low pass */
data0 = psyData->mdctSpectrum + hPsyConfLong->lowpassLine;
for(i=hPsyConfLong->lowpassLine; i<FRAME_LEN_LONG; i++) {
*data0++ = 0;
}
/* Calc sfb-bandwise mdct-energies for left and right channel */
CalcBandEnergy( psyData->mdctSpectrum,
hPsyConfLong->sfbOffset,
hPsyConfLong->sfbActive,
psyData->sfbEnergy.sfbLong,
&psyData->sfbEnergySum.sfbLong);
/*
TNS detect
*/
TnsDetect(tnsData,
hPsyConfLong->tnsConf,
pScratchTns,
(const Word16*)hPsyConfLong->sfbOffset,
psyData->mdctSpectrum,
0,
psyData->blockSwitchingControl.windowSequence,
psyData->sfbEnergy.sfbLong);
/* TnsSync */
if (ch == 1) {
TnsSync(tnsData,
tnsData2,
hPsyConfLong->tnsConf,
0,
psyData->blockSwitchingControl.windowSequence);
}
/* Tns Encoder */
TnsEncode(&psyOutChannel->tnsInfo,
tnsData,
hPsyConfLong->sfbCnt,
hPsyConfLong->tnsConf,
hPsyConfLong->lowpassLine,
psyData->mdctSpectrum,
0,
psyData->blockSwitchingControl.windowSequence);
/* first part of threshold calculation */
data0 = psyData->sfbEnergy.sfbLong;
data1 = psyData->sfbThreshold.sfbLong;
for (i=hPsyConfLong->sfbCnt; i; i--) {
tdata = L_mpy_ls(*data0++, hPsyConfLong->ratio);
*data1++ = min(tdata, clipEnergy);
}
/* Calc sfb-bandwise mdct-energies for left and right channel again */
if (tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive!=0) {
Word16 tnsStartBand = hPsyConfLong->tnsConf.tnsStartBand;
CalcBandEnergy( psyData->mdctSpectrum,
hPsyConfLong->sfbOffset+tnsStartBand,
hPsyConfLong->sfbActive - tnsStartBand,
psyData->sfbEnergy.sfbLong+tnsStartBand,
&psyData->sfbEnergySum.sfbLong);
data0 = psyData->sfbEnergy.sfbLong;
tdata = psyData->sfbEnergySum.sfbLong;
for (i=0; i<tnsStartBand; i++)
tdata += *data0++;
psyData->sfbEnergySum.sfbLong = tdata;
}
/* spreading energy */
SpreadingMax(hPsyConfLong->sfbCnt,
hPsyConfLong->sfbMaskLowFactor,
hPsyConfLong->sfbMaskHighFactor,
psyData->sfbThreshold.sfbLong);
/* threshold in quiet */
data0 = psyData->sfbThreshold.sfbLong;
data1 = hPsyConfLong->sfbThresholdQuiet;
for (i=hPsyConfLong->sfbCnt; i; i--)
{
*data0 = max(*data0, (*data1 >> normEnergyShift));
data0++; data1++;
}
/* preecho control */
if (psyData->blockSwitchingControl.windowSequence == STOP_WINDOW) {
data0 = psyData->sfbThresholdnm1;
for (i=hPsyConfLong->sfbCnt; i; i--) {
*data0++ = MAX_32;
}
psyData->mdctScalenm1 = 0;
}
PreEchoControl( psyData->sfbThresholdnm1,
hPsyConfLong->sfbCnt,
hPsyConfLong->maxAllowedIncreaseFactor,
hPsyConfLong->minRemainingThresholdFactor,
psyData->sfbThreshold.sfbLong,
psyData->mdctScale,
psyData->mdctScalenm1);
psyData->mdctScalenm1 = psyData->mdctScale;
if (psyData->blockSwitchingControl.windowSequence== START_WINDOW) {
data0 = psyData->sfbThresholdnm1;
for (i=hPsyConfLong->sfbCnt; i; i--) {
*data0++ = MAX_32;
}
psyData->mdctScalenm1 = 0;
}
/* apply tns mult table on cb thresholds */
ApplyTnsMultTableToRatios(hPsyConfLong->tnsConf.tnsRatioPatchLowestCb,
hPsyConfLong->tnsConf.tnsStartBand,
tnsData->dataRaw.tnsLong.subBlockInfo,
psyData->sfbThreshold.sfbLong);
/* spreaded energy */
data0 = psyData->sfbSpreadedEnergy.sfbLong;
data1 = psyData->sfbEnergy.sfbLong;
for (i=hPsyConfLong->sfbCnt; i; i--) {
//psyData->sfbSpreadedEnergy.sfbLong[i] = psyData->sfbEnergy.sfbLong[i];
*data0++ = *data1++;
}
/* spreading energy */
SpreadingMax(hPsyConfLong->sfbCnt,
hPsyConfLong->sfbMaskLowFactorSprEn,
hPsyConfLong->sfbMaskHighFactorSprEn,
psyData->sfbSpreadedEnergy.sfbLong);
return 0;
}
/*****************************************************************************
*
* function name: advancePsychLongMS
* description: update mdct-energies for left add or minus right channel
* for long block
*
*****************************************************************************/
static Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS],
const PSY_CONFIGURATION_LONG *hPsyConfLong)
{
CalcBandEnergyMS(psyData[0].mdctSpectrum,
psyData[1].mdctSpectrum,
hPsyConfLong->sfbOffset,
hPsyConfLong->sfbActive,
psyData[0].sfbEnergyMS.sfbLong,
&psyData[0].sfbEnergySumMS.sfbLong,
psyData[1].sfbEnergyMS.sfbLong,
&psyData[1].sfbEnergySumMS.sfbLong);
return 0;
}
/*****************************************************************************
*
* function name: advancePsychShort
* description: psychoacoustic for short blocks
*
*****************************************************************************/
static Word16 advancePsychShort(PSY_DATA* psyData,
TNS_DATA* tnsData,
const PSY_CONFIGURATION_SHORT *hPsyConfShort,
PSY_OUT_CHANNEL* psyOutChannel,
Word32 *pScratchTns,
const TNS_DATA *tnsData2,
const Word16 ch)
{
Word32 w;
Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */
Word32 clipEnergy = hPsyConfShort->clipEnergy >> normEnergyShift;
Word32 wOffset = 0;
Word32 *data0;
const Word32 *data1;
for(w = 0; w < TRANS_FAC; w++) {
Word32 i, tdata;
/* low pass */
data0 = psyData->mdctSpectrum + wOffset + hPsyConfShort->lowpassLine;
for(i=hPsyConfShort->lowpassLine; i<FRAME_LEN_SHORT; i++){
*data0++ = 0;
}
/* Calc sfb-bandwise mdct-energies for left and right channel */
CalcBandEnergy( psyData->mdctSpectrum+wOffset,
hPsyConfShort->sfbOffset,
hPsyConfShort->sfbActive,
psyData->sfbEnergy.sfbShort[w],
&psyData->sfbEnergySum.sfbShort[w]);
/*
TNS
*/
TnsDetect(tnsData,
hPsyConfShort->tnsConf,
pScratchTns,
(const Word16*)hPsyConfShort->sfbOffset,
psyData->mdctSpectrum+wOffset,
w,
psyData->blockSwitchingControl.windowSequence,
psyData->sfbEnergy.sfbShort[w]);
/* TnsSync */
if (ch == 1) {
TnsSync(tnsData,
tnsData2,
hPsyConfShort->tnsConf,
w,
psyData->blockSwitchingControl.windowSequence);
}
TnsEncode(&psyOutChannel->tnsInfo,
tnsData,
hPsyConfShort->sfbCnt,
hPsyConfShort->tnsConf,
hPsyConfShort->lowpassLine,
psyData->mdctSpectrum+wOffset,
w,
psyData->blockSwitchingControl.windowSequence);
/* first part of threshold calculation */
data0 = psyData->sfbThreshold.sfbShort[w];
data1 = psyData->sfbEnergy.sfbShort[w];
for (i=hPsyConfShort->sfbCnt; i; i--) {
tdata = L_mpy_ls(*data1++, hPsyConfShort->ratio);
*data0++ = min(tdata, clipEnergy);
}
/* Calc sfb-bandwise mdct-energies for left and right channel again */
if (tnsData->dataRaw.tnsShort.subBlockInfo[w].tnsActive != 0) {
Word16 tnsStartBand = hPsyConfShort->tnsConf.tnsStartBand;
CalcBandEnergy( psyData->mdctSpectrum+wOffset,
hPsyConfShort->sfbOffset+tnsStartBand,
(hPsyConfShort->sfbActive - tnsStartBand),
psyData->sfbEnergy.sfbShort[w]+tnsStartBand,
&psyData->sfbEnergySum.sfbShort[w]);
tdata = psyData->sfbEnergySum.sfbShort[w];
data0 = psyData->sfbEnergy.sfbShort[w];
for (i=tnsStartBand; i; i--)
tdata += *data0++;
psyData->sfbEnergySum.sfbShort[w] = tdata;
}
/* spreading */
SpreadingMax(hPsyConfShort->sfbCnt,
hPsyConfShort->sfbMaskLowFactor,
hPsyConfShort->sfbMaskHighFactor,
psyData->sfbThreshold.sfbShort[w]);
/* threshold in quiet */
data0 = psyData->sfbThreshold.sfbShort[w];
data1 = hPsyConfShort->sfbThresholdQuiet;
for (i=hPsyConfShort->sfbCnt; i; i--)
{
*data0 = max(*data0, (*data1 >> normEnergyShift));
data0++; data1++;
}
/* preecho */
PreEchoControl( psyData->sfbThresholdnm1,
hPsyConfShort->sfbCnt,
hPsyConfShort->maxAllowedIncreaseFactor,
hPsyConfShort->minRemainingThresholdFactor,
psyData->sfbThreshold.sfbShort[w],
psyData->mdctScale,
w==0 ? psyData->mdctScalenm1 : psyData->mdctScale);
/* apply tns mult table on cb thresholds */
ApplyTnsMultTableToRatios( hPsyConfShort->tnsConf.tnsRatioPatchLowestCb,
hPsyConfShort->tnsConf.tnsStartBand,
tnsData->dataRaw.tnsShort.subBlockInfo[w],
psyData->sfbThreshold.sfbShort[w]);
/* spreaded energy */
data0 = psyData->sfbSpreadedEnergy.sfbShort[w];
data1 = psyData->sfbEnergy.sfbShort[w];
for (i=hPsyConfShort->sfbCnt; i; i--) {
*data0++ = *data1++;
}
SpreadingMax(hPsyConfShort->sfbCnt,
hPsyConfShort->sfbMaskLowFactorSprEn,
hPsyConfShort->sfbMaskHighFactorSprEn,
psyData->sfbSpreadedEnergy.sfbShort[w]);
wOffset += FRAME_LEN_SHORT;
} /* for TRANS_FAC */
psyData->mdctScalenm1 = psyData->mdctScale;
return 0;
}
/*****************************************************************************
*
* function name: advancePsychShortMS
* description: update mdct-energies for left add or minus right channel
* for short block
*
*****************************************************************************/
static Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS],
const PSY_CONFIGURATION_SHORT *hPsyConfShort)
{
Word32 w, wOffset;
wOffset = 0;
for(w=0; w<TRANS_FAC; w++) {
CalcBandEnergyMS(psyData[0].mdctSpectrum+wOffset,
psyData[1].mdctSpectrum+wOffset,
hPsyConfShort->sfbOffset,
hPsyConfShort->sfbActive,
psyData[0].sfbEnergyMS.sfbShort[w],
&psyData[0].sfbEnergySumMS.sfbShort[w],
psyData[1].sfbEnergyMS.sfbShort[w],
&psyData[1].sfbEnergySumMS.sfbShort[w]);
wOffset += FRAME_LEN_SHORT;
}
return 0;
}

69
aacenc/external/aacenc/src/psy_main.h vendored Normal file
View file

@ -0,0 +1,69 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: psy_main.h
Content: Psychoacoustic major function block
*******************************************************************************/
#ifndef _PSYMAIN_H
#define _PSYMAIN_H
#include "psy_configuration.h"
#include "qc_data.h"
#include "memalign.h"
/*
psy kernel
*/
typedef struct {
PSY_CONFIGURATION_LONG psyConfLong; /* Word16 size: 515 */
PSY_CONFIGURATION_SHORT psyConfShort; /* Word16 size: 167 */
PSY_DATA psyData[MAX_CHANNELS]; /* Word16 size: MAX_CHANNELS*1669*/
TNS_DATA tnsData[MAX_CHANNELS]; /* Word16 size: MAX_CHANNELS*235 */
Word32* pScratchTns;
Word16 sampleRateIdx;
}PSY_KERNEL; /* Word16 size: 2587 / 4491 */
Word16 PsyNew( PSY_KERNEL *hPsy, Word32 nChan, VO_MEM_OPERATOR *pMemOP);
Word16 PsyDelete( PSY_KERNEL *hPsy, VO_MEM_OPERATOR *pMemOP);
Word16 PsyOutNew( PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP);
Word16 PsyOutDelete( PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP);
Word16 psyMainInit( PSY_KERNEL *hPsy,
Word32 sampleRate,
Word32 bitRate,
Word16 channels,
Word16 tnsMask,
Word16 bandwidth);
Word16 psyMain(Word16 nChannels, /*!< total number of channels */
ELEMENT_INFO *elemInfo,
Word16 *timeSignal, /*!< interleaved time signal */
PSY_DATA psyData[MAX_CHANNELS],
TNS_DATA tnsData[MAX_CHANNELS],
PSY_CONFIGURATION_LONG* psyConfLong,
PSY_CONFIGURATION_SHORT* psyConfShort,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word32 *pScratchTns,
Word32 sampleRate);
#endif /* _PSYMAIN_H */

143
aacenc/external/aacenc/src/qc_data.h vendored Normal file
View file

@ -0,0 +1,143 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: qc_data.h
Content: Quantizing & coding structures
*******************************************************************************/
#ifndef _QC_DATA_H
#define _QC_DATA_H
#include "psy_const.h"
#include "dyn_bits.h"
#include "adj_thr_data.h"
#define MAX_MODES 10
typedef enum {
MODE_INVALID = 0,
MODE_1, /* mono */
MODE_1_1, /* dual mono */
MODE_2 /* stereo */
} ENCODER_MODE;
typedef enum {
ID_SCE=0, /* Single Channel Element */
ID_CPE=1, /* Channel Pair Element */
ID_CCE=2, /* Coupling Channel Element */
ID_LFE=3, /* LFE Channel Element */
ID_DSE=4, /* current one DSE element for ancillary is supported */
ID_PCE=5,
ID_FIL=6,
ID_END=7
}ELEMENT_TYPE;
typedef struct {
ELEMENT_TYPE elType;
Word16 instanceTag;
Word16 nChannelsInEl;
Word16 ChannelIndex[MAX_CHANNELS];
} ELEMENT_INFO;
typedef struct {
Word32 paddingRest;
} PADDING;
/* Quantizing & coding stage */
struct QC_INIT{
ELEMENT_INFO *elInfo;
Word16 maxBits; /* maximum number of bits in reservoir */
Word16 averageBits; /* average number of bits we should use */
Word16 bitRes;
Word16 meanPe;
Word32 chBitrate;
Word16 maxBitFac;
Word32 bitrate;
PADDING padding;
};
typedef struct
{
Word16 *quantSpec; /* [FRAME_LEN_LONG]; */
UWord16 *maxValueInSfb; /* [MAX_GROUPED_SFB]; */
Word16 *scf; /* [MAX_GROUPED_SFB]; */
Word16 globalGain;
Word16 mdctScale;
Word16 groupingMask;
SECTION_DATA sectionData;
Word16 windowShape;
} QC_OUT_CHANNEL;
typedef struct
{
Word16 adtsUsed;
Word16 staticBitsUsed; /* for verification purposes */
Word16 dynBitsUsed; /* for verification purposes */
Word16 pe;
Word16 ancBitsUsed;
Word16 fillBits;
} QC_OUT_ELEMENT;
typedef struct
{
QC_OUT_CHANNEL qcChannel[MAX_CHANNELS];
QC_OUT_ELEMENT qcElement;
Word16 totStaticBitsUsed; /* for verification purposes */
Word16 totDynBitsUsed; /* for verification purposes */
Word16 totAncBitsUsed; /* for verification purposes */
Word16 totFillBits;
Word16 alignBits;
Word16 bitResTot;
Word16 averageBitsTot;
} QC_OUT;
typedef struct {
Word32 chBitrate;
Word16 averageBits; /* brutto -> look ancillary.h */
Word16 maxBits;
Word16 bitResLevel;
Word16 maxBitResBits;
Word16 relativeBits; /* Bits relative to total Bits scaled down by 2 */
} ELEMENT_BITS;
typedef struct
{
/* this is basically struct QC_INIT */
Word16 averageBitsTot;
Word16 maxBitsTot;
Word16 globStatBits;
Word16 nChannels;
Word16 bitResTot;
Word16 maxBitFac;
PADDING padding;
ELEMENT_BITS elementBits;
ADJ_THR_STATE adjThr;
Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB];
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB];
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB];
} QC_STATE;
#endif /* _QC_DATA_H */

578
aacenc/external/aacenc/src/qc_main.c vendored Normal file
View file

@ -0,0 +1,578 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: qc_main.c
Content: Quantizing & coding functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "qc_main.h"
#include "quantize.h"
#include "interface.h"
#include "adj_thr.h"
#include "sf_estim.h"
#include "stat_bits.h"
#include "bit_cnt.h"
#include "dyn_bits.h"
#include "channel_map.h"
#include "memalign.h"
#define UNUSED(x) (void)(x)
typedef enum{
FRAME_LEN_BYTES_MODULO = 1,
FRAME_LEN_BYTES_INT = 2
}FRAME_LEN_RESULT_MODE;
static const Word16 maxFillElemBits = 7 + 270*8;
/* forward declarations */
static Word16 calcMaxValueInSfb(Word16 sfbCnt,
Word16 maxSfbPerGroup,
Word16 sfbPerGroup,
Word16 sfbOffset[MAX_GROUPED_SFB],
Word16 quantSpectrum[FRAME_LEN_LONG],
UWord16 maxValue[MAX_GROUPED_SFB]);
/*****************************************************************************
*
* function name: calcFrameLen
* description: estimate the frame length according the bitrates
*
*****************************************************************************/
static Word16 calcFrameLen(Word32 bitRate,
Word32 sampleRate,
FRAME_LEN_RESULT_MODE mode)
{
Word32 result;
Word32 quot;
result = (FRAME_LEN_LONG >> 3) * bitRate;
quot = result / sampleRate;
if (mode == FRAME_LEN_BYTES_MODULO) {
result -= quot * sampleRate;
}
else { /* FRAME_LEN_BYTES_INT */
result = quot;
}
return result;
}
/*****************************************************************************
*
* function name:framePadding
* description: Calculates if padding is needed for actual frame
* returns: paddingOn or not
*
*****************************************************************************/
static Word16 framePadding(Word32 bitRate,
Word32 sampleRate,
Word32 *paddingRest)
{
Word16 paddingOn;
Word16 difference;
paddingOn = 0;
difference = calcFrameLen( bitRate,
sampleRate,
FRAME_LEN_BYTES_MODULO );
*paddingRest = *paddingRest - difference;
if (*paddingRest <= 0 ) {
paddingOn = 1;
*paddingRest = *paddingRest + sampleRate;
}
return paddingOn;
}
/*********************************************************************************
*
* function name: QCOutNew
* description: init qcout parameter
* returns: 0 if success
*
**********************************************************************************/
Word16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP)
{
Word32 i;
Word16 *quantSpec;
Word16 *scf;
UWord16 *maxValueInSfb;
quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
if(NULL == quantSpec)
return 1;
scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
if(NULL == scf)
{
return 1;
}
maxValueInSfb = (UWord16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(UWord16), 32, VO_INDEX_ENC_AAC);
if(NULL == maxValueInSfb)
{
return 1;
}
for (i=0; i<nChannels; i++) {
hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG;
hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB;
hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB;
}
return 0;
}
/*********************************************************************************
*
* function name: QCOutDelete
* description: unint qcout parameter
* returns: 0 if success
*
**********************************************************************************/
void QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP)
{
Word32 i;
if(hQC)
{
if(hQC->qcChannel[0].quantSpec)
mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);
if(hQC->qcChannel[0].maxValueInSfb)
mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC);
if(hQC->qcChannel[0].scf)
mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC);
for (i=0; i<MAX_CHANNELS; i++) {
hQC->qcChannel[i].quantSpec = NULL;
hQC->qcChannel[i].maxValueInSfb = NULL;
hQC->qcChannel[i].scf = NULL;
}
}
}
/*********************************************************************************
*
* function name: QCNew
* description: set QC to zero
* returns: 0 if success
*
**********************************************************************************/
Word16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
{
pMemOP->Set(VO_INDEX_ENC_AAC, hQC,0,sizeof(QC_STATE));
return (0);
}
/*********************************************************************************
*
* function name: QCDelete
* description: unint qcout parameter
*
**********************************************************************************/
void QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
{
UNUSED(hQC);
UNUSED(pMemOP);
}
/*********************************************************************************
*
* function name: QCInit
* description: init QD parameter
* returns: 0 if success
*
**********************************************************************************/
Word16 QCInit(QC_STATE *hQC,
struct QC_INIT *init)
{
hQC->nChannels = init->elInfo->nChannelsInEl;
hQC->maxBitsTot = init->maxBits;
hQC->bitResTot = sub(init->bitRes, init->averageBits);
hQC->averageBitsTot = init->averageBits;
hQC->maxBitFac = init->maxBitFac;
hQC->padding.paddingRest = init->padding.paddingRest;
hQC->globStatBits = 3; /* for ID_END */
/* channel elements init */
InitElementBits(&hQC->elementBits,
*init->elInfo,
init->bitrate,
init->averageBits,
hQC->globStatBits);
/* threshold parameter init */
AdjThrInit(&hQC->adjThr,
init->meanPe,
hQC->elementBits.chBitrate);
return 0;
}
/*********************************************************************************
*
* function name: QCMain
* description: quantization and coding the spectrum
* returns: 0 if success
*
**********************************************************************************/
Word16 QCMain(QC_STATE* hQC,
ELEMENT_BITS* elBits,
ATS_ELEMENT* adjThrStateElement,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], /* may be modified in-place */
PSY_OUT_ELEMENT* psyOutElement,
QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS], /* out */
QC_OUT_ELEMENT* qcOutElement,
Word16 nChannels,
Word16 ancillaryDataBytes)
{
Word16 maxChDynBits[MAX_CHANNELS];
Word16 chBitDistribution[MAX_CHANNELS];
Word32 ch;
if (elBits->bitResLevel < 0) {
return -1;
}
if (elBits->bitResLevel > elBits->maxBitResBits) {
return -1;
}
qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel,
psyOutElement,
nChannels,
qcOutElement->adtsUsed);
if (ancillaryDataBytes) {
qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3);
if (ancillaryDataBytes >= 15)
qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8;
}
else {
qcOutElement->ancBitsUsed = 0;
}
CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels);
/*adjust thresholds for the desired bitrate */
AdjustThresholds(&hQC->adjThr,
adjThrStateElement,
psyOutChannel,
psyOutElement,
chBitDistribution,
hQC->logSfbEnergy,
hQC->sfbNRelevantLines,
qcOutElement,
elBits,
nChannels,
hQC->maxBitFac);
/*estimate scale factors */
EstimateScaleFactors(psyOutChannel,
qcOutChannel,
hQC->logSfbEnergy,
hQC->logSfbFormFactor,
hQC->sfbNRelevantLines,
nChannels);
/* condition to prevent empty bitreservoir */
for (ch = 0; ch < nChannels; ch++) {
Word32 maxDynBits;
maxDynBits = elBits->averageBits + elBits->bitResLevel - 7; /* -7 bec. of align bits */
maxDynBits = maxDynBits - qcOutElement->staticBitsUsed + qcOutElement->ancBitsUsed;
maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000);
}
qcOutElement->dynBitsUsed = 0;
for (ch = 0; ch < nChannels; ch++) {
Word32 chDynBits;
Flag constraintsFulfilled;
Word32 iter;
iter = 0;
do {
constraintsFulfilled = 1;
QuantizeSpectrum(psyOutChannel[ch].sfbCnt,
psyOutChannel[ch].maxSfbPerGroup,
psyOutChannel[ch].sfbPerGroup,
psyOutChannel[ch].sfbOffsets,
psyOutChannel[ch].mdctSpectrum,
qcOutChannel[ch].globalGain,
qcOutChannel[ch].scf,
qcOutChannel[ch].quantSpec);
if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt,
psyOutChannel[ch].maxSfbPerGroup,
psyOutChannel[ch].sfbPerGroup,
psyOutChannel[ch].sfbOffsets,
qcOutChannel[ch].quantSpec,
qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) {
constraintsFulfilled = 0;
}
chDynBits = dynBitCount(qcOutChannel[ch].quantSpec,
qcOutChannel[ch].maxValueInSfb,
qcOutChannel[ch].scf,
psyOutChannel[ch].windowSequence,
psyOutChannel[ch].sfbCnt,
psyOutChannel[ch].maxSfbPerGroup,
psyOutChannel[ch].sfbPerGroup,
psyOutChannel[ch].sfbOffsets,
&qcOutChannel[ch].sectionData);
if (chDynBits >= maxChDynBits[ch]) {
constraintsFulfilled = 0;
}
if (!constraintsFulfilled) {
qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1;
}
iter = iter + 1;
} while(!constraintsFulfilled);
qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits;
qcOutChannel[ch].mdctScale = psyOutChannel[ch].mdctScale;
qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask;
qcOutChannel[ch].windowShape = psyOutChannel[ch].windowShape;
}
/* save dynBitsUsed for correction of bits2pe relation */
AdjThrUpdate(adjThrStateElement, qcOutElement->dynBitsUsed);
{
Word16 bitResSpace = elBits->maxBitResBits - elBits->bitResLevel;
Word16 deltaBitRes = elBits->averageBits -
(qcOutElement->staticBitsUsed +
qcOutElement->dynBitsUsed + qcOutElement->ancBitsUsed);
qcOutElement->fillBits = max(0, (deltaBitRes - bitResSpace));
}
return 0; /* OK */
}
/*********************************************************************************
*
* function name: calcMaxValueInSfb
* description: search the max Spectrum in one sfb
*
**********************************************************************************/
static Word16 calcMaxValueInSfb(Word16 sfbCnt,
Word16 maxSfbPerGroup,
Word16 sfbPerGroup,
Word16 sfbOffset[MAX_GROUPED_SFB],
Word16 quantSpectrum[FRAME_LEN_LONG],
UWord16 maxValue[MAX_GROUPED_SFB])
{
Word16 sfbOffs, sfb;
Word16 maxValueAll;
maxValueAll = 0;
for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {
for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
Word16 line;
Word16 maxThisSfb;
maxThisSfb = 0;
for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) {
Word16 absVal;
absVal = abs_s(quantSpectrum[line]);
maxThisSfb = max(maxThisSfb, absVal);
}
maxValue[sfbOffs+sfb] = maxThisSfb;
maxValueAll = max(maxValueAll, maxThisSfb);
}
}
return maxValueAll;
}
/*********************************************************************************
*
* function name: updateBitres
* description: update bitreservoir
*
**********************************************************************************/
void updateBitres(QC_STATE* qcKernel,
QC_OUT* qcOut)
{
ELEMENT_BITS *elBits;
qcKernel->bitResTot = 0;
elBits = &qcKernel->elementBits;
if (elBits->averageBits > 0) {
/* constant bitrate */
Word16 bitsUsed;
bitsUsed = (qcOut->qcElement.staticBitsUsed + qcOut->qcElement.dynBitsUsed) +
(qcOut->qcElement.ancBitsUsed + qcOut->qcElement.fillBits);
elBits->bitResLevel = elBits->bitResLevel + (elBits->averageBits - bitsUsed);
qcKernel->bitResTot = qcKernel->bitResTot + elBits->bitResLevel;
}
else {
/* variable bitrate */
elBits->bitResLevel = elBits->maxBits;
qcKernel->bitResTot = qcKernel->maxBitsTot;
}
}
/*********************************************************************************
*
* function name: FinalizeBitConsumption
* description: count bits used
*
**********************************************************************************/
Word16 FinalizeBitConsumption(QC_STATE *qcKernel,
QC_OUT* qcOut)
{
Word32 nFullFillElem;
Word32 totFillBits;
Word16 diffBits;
Word16 bitsUsed;
totFillBits = 0;
qcOut->totStaticBitsUsed = qcKernel->globStatBits;
qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed;
qcOut->totDynBitsUsed = qcOut->qcElement.dynBitsUsed;
qcOut->totAncBitsUsed = qcOut->qcElement.ancBitsUsed;
qcOut->totFillBits = qcOut->qcElement.fillBits;
if (qcOut->qcElement.fillBits) {
totFillBits += qcOut->qcElement.fillBits;
}
nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits;
qcOut->totFillBits = qcOut->totFillBits - nFullFillElem;
/* check fill elements */
if (qcOut->totFillBits > 0) {
/* minimum Fillelement contains 7 (TAG + byte cnt) bits */
qcOut->totFillBits = max(7, qcOut->totFillBits);
/* fill element size equals n*8 + 7 */
qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007);
}
qcOut->totFillBits = qcOut->totFillBits + nFullFillElem;
/* now distribute extra fillbits and alignbits over channel elements */
qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed +
qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007);
if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) &&
(qcOut->totFillBits > 8))
qcOut->totFillBits = qcOut->totFillBits - 8;
diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits;
if(diffBits>=0) {
qcOut->qcElement.fillBits += diffBits;
}
bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed;
bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits;
if (bitsUsed > qcKernel->maxBitsTot) {
return -1;
}
return bitsUsed;
}
/*********************************************************************************
*
* function name: AdjustBitrate
* description: adjusts framelength via padding on a frame to frame basis,
* to achieve a bitrate that demands a non byte aligned
* framelength
* return: errorcode
*
**********************************************************************************/
Word16 AdjustBitrate(QC_STATE *hQC,
Word32 bitRate, /* total bitrate */
Word32 sampleRate) /* output sampling rate */
{
Word16 paddingOn;
Word16 frameLen;
Word16 codeBits;
Word16 codeBitsLast;
/* Do we need a extra padding byte? */
paddingOn = framePadding(bitRate,
sampleRate,
&hQC->padding.paddingRest);
/* frame length */
frameLen = paddingOn + calcFrameLen(bitRate,
sampleRate,
FRAME_LEN_BYTES_INT);
frameLen = frameLen << 3;
codeBitsLast = hQC->averageBitsTot - hQC->globStatBits;
codeBits = frameLen - hQC->globStatBits;
/* calculate bits for every channel element */
if (codeBits != codeBitsLast) {
Word16 totalBits = 0;
hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */
totalBits += hQC->elementBits.averageBits;
hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits);
}
hQC->averageBitsTot = frameLen;
return 0;
}

64
aacenc/external/aacenc/src/qc_main.h vendored Normal file
View file

@ -0,0 +1,64 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: qc_main.h
Content: Quantizing & coding functions
*******************************************************************************/
#ifndef _QC_MAIN_H
#define _QC_MAIN_H
#include "qc_data.h"
#include "interface.h"
#include "memalign.h"
/* Quantizing & coding stage */
Word16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP);
void QCOutDelete(QC_OUT *hQC, VO_MEM_OPERATOR *pMemOP);
Word16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP);
Word16 QCInit(QC_STATE *hQC,
struct QC_INIT *init);
void QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP);
Word16 QCMain(QC_STATE *hQC,
ELEMENT_BITS* elBits,
ATS_ELEMENT* adjThrStateElement,
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], /* may be modified in-place */
PSY_OUT_ELEMENT* psyOutElement,
QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS], /* out */
QC_OUT_ELEMENT* qcOutElement,
Word16 nChannels,
Word16 ancillaryDataBytes); /* returns error code */
void updateBitres(QC_STATE* qcKernel,
QC_OUT* qcOut);
Word16 FinalizeBitConsumption(QC_STATE *hQC,
QC_OUT* qcOut);
Word16 AdjustBitrate(QC_STATE *hQC,
Word32 bitRate,
Word32 sampleRate);
#endif /* _QC_MAIN_H */

445
aacenc/external/aacenc/src/quantize.c vendored Normal file
View file

@ -0,0 +1,445 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: quantize.c
Content: quantization functions
*******************************************************************************/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "quantize.h"
#include "aac_rom.h"
#define MANT_DIGITS 9
#define MANT_SIZE (1<<MANT_DIGITS)
static const Word32 XROUND = 0x33e425af; /* final rounding constant (-0.0946f+ 0.5f) */
/*****************************************************************************
*
* function name:pow34
* description: calculate $x^{\frac{3}{4}}, for 0.5 < x < 1.0$.
*
*****************************************************************************/
__inline Word32 pow34(Word32 x)
{
/* index table using MANT_DIGITS bits, but mask out the sign bit and the MSB
which is always one */
return mTab_3_4[(x >> (INT_BITS-2-MANT_DIGITS)) & (MANT_SIZE-1)];
}
/*****************************************************************************
*
* function name:quantizeSingleLine
* description: quantizes spectrum
* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)
*
*****************************************************************************/
static Word16 quantizeSingleLine(const Word16 gain, const Word32 absSpectrum)
{
Word32 e, minusFinalExp, finalShift;
Word32 x;
Word16 qua = 0;
if (absSpectrum) {
e = norm_l(absSpectrum);
x = pow34(absSpectrum << e);
/* calculate the final fractional exponent times 16 (was 3*(4*e + gain) + (INT_BITS-1)*16) */
minusFinalExp = (e << 2) + gain;
minusFinalExp = (minusFinalExp << 1) + minusFinalExp;
minusFinalExp = minusFinalExp + ((INT_BITS-1) << 4);
/* separate the exponent into a shift, and a multiply */
finalShift = minusFinalExp >> 4;
if (finalShift < INT_BITS) {
x = L_mpy_wx(x, pow2tominusNover16[minusFinalExp & 15]);
x += XROUND >> (INT_BITS - finalShift);
/* shift and quantize */
finalShift--;
if(finalShift >= 0)
x >>= finalShift;
else
x <<= (-finalShift);
qua = saturate(x);
}
}
return qua;
}
/*****************************************************************************
*
* function name:quantizeLines
* description: quantizes spectrum lines
* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)
* input: global gain, number of lines to process, spectral data
* output: quantized spectrum
*
*****************************************************************************/
static void quantizeLines(const Word16 gain,
const Word16 noOfLines,
const Word32 *mdctSpectrum,
Word16 *quaSpectrum)
{
Word32 line;
Word32 m = gain&3;
Word32 g = (gain >> 2) + 4;
Word32 mdctSpeL;
const Word16 *pquat;
/* gain&3 */
pquat = quantBorders[m];
g += 16;
if(g >= 0)
{
for (line=0; line<noOfLines; line++) {
Word32 qua;
qua = 0;
mdctSpeL = mdctSpectrum[line];
if (mdctSpeL) {
Word32 sa;
Word32 saShft;
sa = L_abs(mdctSpeL);
//saShft = L_shr(sa, 16 + g);
saShft = sa >> g;
if (saShft > pquat[0]) {
if (saShft < pquat[1]) {
qua = mdctSpeL>0 ? 1 : -1;
}
else {
if (saShft < pquat[2]) {
qua = mdctSpeL>0 ? 2 : -2;
}
else {
if (saShft < pquat[3]) {
qua = mdctSpeL>0 ? 3 : -3;
}
else {
qua = quantizeSingleLine(gain, sa);
/* adjust the sign. Since 0 < qua < 1, this cannot overflow. */
if (mdctSpeL < 0)
qua = -qua;
}
}
}
}
}
quaSpectrum[line] = qua ;
}
}
else
{
for (line=0; line<noOfLines; line++) {
Word32 qua;
qua = 0;
mdctSpeL = mdctSpectrum[line];
if (mdctSpeL) {
Word32 sa;
Word32 saShft;
sa = L_abs(mdctSpeL);
saShft = sa << g;
if (saShft > pquat[0]) {
if (saShft < pquat[1]) {
qua = mdctSpeL>0 ? 1 : -1;
}
else {
if (saShft < pquat[2]) {
qua = mdctSpeL>0 ? 2 : -2;
}
else {
if (saShft < pquat[3]) {
qua = mdctSpeL>0 ? 3 : -3;
}
else {
qua = quantizeSingleLine(gain, sa);
/* adjust the sign. Since 0 < qua < 1, this cannot overflow. */
if (mdctSpeL < 0)
qua = -qua;
}
}
}
}
}
quaSpectrum[line] = qua ;
}
}
}
/*****************************************************************************
*
* function name:iquantizeLines
* description: iquantizes spectrum lines without sign
* mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
* input: global gain, number of lines to process,quantized spectrum
* output: spectral data
*
*****************************************************************************/
static void iquantizeLines(const Word16 gain,
const Word16 noOfLines,
const Word16 *quantSpectrum,
Word32 *mdctSpectrum)
{
Word32 iquantizermod;
Word32 iquantizershift;
Word32 line;
iquantizermod = gain & 3;
iquantizershift = gain >> 2;
for (line=0; line<noOfLines; line++) {
if( quantSpectrum[line] != 0 ) {
Word32 accu;
Word32 ex;
Word32 tabIndex;
Word32 specExp;
Word32 s,t;
accu = quantSpectrum[line];
ex = norm_l(accu);
accu = accu << ex;
specExp = INT_BITS-1 - ex;
tabIndex = (accu >> (INT_BITS-2-MANT_DIGITS)) & (~MANT_SIZE);
/* calculate "mantissa" ^4/3 */
s = mTab_4_3[tabIndex];
/* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */
t = specExpMantTableComb_enc[iquantizermod][specExp];
/* multiply "mantissa" ^4/3 with exponent multiplier */
accu = MULHIGH(s, t);
/* get approperiate exponent shifter */
specExp = specExpTableComb_enc[iquantizermod][specExp];
specExp += iquantizershift + 1;
if(specExp >= 0)
mdctSpectrum[line] = accu << specExp;
else
mdctSpectrum[line] = accu >> (-specExp);
}
else {
mdctSpectrum[line] = 0;
}
}
}
/*****************************************************************************
*
* function name: QuantizeSpectrum
* description: quantizes the entire spectrum
* returns:
* input: number of scalefactor bands to be quantized, ...
* output: quantized spectrum
*
*****************************************************************************/
void QuantizeSpectrum(Word16 sfbCnt,
Word16 maxSfbPerGroup,
Word16 sfbPerGroup,
Word16 *sfbOffset,
Word32 *mdctSpectrum,
Word16 globalGain,
Word16 *scalefactors,
Word16 *quantizedSpectrum)
{
Word32 sfbOffs, sfb;
for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {
Word32 sfbNext ;
for (sfb = 0; sfb < maxSfbPerGroup; sfb = sfbNext) {
Word16 scalefactor = scalefactors[sfbOffs+sfb];
/* coalesce sfbs with the same scalefactor */
for (sfbNext = sfb+1;
sfbNext < maxSfbPerGroup && scalefactor == scalefactors[sfbOffs+sfbNext];
sfbNext++) ;
quantizeLines(globalGain - scalefactor,
sfbOffset[sfbOffs+sfbNext] - sfbOffset[sfbOffs+sfb],
mdctSpectrum + sfbOffset[sfbOffs+sfb],
quantizedSpectrum + sfbOffset[sfbOffs+sfb]);
}
}
}
/*****************************************************************************
*
* function name:calcSfbDist
* description: quantizes and requantizes lines to calculate distortion
* input: number of lines to be quantized, ...
* output: distortion
*
*****************************************************************************/
Word32 calcSfbDist(const Word32 *spec,
Word16 sfbWidth,
Word16 gain)
{
Word32 line;
Word32 dist;
Word32 m = gain&3;
Word32 g = (gain >> 2) + 4;
Word32 g2 = (g << 1) + 1;
const Word16 *pquat, *repquat;
/* gain&3 */
pquat = quantBorders[m];
repquat = quantRecon[m];
dist = 0;
g += 16;
if(g2 < 0 && g >= 0)
{
g2 = -g2;
for(line=0; line<sfbWidth; line++) {
if (spec[line]) {
Word32 diff;
Word32 distSingle;
Word32 sa;
Word32 saShft;
sa = L_abs(spec[line]);
//saShft = round16(L_shr(sa, g));
//saShft = L_shr(sa, 16+g);
saShft = sa >> g;
if (saShft < pquat[0]) {
distSingle = (saShft * saShft) >> g2;
}
else {
if (saShft < pquat[1]) {
diff = saShft - repquat[0];
distSingle = (diff * diff) >> g2;
}
else {
if (saShft < pquat[2]) {
diff = saShft - repquat[1];
distSingle = (diff * diff) >> g2;
}
else {
if (saShft < pquat[3]) {
diff = saShft - repquat[2];
distSingle = (diff * diff) >> g2;
}
else {
Word16 qua = quantizeSingleLine(gain, sa);
Word32 iqval, diff32;
/* now that we have quantized x, re-quantize it. */
iquantizeLines(gain, 1, &qua, &iqval);
diff32 = sa - iqval;
distSingle = fixmul(diff32, diff32);
}
}
}
}
dist = L_add(dist, distSingle);
}
}
}
else
{
for(line=0; line<sfbWidth; line++) {
if (spec[line]) {
Word32 diff;
Word32 distSingle;
Word32 sa;
Word32 saShft;
sa = L_abs(spec[line]);
//saShft = round16(L_shr(sa, g));
saShft = L_shr(sa, g);
if (saShft < pquat[0]) {
distSingle = L_shl((saShft * saShft), g2);
}
else {
if (saShft < pquat[1]) {
diff = saShft - repquat[0];
distSingle = L_shl((diff * diff), g2);
}
else {
if (saShft < pquat[2]) {
diff = saShft - repquat[1];
distSingle = L_shl((diff * diff), g2);
}
else {
if (saShft < pquat[3]) {
diff = saShft - repquat[2];
distSingle = L_shl((diff * diff), g2);
}
else {
Word16 qua = quantizeSingleLine(gain, sa);
Word32 iqval, diff32;
/* now that we have quantized x, re-quantize it. */
iquantizeLines(gain, 1, &qua, &iqval);
diff32 = sa - iqval;
distSingle = fixmul(diff32, diff32);
}
}
}
}
dist = L_add(dist, distSingle);
}
}
}
return dist;
}

42
aacenc/external/aacenc/src/quantize.h vendored Normal file
View file

@ -0,0 +1,42 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: quantize.h
Content: Quantization functions
*******************************************************************************/
#ifndef _QUANTIZE_H_
#define _QUANTIZE_H_
#include "typedefs.h"
/* quantizing */
#define MAX_QUANT 8191
void QuantizeSpectrum(Word16 sfbCnt,
Word16 maxSfbPerGroup,
Word16 sfbPerGroup,
Word16 *sfbOffset, Word32 *mdctSpectrum,
Word16 globalGain, Word16 *scalefactors,
Word16 *quantizedSpectrum);
Word32 calcSfbDist(const Word32 *spec,
Word16 sfbWidth,
Word16 gain);
#endif /* _QUANTIZE_H_ */

882
aacenc/external/aacenc/src/sf_estim.c vendored Normal file
View file

@ -0,0 +1,882 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: sf_estim.c
Content: Scale factor estimation functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "sf_estim.h"
#include "quantize.h"
#include "bit_cnt.h"
#include "aac_rom.h"
static const Word16 MAX_SCF_DELTA = 60;
/*!
constants reference in comments
C0 = 6.75f;
C1 = -69.33295f; -16/3*log(MAX_QUANT+0.5-logCon)/log(2)
C2 = 4.0f;
C3 = 2.66666666f;
PE_C1 = 3.0f; log(8.0)/log(2)
PE_C2 = 1.3219281f; log(2.5)/log(2)
PE_C3 = 0.5593573f; 1-C2/C1
*/
#define FF_SQRT_BITS 7
#define FF_SQRT_TABLE_SIZE (1<<FF_SQRT_BITS - 1<<(FF_SQRT_BITS-2))
#define COEF08_31 0x66666666 /* 0.8*(1 << 31) */
#define PE_C1_8 24 /* PE_C1*8 */
#define PE_C2_16 21 /* PE_C2*8/PE_C3 */
#define PE_SCALE 0x059a /* 0.7 * (1 << (15 - 1 - 3))*/
#define SCALE_ESTIMATE_COEF 0x5555 /* (8.8585/(4*log2(10))) * (1 << 15)*/
/*********************************************************************************
*
* function name: formfac_sqrt
* description: calculates sqrt(x)/256
*
**********************************************************************************/
__inline Word32 formfac_sqrt(Word32 x)
{
Word32 y;
Word32 preshift, postshift;
if (x==0) return 0;
preshift = norm_l(x) - (INT_BITS-1-FF_SQRT_BITS);
postshift = preshift >> 1;
preshift = postshift << 1;
postshift = postshift + 8; /* sqrt/256 */
if(preshift >= 0)
y = x << preshift; /* now 1/4 <= y < 1 */
else
y = x >> (-preshift);
y = formfac_sqrttable[y-32];
if(postshift >= 0)
y = y >> postshift;
else
y = y << (-postshift);
return y;
}
/*********************************************************************************
*
* function name: CalcFormFactorChannel
* description: calculate the form factor one channel
* ffac(n) = sqrt(abs(X(k)) + sqrt(abs(X(k+1)) + ....
*
**********************************************************************************/
static void
CalcFormFactorChannel(Word16 *logSfbFormFactor,
Word16 *sfbNRelevantLines,
Word16 *logSfbEnergy,
PSY_OUT_CHANNEL *psyOutChan)
{
Word32 sfbw, sfbw1;
Word32 i, j;
Word32 sfbOffs, sfb;
sfbw = sfbw1 = 0;
for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup){
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
i = sfbOffs+sfb;
if (psyOutChan->sfbEnergy[i] > psyOutChan->sfbThreshold[i]) {
Word32 accu, avgFormFactor,iSfbWidth;
Word32 *mdctSpec;
sfbw = psyOutChan->sfbOffsets[i+1] - psyOutChan->sfbOffsets[i];
iSfbWidth = invSBF[(sfbw >> 2) - 1];
mdctSpec = psyOutChan->mdctSpectrum + psyOutChan->sfbOffsets[i];
accu = 0;
/* calc sum of sqrt(spec) */
for (j=sfbw; j; j--) {
accu += formfac_sqrt(L_abs(*mdctSpec)); mdctSpec++;
}
logSfbFormFactor[i] = iLog4(accu);
logSfbEnergy[i] = iLog4(psyOutChan->sfbEnergy[i]);
avgFormFactor = fixmul(rsqrt(psyOutChan->sfbEnergy[i],INT_BITS), iSfbWidth);
avgFormFactor = rsqrt((Word32)avgFormFactor,INT_BITS) >> 10;
/* result is multiplied by 4 */
if(avgFormFactor)
sfbNRelevantLines[i] = accu / avgFormFactor;
else
sfbNRelevantLines[i] = 0x7fff;
}
else {
/* set number of lines to zero */
sfbNRelevantLines[i] = 0;
}
}
}
}
/*********************************************************************************
*
* function name: improveScf
* description: find better scalefactor with analysis by synthesis
*
**********************************************************************************/
static Word16 improveScf(Word32 *spec,
Word16 sfbWidth,
Word32 thresh,
Word16 scf,
Word16 minScf,
Word32 *dist,
Word16 *minScfCalculated)
{
Word32 cnt;
Word32 sfbDist;
Word32 scfBest;
Word32 thresh125 = L_add(thresh, (thresh >> 2));
scfBest = scf;
/* calc real distortion */
sfbDist = calcSfbDist(spec, sfbWidth, scf);
*minScfCalculated = scf;
if(!sfbDist)
return scfBest;
if (sfbDist > thresh125) {
Word32 scfEstimated;
Word32 sfbDistBest;
scfEstimated = scf;
sfbDistBest = sfbDist;
cnt = 0;
while (sfbDist > thresh125 && (cnt < 3)) {
scf = scf + 1;
sfbDist = calcSfbDist(spec, sfbWidth, scf);
if (sfbDist < sfbDistBest) {
scfBest = scf;
sfbDistBest = sfbDist;
}
cnt = cnt + 1;
}
cnt = 0;
scf = scfEstimated;
sfbDist = sfbDistBest;
while ((sfbDist > thresh125) && (cnt < 1) && (scf > minScf)) {
scf = scf - 1;
sfbDist = calcSfbDist(spec, sfbWidth, scf);
if (sfbDist < sfbDistBest) {
scfBest = scf;
sfbDistBest = sfbDist;
}
*minScfCalculated = scf;
cnt = cnt + 1;
}
*dist = sfbDistBest;
}
else {
Word32 sfbDistBest;
Word32 sfbDistAllowed;
Word32 thresh08 = fixmul(COEF08_31, thresh);
sfbDistBest = sfbDist;
if (sfbDist < thresh08)
sfbDistAllowed = sfbDist;
else
sfbDistAllowed = thresh08;
for (cnt=0; cnt<3; cnt++) {
scf = scf + 1;
sfbDist = calcSfbDist(spec, sfbWidth, scf);
if (fixmul(COEF08_31,sfbDist) < sfbDistAllowed) {
*minScfCalculated = scfBest + 1;
scfBest = scf;
sfbDistBest = sfbDist;
}
}
*dist = sfbDistBest;
}
/* return best scalefactor */
return scfBest;
}
/*********************************************************************************
*
* function name: countSingleScfBits
* description: count single scf bits in huffum
*
**********************************************************************************/
static Word16 countSingleScfBits(Word16 scf, Word16 scfLeft, Word16 scfRight)
{
Word16 scfBits;
scfBits = bitCountScalefactorDelta(scfLeft - scf) +
bitCountScalefactorDelta(scf - scfRight);
return scfBits;
}
/*********************************************************************************
*
* function name: calcSingleSpecPe
* description: ldRatio = log2(en(n)) - 0,375*scfGain(n)
* nbits = 0.7*nLines*ldRation for ldRation >= c1
* nbits = 0.7*nLines*(c2 + c3*ldRatio) for ldRation < c1
*
**********************************************************************************/
static Word16 calcSingleSpecPe(Word16 scf, Word16 sfbConstPePart, Word16 nLines)
{
Word32 specPe;
Word32 ldRatio;
Word32 scf3;
ldRatio = sfbConstPePart << 3; /* (sfbConstPePart -0.375*scf)*8 */
scf3 = scf + scf + scf;
ldRatio = ldRatio - scf3;
if (ldRatio < PE_C1_8) {
/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
ldRatio = (ldRatio + PE_C2_16) >> 1;
}
specPe = nLines * ldRatio;
specPe = (specPe * PE_SCALE) >> 14;
return saturate(specPe);
}
/*********************************************************************************
*
* function name: countScfBitsDiff
* description: count different scf bits used
*
**********************************************************************************/
static Word16 countScfBitsDiff(Word16 *scfOld, Word16 *scfNew,
Word16 sfbCnt, Word16 startSfb, Word16 stopSfb)
{
Word32 scfBitsDiff;
Word32 sfb, sfbLast;
Word32 sfbPrev, sfbNext;
scfBitsDiff = 0;
sfb = 0;
/* search for first relevant sfb */
sfbLast = startSfb;
while (sfbLast < stopSfb && scfOld[sfbLast] == VOAAC_SHRT_MIN) {
sfbLast = sfbLast + 1;
}
/* search for previous relevant sfb and count diff */
sfbPrev = startSfb - 1;
while ((sfbPrev>=0) && scfOld[sfbPrev] == VOAAC_SHRT_MIN) {
sfbPrev = sfbPrev - 1;
}
if (sfbPrev>=0) {
scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
}
/* now loop through all sfbs and count diffs of relevant sfbs */
for (sfb=sfbLast+1; sfb<stopSfb; sfb++) {
if (scfOld[sfb] != VOAAC_SHRT_MIN) {
scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
sfbLast = sfb;
}
}
/* search for next relevant sfb and count diff */
sfbNext = stopSfb;
while (sfbNext < sfbCnt && scfOld[sfbNext] == VOAAC_SHRT_MIN) {
sfbNext = sfbNext + 1;
}
if (sfbNext < sfbCnt)
scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
return saturate(scfBitsDiff);
}
static Word16 calcSpecPeDiff(Word16 *scfOld,
Word16 *scfNew,
Word16 *sfbConstPePart,
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
Word16 *sfbNRelevantLines,
Word16 startSfb,
Word16 stopSfb)
{
Word32 specPeDiff;
Word32 sfb;
specPeDiff = 0;
/* loop through all sfbs and count pe difference */
for (sfb=startSfb; sfb<stopSfb; sfb++) {
if (scfOld[sfb] != VOAAC_SHRT_MIN) {
Word32 ldRatioOld, ldRatioNew;
Word32 scf3;
if (sfbConstPePart[sfb] == MIN_16) {
sfbConstPePart[sfb] = ((logSfbEnergy[sfb] -
logSfbFormFactor[sfb]) + 11-8*4+3) >> 2;
}
ldRatioOld = sfbConstPePart[sfb] << 3;
scf3 = scfOld[sfb] + scfOld[sfb] + scfOld[sfb];
ldRatioOld = ldRatioOld - scf3;
ldRatioNew = sfbConstPePart[sfb] << 3;
scf3 = scfNew[sfb] + scfNew[sfb] + scfNew[sfb];
ldRatioNew = ldRatioNew - scf3;
if (ldRatioOld < PE_C1_8) {
/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
ldRatioOld = (ldRatioOld + PE_C2_16) >> 1;
}
if (ldRatioNew < PE_C1_8) {
/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
ldRatioNew = (ldRatioNew + PE_C2_16) >> 1;
}
specPeDiff += sfbNRelevantLines[sfb] * (ldRatioNew - ldRatioOld);
}
}
specPeDiff = (specPeDiff * PE_SCALE) >> 14;
return saturate(specPeDiff);
}
/*********************************************************************************
*
* function name: assimilateSingleScf
* description: searched for single scalefactor bands, where the number of bits gained
* by using a smaller scfgain(n) is greater than the estimated increased
* bit demand
*
**********************************************************************************/
static void assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
Word16 *scf,
Word16 *minScf,
Word32 *sfbDist,
Word16 *sfbConstPePart,
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
Word16 *sfbNRelevantLines,
Word16 *minScfCalculated,
Flag restartOnSuccess)
{
Word16 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
Word16 *scfLast, *scfNext;
Word32 sfbPeOld, sfbPeNew;
Word32 sfbDistNew;
Word32 j;
Flag success;
Word16 deltaPe, deltaPeNew, deltaPeTmp;
Word16 *prevScfLast = psyOutChan->prevScfLast;
Word16 *prevScfNext = psyOutChan->prevScfNext;
Word16 *deltaPeLast = psyOutChan->deltaPeLast;
Flag updateMinScfCalculated;
success = 0;
deltaPe = 0;
for(j=0;j<psyOutChan->sfbCnt;j++){
prevScfLast[j] = MAX_16;
prevScfNext[j] = MAX_16;
deltaPeLast[j] = MAX_16;
}
sfbLast = -1;
sfbAct = -1;
sfbNext = -1;
scfLast = 0;
scfNext = 0;
scfMin = MAX_16;
do {
/* search for new relevant sfb */
sfbNext = sfbNext + 1;
while (sfbNext < psyOutChan->sfbCnt && scf[sfbNext] == MIN_16) {
sfbNext = sfbNext + 1;
}
if ((sfbLast>=0) && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
/* relevant scfs to the left and to the right */
scfAct = scf[sfbAct];
scfLast = scf + sfbLast;
scfNext = scf + sfbNext;
scfMin = min(*scfLast, *scfNext);
}
else {
if (sfbLast == -1 && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
/* first relevant scf */
scfAct = scf[sfbAct];
scfLast = &scfAct;
scfNext = scf + sfbNext;
scfMin = *scfNext;
}
else {
if ((sfbLast>=0) && (sfbAct>=0) && sfbNext == psyOutChan->sfbCnt) {
/* last relevant scf */
scfAct = scf[sfbAct];
scfLast = scf + sfbLast;
scfNext = &scfAct;
scfMin = *scfLast;
}
}
}
if (sfbAct>=0)
scfMin = max(scfMin, minScf[sfbAct]);
if ((sfbAct >= 0) &&
(sfbLast>=0 || sfbNext < psyOutChan->sfbCnt) &&
scfAct > scfMin &&
(*scfLast != prevScfLast[sfbAct] ||
*scfNext != prevScfNext[sfbAct] ||
deltaPe < deltaPeLast[sfbAct])) {
success = 0;
/* estimate required bits for actual scf */
if (sfbConstPePart[sfbAct] == MIN_16) {
sfbConstPePart[sfbAct] = logSfbEnergy[sfbAct] -
logSfbFormFactor[sfbAct] + 11-8*4; /* 4*log2(6.75) - 32 */
if (sfbConstPePart[sfbAct] < 0)
sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] + 3;
sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] >> 2;
}
sfbPeOld = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
countSingleScfBits(scfAct, *scfLast, *scfNext);
deltaPeNew = deltaPe;
updateMinScfCalculated = 1;
do {
scfAct = scfAct - 1;
/* check only if the same check was not done before */
if (scfAct < minScfCalculated[sfbAct]) {
sfbPeNew = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
countSingleScfBits(scfAct, *scfLast, *scfNext);
/* use new scf if no increase in pe and
quantization error is smaller */
deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
if (deltaPeTmp < 10) {
sfbDistNew = calcSfbDist(psyOutChan->mdctSpectrum+
psyOutChan->sfbOffsets[sfbAct],
(psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct]),
scfAct);
if (sfbDistNew < sfbDist[sfbAct]) {
/* success, replace scf by new one */
scf[sfbAct] = scfAct;
sfbDist[sfbAct] = sfbDistNew;
deltaPeNew = deltaPeTmp;
success = 1;
}
/* mark as already checked */
if (updateMinScfCalculated) {
minScfCalculated[sfbAct] = scfAct;
}
}
else {
updateMinScfCalculated = 0;
}
}
} while (scfAct > scfMin);
deltaPe = deltaPeNew;
/* save parameters to avoid multiple computations of the same sfb */
prevScfLast[sfbAct] = *scfLast;
prevScfNext[sfbAct] = *scfNext;
deltaPeLast[sfbAct] = deltaPe;
}
if (success && restartOnSuccess) {
/* start again at first sfb */
sfbLast = -1;
sfbAct = -1;
sfbNext = -1;
scfLast = 0;
scfNext = 0;
scfMin = MAX_16;
success = 0;
}
else {
/* shift sfbs for next band */
sfbLast = sfbAct;
sfbAct = sfbNext;
}
} while (sfbNext < psyOutChan->sfbCnt);
}
/*********************************************************************************
*
* function name: assimilateMultipleScf
* description: scalefactor difference reduction
*
**********************************************************************************/
static void assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
Word16 *scf,
Word16 *minScf,
Word32 *sfbDist,
Word16 *sfbConstPePart,
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
Word16 *sfbNRelevantLines)
{
Word32 sfb, startSfb, stopSfb, scfMin, scfMax, scfAct;
Flag possibleRegionFound;
Word32 deltaScfBits;
Word32 deltaSpecPe;
Word32 deltaPe, deltaPeNew;
Word32 sfbCnt;
Word32 *sfbDistNew = psyOutChan->sfbDistNew;
Word16 *scfTmp = psyOutChan->prevScfLast;
deltaPe = 0;
sfbCnt = psyOutChan->sfbCnt;
/* calc min and max scalfactors */
scfMin = MAX_16;
scfMax = MIN_16;
for (sfb=0; sfb<sfbCnt; sfb++) {
if (scf[sfb] != MIN_16) {
scfMin = min(scfMin, scf[sfb]);
scfMax = max(scfMax, scf[sfb]);
}
}
if (scfMax != MIN_16) {
scfAct = scfMax;
do {
scfAct = scfAct - 1;
for (sfb=0; sfb<sfbCnt; sfb++) {
scfTmp[sfb] = scf[sfb];
}
stopSfb = 0;
do {
sfb = stopSfb;
while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] <= scfAct)) {
sfb = sfb + 1;
}
startSfb = sfb;
sfb = sfb + 1;
while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] > scfAct)) {
sfb = sfb + 1;
}
stopSfb = sfb;
possibleRegionFound = 0;
if (startSfb < sfbCnt) {
possibleRegionFound = 1;
for (sfb=startSfb; sfb<stopSfb; sfb++) {
if (scf[sfb]!=MIN_16) {
if (scfAct < minScf[sfb]) {
possibleRegionFound = 0;
break;
}
}
}
}
if (possibleRegionFound) { /* region found */
/* replace scfs in region by scfAct */
for (sfb=startSfb; sfb<stopSfb; sfb++) {
if (scfTmp[sfb]!=MIN_16)
scfTmp[sfb] = scfAct;
}
/* estimate change in bit demand for new scfs */
deltaScfBits = countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
deltaSpecPe = calcSpecPeDiff(scf, scfTmp, sfbConstPePart,
logSfbEnergy, logSfbFormFactor, sfbNRelevantLines,
startSfb, stopSfb);
deltaPeNew = deltaPe + deltaScfBits + deltaSpecPe;
if (deltaPeNew < 10) {
Word32 distOldSum, distNewSum;
/* quantize and calc sum of new distortion */
distOldSum = 0;
distNewSum = 0;
for (sfb=startSfb; sfb<stopSfb; sfb++) {
if (scfTmp[sfb] != MIN_16) {
distOldSum = L_add(distOldSum, sfbDist[sfb]);
sfbDistNew[sfb] = calcSfbDist(psyOutChan->mdctSpectrum +
psyOutChan->sfbOffsets[sfb],
(psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]),
scfAct);
if (sfbDistNew[sfb] > psyOutChan->sfbThreshold[sfb]) {
distNewSum = distOldSum << 1;
break;
}
distNewSum = L_add(distNewSum, sfbDistNew[sfb]);
}
}
if (distNewSum < distOldSum) {
deltaPe = deltaPeNew;
for (sfb=startSfb; sfb<stopSfb; sfb++) {
if (scf[sfb]!=MIN_16) {
scf[sfb] = scfAct;
sfbDist[sfb] = sfbDistNew[sfb];
}
}
}
}
}
} while (stopSfb <= sfbCnt);
} while (scfAct > scfMin);
}
}
/*********************************************************************************
*
* function name: EstimateScaleFactorsChannel
* description: estimate scale factors for one channel
*
**********************************************************************************/
static void
EstimateScaleFactorsChannel(PSY_OUT_CHANNEL *psyOutChan,
Word16 *scf,
Word16 *globalGain,
Word16 *logSfbEnergy,
Word16 *logSfbFormFactor,
Word16 *sfbNRelevantLines)
{
Word32 i, j;
Word32 thresh, energy;
Word32 energyPart, thresholdPart;
Word32 scfInt, minScf, maxScf, maxAllowedScf, lastSf;
Word32 maxSpec;
Word32 *sfbDist = psyOutChan->sfbDist;
Word16 *minSfMaxQuant = psyOutChan->minSfMaxQuant;
Word16 *minScfCalculated = psyOutChan->minScfCalculated;
for (i=0; i<psyOutChan->sfbCnt; i++) {
Word32 sbfwith, sbfStart;
Word32 *mdctSpec;
thresh = psyOutChan->sfbThreshold[i];
energy = psyOutChan->sfbEnergy[i];
sbfStart = psyOutChan->sfbOffsets[i];
sbfwith = psyOutChan->sfbOffsets[i+1] - sbfStart;
mdctSpec = psyOutChan->mdctSpectrum+sbfStart;
maxSpec = 0;
/* maximum of spectrum */
for (j=sbfwith; j; j-- ) {
Word32 absSpec = L_abs(*mdctSpec); mdctSpec++;
maxSpec |= absSpec;
}
/* scfs without energy or with thresh>energy are marked with MIN_16 */
scf[i] = MIN_16;
minSfMaxQuant[i] = MIN_16;
if ((maxSpec > 0) && (energy > thresh)) {
energyPart = logSfbFormFactor[i];
thresholdPart = iLog4(thresh);
/* -20 = 4*log2(6.75) - 32 */
scfInt = ((thresholdPart - energyPart - 20) * SCALE_ESTIMATE_COEF) >> 15;
minSfMaxQuant[i] = iLog4(maxSpec) - 68; /* 68 -16/3*log(MAX_QUANT+0.5-logCon)/log(2) + 1 */
if (minSfMaxQuant[i] > scfInt) {
scfInt = minSfMaxQuant[i];
}
/* find better scalefactor with analysis by synthesis */
scfInt = improveScf(psyOutChan->mdctSpectrum+sbfStart,
sbfwith,
thresh, scfInt, minSfMaxQuant[i],
&sfbDist[i], &minScfCalculated[i]);
scf[i] = scfInt;
}
}
/* scalefactor differece reduction */
{
Word16 sfbConstPePart[MAX_GROUPED_SFB];
for(i=0;i<psyOutChan->sfbCnt;i++) {
sfbConstPePart[i] = MIN_16;
}
assimilateSingleScf(psyOutChan, scf,
minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
logSfbFormFactor, sfbNRelevantLines, minScfCalculated, 1);
assimilateMultipleScf(psyOutChan, scf,
minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
logSfbFormFactor, sfbNRelevantLines);
}
/* get max scalefac for global gain */
maxScf = MIN_16;
minScf = MAX_16;
for (i=0; i<psyOutChan->sfbCnt; i++) {
if (maxScf < scf[i]) {
maxScf = scf[i];
}
if ((scf[i] != MIN_16) && (minScf > scf[i])) {
minScf = scf[i];
}
}
/* limit scf delta */
maxAllowedScf = minScf + MAX_SCF_DELTA;
for(i=0; i<psyOutChan->sfbCnt; i++) {
if ((scf[i] != MIN_16) && (maxAllowedScf < scf[i])) {
scf[i] = maxAllowedScf;
}
}
/* new maxScf if any scf has been limited */
if (maxAllowedScf < maxScf) {
maxScf = maxAllowedScf;
}
/* calc loop scalefactors */
if (maxScf > MIN_16) {
*globalGain = maxScf;
lastSf = 0;
for(i=0; i<psyOutChan->sfbCnt; i++) {
if (scf[i] == MIN_16) {
scf[i] = lastSf;
/* set band explicitely to zero */
for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
psyOutChan->mdctSpectrum[j] = 0;
}
}
else {
scf[i] = maxScf - scf[i];
lastSf = scf[i];
}
}
}
else{
*globalGain = 0;
/* set spectrum explicitely to zero */
for(i=0; i<psyOutChan->sfbCnt; i++) {
scf[i] = 0;
for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
psyOutChan->mdctSpectrum[j] = 0;
}
}
}
}
/*********************************************************************************
*
* function name: CalcFormFactor
* description: estimate Form factors for all channel
*
**********************************************************************************/
void
CalcFormFactor(Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
const Word16 nChannels)
{
Word16 j;
for (j=0; j<nChannels; j++) {
CalcFormFactorChannel(logSfbFormFactor[j], sfbNRelevantLines[j], logSfbEnergy[j], &psyOutChannel[j]);
}
}
/*********************************************************************************
*
* function name: EstimateScaleFactors
* description: estimate scale factors for all channel
*
**********************************************************************************/
void
EstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels)
{
Word16 j;
for (j=0; j<nChannels; j++) {
EstimateScaleFactorsChannel(&psyOutChannel[j],
qcOutChannel[j].scf,
&(qcOutChannel[j].globalGain),
logSfbEnergy[j],
logSfbFormFactor[j],
sfbNRelevantLines[j]);
}
}

46
aacenc/external/aacenc/src/sf_estim.h vendored Normal file
View file

@ -0,0 +1,46 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: sf_estim.h
Content: Scale factor estimation functions
*******************************************************************************/
#ifndef __SF_ESTIM_H__
#define __SF_ESTIM_H__
/*
Scale factor estimation
*/
#include "psy_const.h"
#include "interface.h"
#include "qc_data.h"
void
CalcFormFactor(Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
const Word16 nChannels);
void
EstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS],
Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels);
#endif

52
aacenc/external/aacenc/src/spreading.c vendored Normal file
View file

@ -0,0 +1,52 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: spreading.c
Content: Spreading of energy function
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "spreading.h"
/*********************************************************************************
*
* function name: SpreadingMax
* description: spreading the energy
* higher frequencies thr(n) = max(thr(n), sh(n)*thr(n-1))
* lower frequencies thr(n) = max(thr(n), sl(n)*thr(n+1))
*
**********************************************************************************/
void SpreadingMax(const Word16 pbCnt,
const Word16 *maskLowFactor,
const Word16 *maskHighFactor,
Word32 *pbSpreadedEnergy)
{
Word32 i;
/* slope to higher frequencies */
for (i=1; i<pbCnt; i++) {
pbSpreadedEnergy[i] = max(pbSpreadedEnergy[i],
L_mpy_ls(pbSpreadedEnergy[i-1], maskHighFactor[i]));
}
/* slope to lower frequencies */
for (i=pbCnt - 2; i>=0; i--) {
pbSpreadedEnergy[i] = max(pbSpreadedEnergy[i],
L_mpy_ls(pbSpreadedEnergy[i+1], maskLowFactor[i]));
}
}

33
aacenc/external/aacenc/src/spreading.h vendored Normal file
View file

@ -0,0 +1,33 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: spreading.h
Content: Spreading of energy functions
*******************************************************************************/
#ifndef _SPREADING_H
#define _SPREADING_H
#include "typedefs.h"
void SpreadingMax(const Word16 pbCnt,
const Word16 *maskLowFactor,
const Word16 *maskHighFactor,
Word32 *pbSpreadedEnergy);
#endif /* #ifndef _SPREADING_H */

237
aacenc/external/aacenc/src/stat_bits.c vendored Normal file
View file

@ -0,0 +1,237 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: stat_bits.c
Content: Static bit counter functions
*******************************************************************************/
#include "stat_bits.h"
#include "bitenc.h"
#include "tns.h"
typedef enum {
SI_ID_BITS =(3),
SI_FILL_COUNT_BITS =(4),
SI_FILL_ESC_COUNT_BITS =(8),
SI_FILL_EXTENTION_BITS =(4),
SI_FILL_NIBBLE_BITS =(4),
SI_SCE_BITS =(4),
SI_CPE_BITS =(5),
SI_CPE_MS_MASK_BITS =(2) ,
SI_ICS_INFO_BITS_LONG =(1+2+1+6+1),
SI_ICS_INFO_BITS_SHORT =(1+2+1+4+7),
SI_ICS_BITS =(8+1+1+1)
} SI_BITS;
/*********************************************************************************
*
* function name: countMsMaskBits
* description: count ms stereo bits demand
*
**********************************************************************************/
static Word16 countMsMaskBits(Word16 sfbCnt,
Word16 sfbPerGroup,
Word16 maxSfbPerGroup,
struct TOOLSINFO *toolsInfo)
{
Word16 msBits, sfbOff, sfb;
msBits = 0;
switch(toolsInfo->msDigest) {
case MS_NONE:
case MS_ALL:
break;
case MS_SOME:
for(sfbOff=0; sfbOff<sfbCnt; sfbOff+=sfbPerGroup)
for(sfb=0; sfb<maxSfbPerGroup; sfb++)
msBits += 1;
break;
}
return(msBits);
}
/*********************************************************************************
*
* function name: tnsCount
* description: count tns bit demand core function
*
**********************************************************************************/
static Word16 tnsCount(TNS_INFO *tnsInfo, Word16 blockType)
{
Word32 i, k;
Flag tnsPresent;
Word32 numOfWindows;
Word32 count;
Word32 coefBits;
Word16 *ptcoef;
count = 0;
if (blockType == 2)
numOfWindows = 8;
else
numOfWindows = 1;
tnsPresent = 0;
for (i=0; i<numOfWindows; i++) {
if (tnsInfo->tnsActive[i]!=0) {
tnsPresent = 1;
}
}
if (tnsPresent) {
/* there is data to be written*/
/*count += 1; */
for (i=0; i<numOfWindows; i++) {
if (blockType == 2)
count += 1;
else
count += 2;
if (tnsInfo->tnsActive[i]) {
count += 1;
if (blockType == 2) {
count += 4;
count += 3;
}
else {
count += 6;
count += 5;
}
if (tnsInfo->order[i]) {
count += 1; /*direction*/
count += 1; /*coef_compression */
if (tnsInfo->coefRes[i] == 4) {
ptcoef = tnsInfo->coef + i*TNS_MAX_ORDER_SHORT;
coefBits = 3;
for(k=0; k<tnsInfo->order[i]; k++) {
if ((ptcoef[k] > 3) || (ptcoef[k] < -4)) {
coefBits = 4;
break;
}
}
}
else {
coefBits = 2;
ptcoef = tnsInfo->coef + i*TNS_MAX_ORDER_SHORT;
for(k=0; k<tnsInfo->order[i]; k++) {
if ((ptcoef[k] > 1) || (ptcoef[k] < -2)) {
coefBits = 3;
break;
}
}
}
for (k=0; k<tnsInfo->order[i]; k++ ) {
count += coefBits;
}
}
}
}
}
return count;
}
/**********************************************************************************
*
* function name: countTnsBits
* description: count tns bit demand
*
**********************************************************************************/
static Word16 countTnsBits(TNS_INFO *tnsInfo,Word16 blockType)
{
return(tnsCount(tnsInfo, blockType));
}
/*********************************************************************************
*
* function name: countStaticBitdemand
* description: count static bit demand include tns
*
**********************************************************************************/
Word16 countStaticBitdemand(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word16 channels,
Word16 adtsUsed)
{
Word32 statBits;
Word32 ch;
statBits = 0;
/* if adts used, add 56 bits */
if(adtsUsed) statBits += 56;
switch (channels) {
case 1:
statBits += SI_ID_BITS+SI_SCE_BITS+SI_ICS_BITS;
statBits += countTnsBits(&(psyOutChannel[0].tnsInfo),
psyOutChannel[0].windowSequence);
switch(psyOutChannel[0].windowSequence){
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
statBits += SI_ICS_INFO_BITS_LONG;
break;
case SHORT_WINDOW:
statBits += SI_ICS_INFO_BITS_SHORT;
break;
}
break;
case 2:
statBits += SI_ID_BITS+SI_CPE_BITS+2*SI_ICS_BITS;
statBits += SI_CPE_MS_MASK_BITS;
statBits += countMsMaskBits(psyOutChannel[0].sfbCnt,
psyOutChannel[0].sfbPerGroup,
psyOutChannel[0].maxSfbPerGroup,
&psyOutElement->toolsInfo);
switch (psyOutChannel[0].windowSequence) {
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
statBits += SI_ICS_INFO_BITS_LONG;
break;
case SHORT_WINDOW:
statBits += SI_ICS_INFO_BITS_SHORT;
break;
}
for(ch=0; ch<2; ch++)
statBits += countTnsBits(&(psyOutChannel[ch].tnsInfo),
psyOutChannel[ch].windowSequence);
break;
}
return statBits;
}

34
aacenc/external/aacenc/src/stat_bits.h vendored Normal file
View file

@ -0,0 +1,34 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: stat_bits.h
Content: Static bit counter functions
*******************************************************************************/
#ifndef __STAT_BITS_H
#define __STAT_BITS_H
#include "psy_const.h"
#include "interface.h"
Word16 countStaticBitdemand(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
PSY_OUT_ELEMENT *psyOutElement,
Word16 nChannels,
Word16 adtsUsed);
#endif /* __STAT_BITS_H */

908
aacenc/external/aacenc/src/tns.c vendored Normal file
View file

@ -0,0 +1,908 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: tns.c
Content: Definition TNS tools functions
*******************************************************************************/
#include "basic_op.h"
#include "oper_32b.h"
#include "assert.h"
#include "aac_rom.h"
#include "psy_const.h"
#include "tns.h"
#include "tns_param.h"
#include "psy_configuration.h"
#include "tns_func.h"
#define UNUSED(x) (void)(x)
#define TNS_MODIFY_BEGIN 2600 /* Hz */
#define RATIO_PATCH_LOWER_BORDER 380 /* Hz */
#define TNS_GAIN_THRESH 141 /* 1.41*100 */
#define NORM_COEF 0x028f5c28
static const Word32 TNS_PARCOR_THRESH = 0x0ccccccd; /* 0.1*(1 << 31) */
/* Limit bands to > 2.0 kHz */
static unsigned short tnsMinBandNumberLong[12] =
{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 };
static unsigned short tnsMinBandNumberShort[12] =
{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 };
/**************************************/
/* Main/Low Profile TNS Parameters */
/**************************************/
static unsigned short tnsMaxBandsLongMainLow[12] =
{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 };
static unsigned short tnsMaxBandsShortMainLow[12] =
{ 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 };
static void CalcWeightedSpectrum(const Word32 spectrum[],
Word16 weightedSpectrum[],
Word32* sfbEnergy,
const Word16* sfbOffset, Word16 lpcStartLine,
Word16 lpcStopLine, Word16 lpcStartBand,Word16 lpcStopBand,
Word32 *pWork32);
void AutoCorrelation(const Word16 input[], Word32 corr[],
Word16 samples, Word16 corrCoeff);
static Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff);
static Word16 CalcTnsFilter(const Word16* signal, const Word32 window[], Word16 numOfLines,
Word16 tnsOrder, Word32 parcor[]);
static void Parcor2Index(const Word32 parcor[], Word16 index[], Word16 order,
Word16 bitsPerCoeff);
static void Index2Parcor(const Word16 index[], Word32 parcor[], Word16 order,
Word16 bitsPerCoeff);
static void AnalysisFilterLattice(const Word32 signal[], Word16 numOfLines,
const Word32 parCoeff[], Word16 order,
Word32 output[]);
/**
*
* function name: FreqToBandWithRounding
* description: Retrieve index of nearest band border
* returnt: index
*
*/
static Word16 FreqToBandWithRounding(Word32 freq, /*!< frequency in Hertz */
Word32 fs, /*!< Sampling frequency in Hertz */
Word16 numOfBands, /*!< total number of bands */
const Word16 *bandStartOffset) /*!< table of band borders */
{
Word32 lineNumber, band;
Word32 temp, shift;
/* assert(freq >= 0); */
shift = norm_l(fs);
lineNumber = (extract_l(fixmul((bandStartOffset[numOfBands] << 2),Div_32(freq << shift,fs << shift))) + 1) >> 1;
/* freq > fs/2 */
temp = lineNumber - bandStartOffset[numOfBands] ;
if (temp >= 0)
return numOfBands;
/* find band the line number lies in */
for (band=0; band<numOfBands; band++) {
temp = bandStartOffset[band + 1] - lineNumber;
if (temp > 0) break;
}
temp = (lineNumber - bandStartOffset[band]);
temp = (temp - (bandStartOffset[band + 1] - lineNumber));
if ( temp > 0 )
{
band = band + 1;
}
return extract_l(band);
}
/**
*
* function name: InitTnsConfigurationLong
* description: Fill TNS_CONFIG structure with sensible content for long blocks
* returns: 0 if success
*
*/
Word16 InitTnsConfigurationLong(Word32 bitRate, /*!< bitrate */
Word32 sampleRate, /*!< Sampling frequency */
Word16 channels, /*!< number of channels */
TNS_CONFIG *tC, /*!< TNS Config struct (modified) */
PSY_CONFIGURATION_LONG *pC, /*!< psy config struct */
Word16 active) /*!< tns active flag */
{
/*Word32 bitratePerChannel __unused;*/
Word32 bitratePerChannel;
tC->maxOrder = TNS_MAX_ORDER;
tC->tnsStartFreq = 1275;
tC->coefRes = 4;
/* to avoid integer division */
if ( sub(channels,2) == 0 ) {
bitratePerChannel = bitRate >> 1;
}
else {
bitratePerChannel = bitRate;
}
tC->tnsMaxSfb = tnsMaxBandsLongMainLow[pC->sampRateIdx];
tC->tnsActive = active;
/* now calc band and line borders */
tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);
tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];
tC->tnsStartBand = FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,
pC->sfbCnt, (const Word16*)pC->sfbOffset);
tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN,
sampleRate,
pC->sfbCnt,
(const Word16*)pC->sfbOffset);
tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER,
sampleRate,
pC->sfbCnt,
(const Word16*)pC->sfbOffset);
tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];
tC->lpcStopBand = tnsMaxBandsLongMainLow[pC->sampRateIdx];
tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);
tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
tC->lpcStartBand = tnsMinBandNumberLong[pC->sampRateIdx];
tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];
tC->threshold = TNS_GAIN_THRESH;
return(0);
}
/**
*
* function name: InitTnsConfigurationShort
* description: Fill TNS_CONFIG structure with sensible content for short blocks
* returns: 0 if success
*
*/
Word16 InitTnsConfigurationShort(Word32 bitRate, /*!< bitrate */
Word32 sampleRate, /*!< Sampling frequency */
Word16 channels, /*!< number of channels */
TNS_CONFIG *tC, /*!< TNS Config struct (modified) */
PSY_CONFIGURATION_SHORT *pC, /*!< psy config struct */
Word16 active) /*!< tns active flag */
{
/*Word32 bitratePerChannel __unused;*/
Word32 bitratePerChannel;
tC->maxOrder = TNS_MAX_ORDER_SHORT;
tC->tnsStartFreq = 2750;
tC->coefRes = 3;
/* to avoid integer division */
if ( sub(channels,2) == 0 ) {
bitratePerChannel = L_shr(bitRate,1);
}
else {
bitratePerChannel = bitRate;
}
tC->tnsMaxSfb = tnsMaxBandsShortMainLow[pC->sampRateIdx];
tC->tnsActive = active;
/* now calc band and line borders */
tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);
tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];
tC->tnsStartBand=FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,
pC->sfbCnt, (const Word16*)pC->sfbOffset);
tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN,
sampleRate,
pC->sfbCnt,
(const Word16*)pC->sfbOffset);
tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER,
sampleRate,
pC->sfbCnt,
(const Word16*)pC->sfbOffset);
tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];
tC->lpcStopBand = tnsMaxBandsShortMainLow[pC->sampRateIdx];
tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);
tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
tC->lpcStartBand = tnsMinBandNumberShort[pC->sampRateIdx];
tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];
tC->threshold = TNS_GAIN_THRESH;
return(0);
}
/**
*
* function name: TnsDetect
* description: Calculate TNS filter and decide on TNS usage
* returns: 0 if success
*
*/
Word32 TnsDetect(TNS_DATA* tnsData, /*!< tns data structure (modified) */
TNS_CONFIG tC, /*!< tns config structure */
Word32* pScratchTns, /*!< pointer to scratch space */
const Word16 sfbOffset[], /*!< scalefactor size and table */
Word32* spectrum, /*!< spectral data */
Word16 subBlockNumber, /*!< subblock num */
Word16 blockType, /*!< blocktype (long or short) */
Word32 * sfbEnergy) /*!< sfb-wise energy */
{
Word32 predictionGain;
Word32 temp;
Word32* pWork32 = &pScratchTns[subBlockNumber >> 8];
Word16* pWeightedSpectrum = (Word16 *)&pScratchTns[subBlockNumber >> 8];
if (tC.tnsActive) {
CalcWeightedSpectrum(spectrum,
pWeightedSpectrum,
sfbEnergy,
sfbOffset,
tC.lpcStartLine,
tC.lpcStopLine,
tC.lpcStartBand,
tC.lpcStopBand,
pWork32);
temp = blockType - SHORT_WINDOW;
if ( temp != 0 ) {
predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],
tC.acfWindow,
tC.lpcStopLine - tC.lpcStartLine,
tC.maxOrder,
tnsData->dataRaw.tnsLong.subBlockInfo.parcor);
temp = predictionGain - tC.threshold;
if ( temp > 0 ) {
tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1;
}
else {
tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
}
tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain;
}
else{
predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],
tC.acfWindow,
tC.lpcStopLine - tC.lpcStartLine,
tC.maxOrder,
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].parcor);
temp = predictionGain - tC.threshold;
if ( temp > 0 ) {
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1;
}
else {
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
}
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain;
}
}
else{
temp = blockType - SHORT_WINDOW;
if ( temp != 0 ) {
tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0;
}
else {
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0;
}
}
return(0);
}
/*****************************************************************************
*
* function name: TnsSync
* description: update tns parameter
*
*****************************************************************************/
void TnsSync(TNS_DATA *tnsDataDest,
const TNS_DATA *tnsDataSrc,
const TNS_CONFIG tC,
const Word16 subBlockNumber,
const Word16 blockType)
{
TNS_SUBBLOCK_INFO *sbInfoDest;
const TNS_SUBBLOCK_INFO *sbInfoSrc;
Word32 i, temp;
temp = blockType - SHORT_WINDOW;
if ( temp != 0 ) {
sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo;
sbInfoSrc = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo;
}
else {
sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
sbInfoSrc = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
}
if (100*abs_s(sbInfoDest->predictionGain - sbInfoSrc->predictionGain) <
(3 * sbInfoDest->predictionGain)) {
sbInfoDest->tnsActive = sbInfoSrc->tnsActive;
for ( i=0; i< tC.maxOrder; i++) {
sbInfoDest->parcor[i] = sbInfoSrc->parcor[i];
}
}
}
/*****************************************************************************
*
* function name: TnsEncode
* description: do TNS filtering
* returns: 0 if success
*
*****************************************************************************/
Word16 TnsEncode(TNS_INFO* tnsInfo, /*!< tns info structure (modified) */
TNS_DATA* tnsData, /*!< tns data structure (modified) */
Word16 numOfSfb, /*!< number of scale factor bands */
TNS_CONFIG tC, /*!< tns config structure */
Word16 lowPassLine, /*!< lowpass line */
Word32* spectrum, /*!< spectral data (modified) */
Word16 subBlockNumber, /*!< subblock num */
Word16 blockType) /*!< blocktype (long or short) */
{
Word32 i;
Word32 temp_s;
Word32 temp;
TNS_SUBBLOCK_INFO *psubBlockInfo;
temp_s = blockType - SHORT_WINDOW;
if ( temp_s != 0) {
psubBlockInfo = &tnsData->dataRaw.tnsLong.subBlockInfo;
if (psubBlockInfo->tnsActive == 0) {
tnsInfo->tnsActive[subBlockNumber] = 0;
return(0);
}
else {
Parcor2Index(psubBlockInfo->parcor,
tnsInfo->coef,
tC.maxOrder,
tC.coefRes);
Index2Parcor(tnsInfo->coef,
psubBlockInfo->parcor,
tC.maxOrder,
tC.coefRes);
for (i=tC.maxOrder - 1; i>=0; i--) {
temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
if ( temp > 0 )
break;
temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
if ( temp < 0 )
break;
}
tnsInfo->order[subBlockNumber] = i + 1;
tnsInfo->tnsActive[subBlockNumber] = 1;
for (i=subBlockNumber+1; i<TRANS_FAC; i++) {
tnsInfo->tnsActive[i] = 0;
}
tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;
AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]),
(min(tC.tnsStopLine,lowPassLine) - tC.tnsStartLine),
psubBlockInfo->parcor,
tnsInfo->order[subBlockNumber],
&(spectrum[tC.tnsStartLine]));
}
} /* if (blockType!=SHORT_WINDOW) */
else /*short block*/ {
psubBlockInfo = &tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
if (psubBlockInfo->tnsActive == 0) {
tnsInfo->tnsActive[subBlockNumber] = 0;
return(0);
}
else {
Parcor2Index(psubBlockInfo->parcor,
&tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT],
tC.maxOrder,
tC.coefRes);
Index2Parcor(&tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT],
psubBlockInfo->parcor,
tC.maxOrder,
tC.coefRes);
for (i=(tC.maxOrder - 1); i>=0; i--) {
temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
if ( temp > 0 )
break;
temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
if ( temp < 0 )
break;
}
tnsInfo->order[subBlockNumber] = i + 1;
tnsInfo->tnsActive[subBlockNumber] = 1;
tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;
AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), (tC.tnsStopLine - tC.tnsStartLine),
psubBlockInfo->parcor,
tnsInfo->order[subBlockNumber],
&(spectrum[tC.tnsStartLine]));
}
}
return(0);
}
/*****************************************************************************
*
* function name: CalcWeightedSpectrum
* description: Calculate weighted spectrum for LPC calculation
*
*****************************************************************************/
static void CalcWeightedSpectrum(const Word32 spectrum[], /*!< input spectrum */
Word16 weightedSpectrum[],
Word32 *sfbEnergy, /*!< sfb energies */
const Word16 *sfbOffset,
Word16 lpcStartLine,
Word16 lpcStopLine,
Word16 lpcStartBand,
Word16 lpcStopBand,
Word32 *pWork32)
{
#define INT_BITS_SCAL 1<<(INT_BITS/2)
Word32 i, sfb, shift;
Word32 maxShift;
Word32 tmp_s, tmp2_s;
Word32 tmp, tmp2;
Word32 maxWS;
Word32 tnsSfbMean[MAX_SFB]; /* length [lpcStopBand-lpcStartBand] should be sufficient here */
maxWS = 0;
/* calc 1.0*2^-INT_BITS/2/sqrt(en) */
for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) {
tmp2 = sfbEnergy[sfb] - 2;
if( tmp2 > 0) {
tmp = rsqrt(sfbEnergy[sfb], INT_BITS);
if(tmp > INT_BITS_SCAL)
{
shift = norm_l(tmp);
tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift );
}
else
{
tmp = 0x7fffffff;
}
}
else {
tmp = 0x7fffffff;
}
tnsSfbMean[sfb] = tmp;
}
/* spread normalized values from sfbs to lines */
sfb = lpcStartBand;
tmp = tnsSfbMean[sfb];
for ( i=lpcStartLine; i<lpcStopLine; i++){
tmp_s = sfbOffset[sfb + 1] - i;
if ( tmp_s == 0 ) {
sfb = sfb + 1;
tmp2_s = sfb + 1 - lpcStopBand;
if (tmp2_s <= 0) {
tmp = tnsSfbMean[sfb];
}
}
pWork32[i] = tmp;
}
/*filter down*/
for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){
pWork32[i] = (pWork32[i] + pWork32[i + 1]) >> 1;
}
/* filter up */
for (i=(lpcStartLine + 1); i<lpcStopLine; i++){
pWork32[i] = (pWork32[i] + pWork32[i - 1]) >> 1;
}
/* weight and normalize */
for (i=lpcStartLine; i<lpcStopLine; i++){
pWork32[i] = MULHIGH(pWork32[i], spectrum[i]);
maxWS |= L_abs(pWork32[i]);
}
maxShift = norm_l(maxWS);
maxShift = 16 - maxShift;
if(maxShift >= 0)
{
for (i=lpcStartLine; i<lpcStopLine; i++){
weightedSpectrum[i] = pWork32[i] >> maxShift;
}
}
else
{
maxShift = -maxShift;
for (i=lpcStartLine; i<lpcStopLine; i++){
weightedSpectrum[i] = saturate(pWork32[i] << maxShift);
}
}
}
/*****************************************************************************
*
* function name: CalcTnsFilter
* description: LPC calculation for one TNS filter
* returns: prediction gain
* input: signal spectrum, acf window, no. of spectral lines,
* max. TNS order, ptr. to reflection ocefficients
* output: reflection coefficients
*(half) window size must be larger than tnsOrder !!*
******************************************************************************/
static Word16 CalcTnsFilter(const Word16 *signal,
const Word32 window[],
Word16 numOfLines,
Word16 tnsOrder,
Word32 parcor[])
{
Word32 parcorWorkBuffer[2*TNS_MAX_ORDER+1];
Word32 predictionGain;
Word32 i;
Word32 tnsOrderPlus1 = tnsOrder + 1;
UNUSED(window);
assert(tnsOrder <= TNS_MAX_ORDER); /* remove asserts later? (btg) */
for(i=0;i<tnsOrder;i++) {
parcor[i] = 0;
}
AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1);
/* early return if signal is very low: signal prediction off, with zero parcor coeffs */
if (parcorWorkBuffer[0] == 0)
return 0;
predictionGain = AutoToParcor(parcorWorkBuffer, parcor, tnsOrder);
return(predictionGain);
}
/*****************************************************************************
*
* function name: AutoCorrelation
* description: calc. autocorrelation (acf)
* returns: -
* input: input values, no. of input values, no. of acf values
* output: acf values
*
*****************************************************************************/
#ifndef ARMV5E
void AutoCorrelation(const Word16 input[],
Word32 corr[],
Word16 samples,
Word16 corrCoeff) {
Word32 i, j, isamples;
Word32 accu;
Word32 scf;
scf = 10 - 1;
isamples = samples;
/* calc first corrCoef: R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */
accu = 0;
for(j=0; j<isamples; j++) {
accu = L_add(accu, ((input[j] * input[j]) >> scf));
}
corr[0] = accu;
/* early termination if all corr coeffs are likely going to be zero */
if(corr[0] == 0) return ;
/* calc all other corrCoef: R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */
for(i=1; i<corrCoeff; i++) {
isamples = isamples - 1;
accu = 0;
for(j=0; j<isamples; j++) {
accu = L_add(accu, ((input[j] * input[j+i]) >> scf));
}
corr[i] = accu;
}
}
#endif
/*****************************************************************************
*
* function name: AutoToParcor
* description: conversion autocorrelation to reflection coefficients
* returns: prediction gain
* input: <order+1> input values, no. of output values (=order),
* ptr. to workbuffer (required size: 2*order)
* output: <order> reflection coefficients
*
*****************************************************************************/
static Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff) {
Word32 i, j, shift;
Word32 *pWorkBuffer; /* temp pointer */
Word32 predictionGain = 0;
Word32 num, denom;
Word32 temp, workBuffer0;
num = workBuffer[0];
temp = workBuffer[numOfCoeff];
for(i=0; i<numOfCoeff-1; i++) {
workBuffer[i + numOfCoeff] = workBuffer[i + 1];
}
workBuffer[i + numOfCoeff] = temp;
for(i=0; i<numOfCoeff; i++) {
Word32 refc;
if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) {
return 0 ;
}
shift = norm_l(workBuffer[0]);
workBuffer0 = Div_32(1 << shift, workBuffer[0] << shift);
/* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */
refc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0));
reflCoeff[i] = refc;
pWorkBuffer = &(workBuffer[numOfCoeff]);
for(j=i; j<numOfCoeff; j++) {
Word32 accu1, accu2;
accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i]));
accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j]));
pWorkBuffer[j] = accu1;
workBuffer[j - i] = accu2;
}
}
denom = MULHIGH(workBuffer[0], NORM_COEF);
if (denom != 0) {
Word32 temp;
shift = norm_l(denom);
temp = Div_32(1 << shift, denom << shift);
predictionGain = fixmul(num, temp);
}
return extract_l(predictionGain);
}
static Word16 Search3(Word32 parcor)
{
Word32 index = 0;
Word32 i;
Word32 temp;
for (i=0;i<8;i++) {
temp = L_sub( parcor, tnsCoeff3Borders[i]);
if (temp > 0)
index=i;
}
return extract_l(index - 4);
}
static Word16 Search4(Word32 parcor)
{
Word32 index = 0;
Word32 i;
Word32 temp;
for (i=0;i<16;i++) {
temp = L_sub(parcor, tnsCoeff4Borders[i]);
if (temp > 0)
index=i;
}
return extract_l(index - 8);
}
/*****************************************************************************
*
* functionname: Parcor2Index
* description: quantization index for reflection coefficients
*
*****************************************************************************/
static void Parcor2Index(const Word32 parcor[], /*!< parcor coefficients */
Word16 index[], /*!< quantized coeff indices */
Word16 order, /*!< filter order */
Word16 bitsPerCoeff) { /*!< quantizer resolution */
Word32 i;
Word32 temp;
for(i=0; i<order; i++) {
temp = bitsPerCoeff - 3;
if (temp == 0) {
index[i] = Search3(parcor[i]);
}
else {
index[i] = Search4(parcor[i]);
}
}
}
/*****************************************************************************
*
* functionname: Index2Parcor
* description: Inverse quantization for reflection coefficients
*
*****************************************************************************/
static void Index2Parcor(const Word16 index[], /*!< quantized values */
Word32 parcor[], /*!< ptr. to reflection coefficients (output) */
Word16 order, /*!< no. of coefficients */
Word16 bitsPerCoeff) /*!< quantizer resolution */
{
Word32 i;
Word32 temp;
for (i=0; i<order; i++) {
temp = bitsPerCoeff - 4;
if ( temp == 0 ) {
parcor[i] = tnsCoeff4[index[i] + 8];
}
else {
parcor[i] = tnsCoeff3[index[i] + 4];
}
}
}
/*****************************************************************************
*
* functionname: FIRLattice
* description: in place lattice filtering of spectral data
* returns: pointer to modified data
*
*****************************************************************************/
static Word32 FIRLattice(Word16 order, /*!< filter order */
Word32 x, /*!< spectral data */
Word32 *state_par, /*!< filter states */
const Word32 *coef_par) /*!< filter coefficients */
{
Word32 i;
Word32 accu,tmp,tmpSave;
x = x >> 1;
tmpSave = x;
for (i=0; i<(order - 1); i++) {
tmp = L_add(fixmul(coef_par[i], x), state_par[i]);
x = L_add(fixmul(coef_par[i], state_par[i]), x);
state_par[i] = tmpSave;
tmpSave = tmp;
}
/* last stage: only need half operations */
accu = fixmul(state_par[order - 1], coef_par[(order - 1)]);
state_par[(order - 1)] = tmpSave;
x = L_add(accu, x);
x = L_add(x, x);
return x;
}
/*****************************************************************************
*
* functionname: AnalysisFilterLattice
* description: filters spectral lines with TNS filter
*
*****************************************************************************/
static void AnalysisFilterLattice(const Word32 signal[], /*!< input spectrum */
Word16 numOfLines, /*!< no. of lines */
const Word32 parCoeff[],/*!< PARC coefficients */
Word16 order, /*!< filter order */
Word32 output[]) /*!< filtered signal values */
{
Word32 state_par[TNS_MAX_ORDER];
Word32 j;
for ( j=0; j<TNS_MAX_ORDER; j++ ) {
state_par[j] = 0;
}
for(j=0; j<numOfLines; j++) {
output[j] = FIRLattice(order,signal[j],state_par,parCoeff);
}
}
/*****************************************************************************
*
* functionname: ApplyTnsMultTableToRatios
* description: Change thresholds according to tns
*
*****************************************************************************/
void ApplyTnsMultTableToRatios(Word16 startCb,
Word16 stopCb,
TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */
Word32 *thresholds) /*!< thresholds (modified) */
{
Word32 i;
if (subInfo.tnsActive) {
for(i=startCb; i<stopCb; i++) {
/* thresholds[i] * 0.25 */
thresholds[i] = (thresholds[i] >> 2);
}
}
}

108
aacenc/external/aacenc/src/tns.h vendored Normal file
View file

@ -0,0 +1,108 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: tns.h
Content: TNS structures
*******************************************************************************/
#ifndef _TNS_H
#define _TNS_H
#include "typedef.h"
#include "psy_const.h"
#define TNS_MAX_ORDER 12
#define TNS_MAX_ORDER_SHORT 5
#define FILTER_DIRECTION 0
typedef struct{ /*stuff that is tabulated dependent on bitrate etc. */
Word16 threshOn; /* min. prediction gain for using tns TABUL * 100*/
Word32 lpcStartFreq; /* lowest freq for lpc TABUL*/
Word32 lpcStopFreq; /* TABUL */
Word32 tnsTimeResolution;
}TNS_CONFIG_TABULATED;
typedef struct { /*assigned at InitTime*/
Word16 tnsActive;
Word16 tnsMaxSfb;
Word16 maxOrder; /* max. order of tns filter */
Word16 tnsStartFreq; /* lowest freq. for tns filtering */
Word16 coefRes;
TNS_CONFIG_TABULATED confTab;
Word32 acfWindow[TNS_MAX_ORDER+1];
Word16 tnsStartBand;
Word16 tnsStartLine;
Word16 tnsStopBand;
Word16 tnsStopLine;
Word16 lpcStartBand;
Word16 lpcStartLine;
Word16 lpcStopBand;
Word16 lpcStopLine;
Word16 tnsRatioPatchLowestCb;
Word16 tnsModifyBeginCb;
Word16 threshold; /* min. prediction gain for using tns TABUL * 100 */
}TNS_CONFIG;
typedef struct {
Word16 tnsActive;
Word32 parcor[TNS_MAX_ORDER];
Word16 predictionGain;
} TNS_SUBBLOCK_INFO; /* Word16 size: 26 */
typedef struct{
TNS_SUBBLOCK_INFO subBlockInfo[TRANS_FAC];
} TNS_DATA_SHORT;
typedef struct{
TNS_SUBBLOCK_INFO subBlockInfo;
} TNS_DATA_LONG;
typedef struct{
TNS_DATA_LONG tnsLong;
TNS_DATA_SHORT tnsShort;
}TNS_DATA_RAW;
typedef struct{
Word16 numOfSubblocks;
TNS_DATA_RAW dataRaw;
}TNS_DATA; /* Word16 size: 1 + 8*26 + 26 = 235 */
typedef struct{
Word16 tnsActive[TRANS_FAC];
Word16 coefRes[TRANS_FAC];
Word16 length[TRANS_FAC];
Word16 order[TRANS_FAC];
Word16 coef[TRANS_FAC*TNS_MAX_ORDER_SHORT];
}TNS_INFO; /* Word16 size: 72 */
#endif /* _TNS_H */

75
aacenc/external/aacenc/src/tns_func.h vendored Normal file
View file

@ -0,0 +1,75 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: tns_func.h
Content: TNS functions
*******************************************************************************/
/*
Temporal noise shaping
*/
#ifndef _TNS_FUNC_H
#define _TNS_FUNC_H
#include "typedef.h"
#include "psy_configuration.h"
Word16 InitTnsConfigurationLong(Word32 bitrate,
Word32 samplerate,
Word16 channels,
TNS_CONFIG *tnsConfig,
PSY_CONFIGURATION_LONG *psyConfig,
Word16 active);
Word16 InitTnsConfigurationShort(Word32 bitrate,
Word32 samplerate,
Word16 channels,
TNS_CONFIG *tnsConfig,
PSY_CONFIGURATION_SHORT *psyConfig,
Word16 active);
Word32 TnsDetect(TNS_DATA* tnsData,
TNS_CONFIG tC,
Word32* pScratchTns,
const Word16 sfbOffset[],
Word32* spectrum,
Word16 subBlockNumber,
Word16 blockType,
Word32 * sfbEnergy);
void TnsSync(TNS_DATA *tnsDataDest,
const TNS_DATA *tnsDataSrc,
const TNS_CONFIG tC,
const Word16 subBlockNumber,
const Word16 blockType);
Word16 TnsEncode(TNS_INFO* tnsInfo,
TNS_DATA* tnsData,
Word16 numOfSfb,
TNS_CONFIG tC,
Word16 lowPassLine,
Word32* spectrum,
Word16 subBlockNumber,
Word16 blockType);
void ApplyTnsMultTableToRatios(Word16 startCb,
Word16 stopCb,
TNS_SUBBLOCK_INFO subInfo,
Word32 *thresholds);
#endif /* _TNS_FUNC_H */

52
aacenc/external/aacenc/src/tns_param.h vendored Normal file
View file

@ -0,0 +1,52 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: tns_param.h
Content: TNS parameters
*******************************************************************************/
/*
TNS parameters
*/
#ifndef _TNS_PARAM_H
#define _TNS_PARAM_H
#include "tns.h"
typedef struct{
Word32 samplingRate;
Word16 maxBandLong;
Word16 maxBandShort;
}TNS_MAX_TAB_ENTRY;
typedef struct{
Word32 bitRateFrom;
Word32 bitRateTo;
const TNS_CONFIG_TABULATED *paramMono_Long; /* contains TNS parameters */
const TNS_CONFIG_TABULATED *paramMono_Short;
const TNS_CONFIG_TABULATED *paramStereo_Long;
const TNS_CONFIG_TABULATED *paramStereo_Short;
}TNS_INFO_TAB;
void GetTnsParam(TNS_CONFIG_TABULATED *tnsConfigTab,
Word32 bitRate, Word16 channels, Word16 blockType);
void GetTnsMaxBands(Word32 samplingRate, Word16 blockType, Word16* tnsMaxSfb);
#endif /* _TNS_PARAM_H */

677
aacenc/external/aacenc/src/transform.c vendored Normal file
View file

@ -0,0 +1,677 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: transform.c
Content: MDCT Transform functionss
*******************************************************************************/
#include "basic_op.h"
#include "psy_const.h"
#include "transform.h"
#include "aac_rom.h"
#define LS_TRANS ((FRAME_LEN_LONG-FRAME_LEN_SHORT)/2) /* 448 */
#define SQRT1_2 0x5a82799a /* sqrt(1/2) in Q31 */
#define swap2(p0,p1) \
t = p0; t1 = *(&(p0)+1); \
p0 = p1; *(&(p0)+1) = *(&(p1)+1); \
p1 = t; *(&(p1)+1) = t1
/*********************************************************************************
*
* function name: Shuffle
* description: Shuffle points prepared function for fft
*
**********************************************************************************/
static void Shuffle(int *buf, int num, const unsigned char* bitTab)
{
int *part0, *part1;
int i, j;
int t, t1;
part0 = buf;
part1 = buf + num;
while ((i = *bitTab++) != 0) {
j = *bitTab++;
swap2(part0[4*i+0], part0[4*j+0]);
swap2(part0[4*i+2], part1[4*j+0]);
swap2(part1[4*i+0], part0[4*j+2]);
swap2(part1[4*i+2], part1[4*j+2]);
}
do {
swap2(part0[4*i+2], part1[4*i+0]);
} while ((i = *bitTab++) != 0);
}
#if !defined(ARMV5E) && !defined(ARMV7Neon)
/*****************************************************************************
*
* function name: Radix4First
* description: Radix 4 point prepared function for fft
*
**********************************************************************************/
static void Radix4First(int *buf, int num)
{
int r0, r1, r2, r3;
int r4, r5, r6, r7;
for (; num != 0; num--)
{
r0 = buf[0] + buf[2];
r1 = buf[1] + buf[3];
r2 = buf[0] - buf[2];
r3 = buf[1] - buf[3];
r4 = buf[4] + buf[6];
r5 = buf[5] + buf[7];
r6 = buf[4] - buf[6];
r7 = buf[5] - buf[7];
buf[0] = r0 + r4;
buf[1] = r1 + r5;
buf[4] = r0 - r4;
buf[5] = r1 - r5;
buf[2] = r2 + r7;
buf[3] = r3 - r6;
buf[6] = r2 - r7;
buf[7] = r3 + r6;
buf += 8;
}
}
/*****************************************************************************
*
* function name: Radix8First
* description: Radix 8 point prepared function for fft
*
**********************************************************************************/
static void Radix8First(int *buf, int num)
{
int r0, r1, r2, r3;
int i0, i1, i2, i3;
int r4, r5, r6, r7;
int i4, i5, i6, i7;
int t0, t1, t2, t3;
for ( ; num != 0; num--)
{
r0 = buf[0] + buf[2];
i0 = buf[1] + buf[3];
r1 = buf[0] - buf[2];
i1 = buf[1] - buf[3];
r2 = buf[4] + buf[6];
i2 = buf[5] + buf[7];
r3 = buf[4] - buf[6];
i3 = buf[5] - buf[7];
r4 = (r0 + r2) >> 1;
i4 = (i0 + i2) >> 1;
r5 = (r0 - r2) >> 1;
i5 = (i0 - i2) >> 1;
r6 = (r1 - i3) >> 1;
i6 = (i1 + r3) >> 1;
r7 = (r1 + i3) >> 1;
i7 = (i1 - r3) >> 1;
r0 = buf[ 8] + buf[10];
i0 = buf[ 9] + buf[11];
r1 = buf[ 8] - buf[10];
i1 = buf[ 9] - buf[11];
r2 = buf[12] + buf[14];
i2 = buf[13] + buf[15];
r3 = buf[12] - buf[14];
i3 = buf[13] - buf[15];
t0 = (r0 + r2) >> 1;
t1 = (i0 + i2) >> 1;
t2 = (r0 - r2) >> 1;
t3 = (i0 - i2) >> 1;
buf[ 0] = r4 + t0;
buf[ 1] = i4 + t1;
buf[ 8] = r4 - t0;
buf[ 9] = i4 - t1;
buf[ 4] = r5 + t3;
buf[ 5] = i5 - t2;
buf[12] = r5 - t3;
buf[13] = i5 + t2;
r0 = r1 - i3;
i0 = i1 + r3;
r2 = r1 + i3;
i2 = i1 - r3;
t0 = MULHIGH(SQRT1_2, r0 - i0);
t1 = MULHIGH(SQRT1_2, r0 + i0);
t2 = MULHIGH(SQRT1_2, r2 - i2);
t3 = MULHIGH(SQRT1_2, r2 + i2);
buf[ 6] = r6 - t0;
buf[ 7] = i6 - t1;
buf[14] = r6 + t0;
buf[15] = i6 + t1;
buf[ 2] = r7 + t3;
buf[ 3] = i7 - t2;
buf[10] = r7 - t3;
buf[11] = i7 + t2;
buf += 16;
}
}
/*****************************************************************************
*
* function name: Radix4FFT
* description: Radix 4 point fft core function
*
**********************************************************************************/
static void Radix4FFT(int *buf, int num, int bgn, int *twidTab)
{
int r0, r1, r2, r3;
int r4, r5, r6, r7;
int t0, t1;
int sinx, cosx;
int i, j, step;
int *xptr, *csptr;
for (num >>= 2; num != 0; num >>= 2)
{
step = 2*bgn;
xptr = buf;
for (i = num; i != 0; i--)
{
csptr = twidTab;
for (j = bgn; j != 0; j--)
{
r0 = xptr[0];
r1 = xptr[1];
xptr += step;
t0 = xptr[0];
t1 = xptr[1];
cosx = csptr[0];
sinx = csptr[1];
r2 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*br + sin*bi */
r3 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*bi - sin*br */
xptr += step;
t0 = r0 >> 2;
t1 = r1 >> 2;
r0 = t0 - r2;
r1 = t1 - r3;
r2 = t0 + r2;
r3 = t1 + r3;
t0 = xptr[0];
t1 = xptr[1];
cosx = csptr[2];
sinx = csptr[3];
r4 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*cr + sin*ci */
r5 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*ci - sin*cr */
xptr += step;
t0 = xptr[0];
t1 = xptr[1];
cosx = csptr[4];
sinx = csptr[5];
r6 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*cr + sin*ci */
r7 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*ci - sin*cr */
csptr += 6;
t0 = r4;
t1 = r5;
r4 = t0 + r6;
r5 = r7 - t1;
r6 = t0 - r6;
r7 = r7 + t1;
xptr[0] = r0 + r5;
xptr[1] = r1 + r6;
xptr -= step;
xptr[0] = r2 - r4;
xptr[1] = r3 - r7;
xptr -= step;
xptr[0] = r0 - r5;
xptr[1] = r1 - r6;
xptr -= step;
xptr[0] = r2 + r4;
xptr[1] = r3 + r7;
xptr += 2;
}
xptr += 3*step;
}
twidTab += 3*step;
bgn <<= 2;
}
}
/*********************************************************************************
*
* function name: PreMDCT
* description: prepare MDCT process for next FFT compute
*
**********************************************************************************/
static void PreMDCT(int *buf0, int num, const int *csptr)
{
int i;
int tr1, ti1, tr2, ti2;
int cosa, sina, cosb, sinb;
int *buf1;
buf1 = buf0 + num - 1;
for(i = num >> 2; i != 0; i--)
{
cosa = *csptr++;
sina = *csptr++;
cosb = *csptr++;
sinb = *csptr++;
tr1 = *(buf0 + 0);
ti2 = *(buf0 + 1);
tr2 = *(buf1 - 1);
ti1 = *(buf1 + 0);
*buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);
*buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1);
*buf1-- = MULHIGH(cosb, ti2) - MULHIGH(sinb, tr2);
*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
}
}
/*********************************************************************************
*
* function name: PostMDCT
* description: post MDCT process after next FFT for MDCT
*
**********************************************************************************/
static void PostMDCT(int *buf0, int num, const int *csptr)
{
int i;
int tr1, ti1, tr2, ti2;
int cosa, sina, cosb, sinb;
int *buf1;
buf1 = buf0 + num - 1;
for(i = num >> 2; i != 0; i--)
{
cosa = *csptr++;
sina = *csptr++;
cosb = *csptr++;
sinb = *csptr++;
tr1 = *(buf0 + 0);
ti1 = *(buf0 + 1);
ti2 = *(buf1 + 0);
tr2 = *(buf1 - 1);
*buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);
*buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1);
*buf0++ = MULHIGH(sinb, tr2) - MULHIGH(cosb, ti2);
*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
}
}
#else
void Radix4First(int *buf, int num);
void Radix8First(int *buf, int num);
void Radix4FFT(int *buf, int num, int bgn, int *twidTab);
void PreMDCT(int *buf0, int num, const int *csptr);
void PostMDCT(int *buf0, int num, const int *csptr);
#endif
/**********************************************************************************
*
* function name: Mdct_Long
* description: the long block mdct, include long_start block, end_long block
*
**********************************************************************************/
void Mdct_Long(int *buf)
{
PreMDCT(buf, 1024, cossintab + 128);
Shuffle(buf, 512, bitrevTab + 17);
Radix8First(buf, 512 >> 3);
Radix4FFT(buf, 512 >> 3, 8, (int *)twidTab512);
PostMDCT(buf, 1024, cossintab + 128);
}
/**********************************************************************************
*
* function name: Mdct_Short
* description: the short block mdct
*
**********************************************************************************/
void Mdct_Short(int *buf)
{
PreMDCT(buf, 128, cossintab);
Shuffle(buf, 64, bitrevTab);
Radix4First(buf, 64 >> 2);
Radix4FFT(buf, 64 >> 2, 4, (int *)twidTab64);
PostMDCT(buf, 128, cossintab);
}
/*****************************************************************************
*
* function name: shiftMdctDelayBuffer
* description: the mdct delay buffer has a size of 1600,
* so the calculation of LONG,STOP must be spilt in two
* passes with 1024 samples and a mid shift,
* the SHORT transforms can be completed in the delay buffer,
* and afterwards a shift
*
**********************************************************************************/
static void shiftMdctDelayBuffer(Word16 *mdctDelayBuffer, /*! start of mdct delay buffer */
Word16 *timeSignal, /*! pointer to new time signal samples, interleaved */
Word16 chIncrement /*! number of channels */
)
{
Word32 i;
Word16 *srBuf = mdctDelayBuffer;
Word16 *dsBuf = mdctDelayBuffer+FRAME_LEN_LONG;
for(i = 0; i < BLOCK_SWITCHING_OFFSET-FRAME_LEN_LONG; i+= 8)
{
*srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
*srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
*srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
*srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
}
srBuf = mdctDelayBuffer + BLOCK_SWITCHING_OFFSET-FRAME_LEN_LONG;
dsBuf = timeSignal;
for(i=0; i<FRAME_LEN_LONG; i+=8)
{
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
*srBuf++ = *dsBuf; dsBuf += chIncrement;
}
}
/*****************************************************************************
*
* function name: getScalefactorOfShortVectorStride
* description: Calculate max possible scale factor for input vector of shorts
* returns: Maximum scale factor
*
**********************************************************************************/
static Word16 getScalefactorOfShortVectorStride(const Word16 *vector, /*!< Pointer to input vector */
Word16 len, /*!< Length of input vector */
Word16 stride) /*!< Stride of input vector */
{
Word16 maxVal = 0;
Word16 absVal;
Word16 i;
for(i=0; i<len; i++){
absVal = abs_s(vector[i*stride]);
maxVal |= absVal;
}
return( maxVal ? norm_s(maxVal) : 15);
}
/*****************************************************************************
*
* function name: Transform_Real
* description: Calculate transform filter for input vector of shorts
* returns: TRUE if success
*
**********************************************************************************/
void Transform_Real(Word16 *mdctDelayBuffer,
Word16 *timeSignal,
Word16 chIncrement,
Word32 *realOut,
Word16 *mdctScale,
Word16 blockType
)
{
Word32 i,w;
Word32 timeSignalSample;
Word32 ws1,ws2;
Word16 *dctIn0, *dctIn1;
Word32 *outData0, *outData1;
Word32 *winPtr;
Word32 delayBufferSf,timeSignalSf,minSf;
switch(blockType){
case LONG_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + 448 new timeSignal samples
and get the biggest scale factor for next calculate more precise
*/
delayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer,BLOCK_SWITCHING_OFFSET,1);
timeSignalSf = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);
minSf = min(delayBufferSf,timeSignalSf);
minSf = min(minSf,14);
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
outData0 = realOut + FRAME_LEN_LONG/2;
/* add windows and pre add for mdct to last buffer*/
winPtr = (int *)LongWindowKBD;
for(i=0;i<FRAME_LEN_LONG/2;i++){
timeSignalSample = (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr >> 16);
timeSignalSample = (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr & 0xffff);
winPtr ++;
/* shift 2 to avoid overflow next */
*outData0++ = (ws1 >> 2) - (ws2 >> 2);
}
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
/* add windows and pre add for mdct to new buffer*/
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
outData0 = realOut + FRAME_LEN_LONG/2 - 1;
winPtr = (int *)LongWindowKBD;
for(i=0;i<FRAME_LEN_LONG/2;i++){
timeSignalSample = (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr & 0xffff);
timeSignalSample = (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr >> 16);
winPtr++;
/* shift 2 to avoid overflow next */
*outData0-- = -((ws1 >> 2) + (ws2 >> 2));
}
Mdct_Long(realOut);
/* update scale factor */
minSf = 14 - minSf;
*mdctScale=minSf;
break;
case START_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no timeSignal samples
and get the biggest scale factor for next calculate more precise
*/
minSf = getScalefactorOfShortVectorStride(mdctDelayBuffer,BLOCK_SWITCHING_OFFSET,1);
minSf = min(minSf,14);
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
outData0 = realOut + FRAME_LEN_LONG/2;
winPtr = (int *)LongWindowKBD;
/* add windows and pre add for mdct to last buffer*/
for(i=0;i<FRAME_LEN_LONG/2;i++){
timeSignalSample = (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr >> 16);
timeSignalSample = (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr & 0xffff);
winPtr ++;
*outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
}
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
outData0 = realOut + FRAME_LEN_LONG/2 - 1;
for(i=0;i<LS_TRANS;i++){
*outData0-- = -mdctDelayBuffer[i] << (15 - 2 + minSf);
}
/* add windows and pre add for mdct to new buffer*/
dctIn0 = mdctDelayBuffer + LS_TRANS;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;
outData0 = realOut + FRAME_LEN_LONG/2 - 1 -LS_TRANS;
winPtr = (int *)ShortWindowSine;
for(i=0;i<FRAME_LEN_SHORT/2;i++){
timeSignalSample= (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr & 0xffff);
timeSignalSample= (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr >> 16);
winPtr++;
*outData0-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
}
Mdct_Long(realOut);
/* update scale factor */
minSf = 14 - minSf;
*mdctScale= minSf;
break;
case STOP_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET-LS_TRANS (1600-448 ) delay buffer samples + 448 new timeSignal samples
and get the biggest scale factor for next calculate more precise
*/
delayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+LS_TRANS,BLOCK_SWITCHING_OFFSET-LS_TRANS,1);
timeSignalSf = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);
minSf = min(delayBufferSf,timeSignalSf);
minSf = min(minSf,13);
outData0 = realOut + FRAME_LEN_LONG/2;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
for(i=0;i<LS_TRANS;i++){
*outData0++ = -(*dctIn1--) << (15 - 2 + minSf);
}
/* add windows and pre add for mdct to last buffer*/
dctIn0 = mdctDelayBuffer + LS_TRANS;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;
outData0 = realOut + FRAME_LEN_LONG/2 + LS_TRANS;
winPtr = (int *)ShortWindowSine;
for(i=0;i<FRAME_LEN_SHORT/2;i++){
timeSignalSample = (*dctIn0++) << minSf;
ws1 = timeSignalSample * (*winPtr >> 16);
timeSignalSample= (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr & 0xffff);
winPtr++;
*outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
}
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
/* add windows and pre add for mdct to new buffer*/
dctIn0 = mdctDelayBuffer;
dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
outData0 = realOut + FRAME_LEN_LONG/2 - 1;
winPtr = (int *)LongWindowKBD;
for(i=0;i<FRAME_LEN_LONG/2;i++){
timeSignalSample= (*dctIn0++) << minSf;
ws1 = timeSignalSample *(*winPtr & 0xffff);
timeSignalSample= (*dctIn1--) << minSf;
ws2 = timeSignalSample * (*winPtr >> 16);
*outData0-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
winPtr++;
}
Mdct_Long(realOut);
minSf = 14 - minSf;
*mdctScale= minSf; /* update scale factor */
break;
case SHORT_WINDOW:
/*
we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no new timeSignal samples
and get the biggest scale factor for next calculate more precise
*/
minSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+TRANSFORM_OFFSET_SHORT,9*FRAME_LEN_SHORT,1);
minSf = min(minSf,10);
for(w=0;w<TRANS_FAC;w++){
dctIn0 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT;
dctIn1 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT + FRAME_LEN_SHORT-1;
outData0 = realOut + FRAME_LEN_SHORT/2;
outData1 = realOut + FRAME_LEN_SHORT/2 - 1;
winPtr = (int *)ShortWindowSine;
for(i=0;i<FRAME_LEN_SHORT/2;i++){
timeSignalSample= *dctIn0 << minSf;
ws1 = timeSignalSample * (*winPtr >> 16);
timeSignalSample= *dctIn1 << minSf;
ws2 = timeSignalSample * (*winPtr & 0xffff);
*outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
timeSignalSample= *(dctIn0 + FRAME_LEN_SHORT) << minSf;
ws1 = timeSignalSample * (*winPtr & 0xffff);
timeSignalSample= *(dctIn1 + FRAME_LEN_SHORT) << minSf;
ws2 = timeSignalSample * (*winPtr >> 16);
*outData1-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
winPtr++;
dctIn0++;
dctIn1--;
}
Mdct_Short(realOut);
realOut += FRAME_LEN_SHORT;
}
minSf = 11 - minSf;
*mdctScale = minSf; /* update scale factor */
shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
break;
}
}

36
aacenc/external/aacenc/src/transform.h vendored Normal file
View file

@ -0,0 +1,36 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: transform.h
Content: MDCT Transform functions
*******************************************************************************/
#ifndef __TRANSFORM_H__
#define __TRANSFORM_H__
#include "typedef.h"
void Transform_Real(Word16 *mdctDelayBuffer,
Word16 *timeSignal,
Word16 chIncrement, /*! channel increment */
Word32 *realOut,
Word16 *mdctScale,
Word16 windowSequence
);
#endif

63
aacenc/external/aacenc/src/typedef.h vendored Normal file
View file

@ -0,0 +1,63 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: typedef.h
Content: type defined for defferent paltform
*******************************************************************************/
#ifndef typedef_h
#define typedef_h "$Id $"
#undef ORIGINAL_TYPEDEF_H /* define to get "original" ETSI version
of typedef.h */
#ifdef ORIGINAL_TYPEDEF_H
/*
* this is the original code from the ETSI file typedef.h
*/
#if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__ZTC__)
typedef signed char Word8;
typedef short Word16;
typedef long Word32;
typedef int Flag;
#elif defined(__sun)
typedef signed char Word8;
typedef short Word16;
typedef long Word32;
typedef int Flag;
#elif defined(__unix__) || defined(__unix)
typedef signed char Word8;
typedef short Word16;
typedef int Word32;
typedef int Flag;
#endif
#else /* not original typedef.h */
/*
* use (improved) type definition file typdefs.h and add a "Flag" type
*/
#include "typedefs.h"
typedef int Flag;
#endif
#endif

187
aacenc/external/aacenc/src/typedefs.h vendored Normal file
View file

@ -0,0 +1,187 @@
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*******************************************************************************
File: typedefs.h
Content: type defined or const defined
*******************************************************************************/
#ifndef typedefs_h
#define typedefs_h "$Id $"
#ifndef CHAR_BIT
#define CHAR_BIT 8 /* number of bits in a char */
#endif
#ifndef VOAAC_SHRT_MAX
#define VOAAC_SHRT_MAX (32767) /* maximum (signed) short value */
#endif
#ifndef VOAAC_SHRT_MIN
#define VOAAC_SHRT_MIN (-32768) /* minimum (signed) short value */
#endif
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#ifndef assert
#define assert(_Expression) ((void)0)
#endif
#define __inline static __inline
#define INT_BITS 32
/*
********************************************************************************
* DEFINITION OF CONSTANTS
********************************************************************************
*/
/*
********* define char type
*/
typedef char Char;
/*
********* define 8 bit signed/unsigned types & constants
*/
typedef signed char Word8;
typedef unsigned char UWord8;
/*
********* define 16 bit signed/unsigned types & constants
*/
typedef short Word16;
typedef unsigned short UWord16;
/*
********* define 32 bit signed/unsigned types & constants
*/
typedef int Word32;
typedef unsigned int UWord32;
#ifndef _MSC_VER
typedef long long Word64;
typedef unsigned long long UWord64;
#else
typedef __int64 Word64;
typedef unsigned __int64 UWord64;
#endif
#ifndef min
#define min(a,b) ( a < b ? a : b)
#endif
#ifndef max
#define max(a,b) ( a > b ? a : b)
#endif
#ifdef ARM_INASM
#ifdef ARMV5_INASM
#define ARMV5E_INASM 1
#endif
#define ARMV4_INASM 1
#endif
#if ARMV4_INASM
#define ARMV5TE_SAT 1
#define ARMV5TE_ADD 1
#define ARMV5TE_SUB 1
#define ARMV5TE_SHL 1
#define ARMV5TE_SHR 1
#define ARMV5TE_L_SHL 1
#define ARMV5TE_L_SHR 1
#endif//ARMV4
#if ARMV5E_INASM
#define ARMV5TE_L_ADD 1
#define ARMV5TE_L_SUB 1
#define ARMV5TE_L_MULT 1
#define ARMV5TE_L_MAC 1
#define ARMV5TE_L_MSU 1
#define ARMV5TE_DIV_S 1
#define ARMV5TE_ROUND 1
#define ARMV5TE_MULT 1
#define ARMV5TE_NORM_S 1
#define ARMV5TE_NORM_L 1
#define ARMV5TE_L_MPY_LS 1
#endif
#if ARMV6_INASM
#undef ARMV5TE_ADD
#define ARMV5TE_ADD 0
#undef ARMV5TE_SUB
#define ARMV5TE_SUB 0
#define ARMV6_SAT 1
#endif
//basic operation functions optimization flags
#define SATRUATE_IS_INLINE 1 //define saturate as inline function
#define SHL_IS_INLINE 1 //define shl as inline function
#define SHR_IS_INLINE 1 //define shr as inline function
#define L_MULT_IS_INLINE 1 //define L_mult as inline function
#define L_MSU_IS_INLINE 1 //define L_msu as inline function
#define L_SUB_IS_INLINE 1 //define L_sub as inline function
#define L_SHL_IS_INLINE 1 //define L_shl as inline function
#define L_SHR_IS_INLINE 1 //define L_shr as inline function
#define ADD_IS_INLINE 1 //define add as inline function //add, inline is the best
#define SUB_IS_INLINE 1 //define sub as inline function //sub, inline is the best
#define DIV_S_IS_INLINE 1 //define div_s as inline function
#define MULT_IS_INLINE 1 //define mult as inline function
#define NORM_S_IS_INLINE 1 //define norm_s as inline function
#define NORM_L_IS_INLINE 1 //define norm_l as inline function
#define ROUND_IS_INLINE 1 //define round as inline function
#define L_MAC_IS_INLINE 1 //define L_mac as inline function
#define L_ADD_IS_INLINE 1 //define L_add as inline function
#define EXTRACT_H_IS_INLINE 1 //define extract_h as inline function
#define EXTRACT_L_IS_INLINE 1 //define extract_l as inline function //???
#define MULT_R_IS_INLINE 1 //define mult_r as inline function
#define SHR_R_IS_INLINE 1 //define shr_r as inline function
#define MAC_R_IS_INLINE 1 //define mac_r as inline function
#define MSU_R_IS_INLINE 1 //define msu_r as inline function
#define L_SHR_R_IS_INLINE 1 //define L_shr_r as inline function
#define PREFIX voAACEnc
#define LINK0(x, y, z) LINK1(x,y,z)
#define LINK1(x,y,z) x##y##z
#define ADD_PREFIX(func) LINK0(PREFIX, _, func)
#define L_Extract ADD_PREFIX(L_Extract)
#define L_Comp ADD_PREFIX(L_Comp)
#define Mpy_32 ADD_PREFIX(Mpy_32)
#define Mpy_32_16 ADD_PREFIX(Mpy_32_16)
#define Div_32 ADD_PREFIX(Div_32)
#define iLog4 ADD_PREFIX(iLog4)
#define rsqrt ADD_PREFIX(rsqrt)
#define pow2_xy ADD_PREFIX(pow2_xy)
#define L_mpy_ls ADD_PREFIX(L_mpy_ls)
#define L_mpy_wx ADD_PREFIX(L_mpy_wx)
#define TnsEncode ADD_PREFIX(TnsEncode)
#define GetSRIndex ADD_PREFIX(GetSRIndex)
#define WriteBitstream ADD_PREFIX(WriteBitstream)
#define mem_malloc ADD_PREFIX(mem_malloc)
#define mem_free ADD_PREFIX(mem_free)
#endif

116
encode.go Normal file
View file

@ -0,0 +1,116 @@
// Package aac provides AAC codec encoder based on [VisualOn AAC encoder library](https://github.com/mstorsjo/vo-aacenc) library.
package aac
import "C"
import (
"io"
"unsafe"
"github.com/gen2brain/aac-go/aacenc"
)
// Options represent encoding options.
type Options struct {
// Audio file sample rate
SampleRate int
// Encoder bit rate in bits/sec
BitRate int
// Number of channels on input (1,2)
NumChannels int
}
// Encoder type.
type Encoder struct {
w io.Writer
insize int
inbuf []byte
outbuf []byte
}
// NewEncoder returns new AAC encoder.
func NewEncoder(w io.Writer, opts *Options) (e *Encoder, err error) {
e = &Encoder{}
e.w = w
if opts.BitRate == 0 {
opts.BitRate = 64000
}
ret := aacenc.Init(aacenc.VoAudioCodingAac)
err = aacenc.ErrorFromResult(ret)
if err != nil {
return
}
var params aacenc.AacencParam
params.SampleRate = int32(opts.SampleRate)
params.BitRate = int32(opts.BitRate)
params.NChannels = int16(opts.NumChannels)
params.AdtsUsed = 1
ret = aacenc.SetParam(aacenc.VoPidAacEncparam, unsafe.Pointer(&params))
err = aacenc.ErrorFromResult(ret)
if err != nil {
return
}
e.insize = int(opts.NumChannels) * 2 * 1024
e.inbuf = make([]byte, e.insize)
e.outbuf = make([]byte, 20480)
return
}
// Encode encodes data from reader.
func (e *Encoder) Encode(r io.Reader) (err error) {
for {
n, err := r.Read(e.inbuf)
if err != nil {
if err != io.EOF {
return err
}
break
}
if n < e.insize {
break
}
var outinfo aacenc.VoAudioOutputinfo
var input, output aacenc.VoCodecBuffer
input.Buffer = C.CBytes(e.inbuf)
input.Length = uint64(n)
ret := aacenc.SetInputData(&input)
err = aacenc.ErrorFromResult(ret)
if err != nil {
return err
}
output.Buffer = C.CBytes(e.outbuf)
output.Length = uint64(len(e.outbuf))
ret = aacenc.GetOutputData(&output, &outinfo)
err = aacenc.ErrorFromResult(ret)
if err != nil {
return err
}
_, err = e.w.Write(C.GoBytes(output.Buffer, C.int(output.Length)))
if err != nil {
return err
}
}
return nil
}
// Close closes encoder.
func (e *Encoder) Close() error {
ret := aacenc.Uninit()
return aacenc.ErrorFromResult(ret)
}

50
encode_test.go Normal file
View file

@ -0,0 +1,50 @@
package aac
import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/youpy/go-wav"
)
func TestEncode(t *testing.T) {
file, err := os.Open(filepath.Join("testdata", "test.wav"))
if err != nil {
t.Fatal(err)
}
wr := wav.NewReader(file)
f, err := wr.Format()
if err != nil {
t.Fatal(err)
}
buf := bytes.NewBuffer(make([]byte, 0))
opts := &Options{}
opts.SampleRate = int(f.SampleRate)
opts.NumChannels = int(f.NumChannels)
enc, err := NewEncoder(buf, opts)
if err != nil {
t.Fatal(err)
}
err = enc.Encode(wr)
if err != nil {
t.Error(err)
}
err = enc.Close()
if err != nil {
t.Error(err)
}
err = ioutil.WriteFile(filepath.Join(os.TempDir(), "test.aac"), buf.Bytes(), 0644)
if err != nil {
t.Error(err)
}
}

49
examples/basic/basic.go Normal file
View file

@ -0,0 +1,49 @@
package main
import (
"bytes"
"io/ioutil"
"os"
"github.com/gen2brain/aac-go"
"github.com/youpy/go-wav"
)
func main() {
file, err := os.Open("test.wav")
if err != nil {
panic(err)
}
wreader := wav.NewReader(file)
f, err := wreader.Format()
if err != nil {
panic(err)
}
buf := bytes.NewBuffer(make([]byte, 0))
opts := &aac.Options{}
opts.SampleRate = int(f.SampleRate)
opts.NumChannels = int(f.NumChannels)
enc, err := aac.NewEncoder(buf, opts)
if err != nil {
panic(err)
}
err = enc.Encode(wreader)
if err != nil {
panic(err)
}
err = enc.Close()
if err != nil {
panic(err)
}
err = ioutil.WriteFile("test.aac", buf.Bytes(), 0644)
if err != nil {
panic(err)
}
}

BIN
testdata/test.wav vendored Normal file

Binary file not shown.