Initial commit
This commit is contained in:
commit
0e9ca200fb
22
.appveyor.yml
Normal file
22
.appveyor.yml
Normal 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
7
.travis.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
|
||||
script:
|
||||
- go test -v ./
|
191
COPYING
Normal file
191
COPYING
Normal 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
69
README.md
Normal 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
316
aacenc/aacenc.go
Normal 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
36
aacenc/aacenc_cgo.go
Normal 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
191
aacenc/external/aacenc/COPYING
vendored
Normal 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
7
aacenc/external/aacenc/README
vendored
Normal 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
82
aacenc/external/aacenc/include/voAAC.h
vendored
Normal 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
173
aacenc/external/aacenc/include/voAudio.h
vendored
Normal 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
193
aacenc/external/aacenc/include/voIndex.h
vendored
Normal 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
65
aacenc/external/aacenc/include/voMem.h
vendored
Normal 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
197
aacenc/external/aacenc/include/voType.h
vendored
Normal 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
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
117
aacenc/external/aacenc/src/aac_rom.h
vendored
Normal 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
505
aacenc/external/aacenc/src/aacenc.c
vendored
Normal 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
238
aacenc/external/aacenc/src/aacenc_core.c
vendored
Normal 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
117
aacenc/external/aacenc/src/aacenc_core.h
vendored
Normal 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
1230
aacenc/external/aacenc/src/adj_thr.c
vendored
Normal 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
57
aacenc/external/aacenc/src/adj_thr.h
vendored
Normal 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
|
69
aacenc/external/aacenc/src/adj_thr_data.h
vendored
Normal file
69
aacenc/external/aacenc/src/adj_thr_data.h
vendored
Normal 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
102
aacenc/external/aacenc/src/band_nrg.c
vendored
Normal 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
46
aacenc/external/aacenc/src/band_nrg.h
vendored
Normal 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
1178
aacenc/external/aacenc/src/basic_op.h
vendored
Normal 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
1624
aacenc/external/aacenc/src/basicop2.c
vendored
Normal 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
885
aacenc/external/aacenc/src/bit_cnt.c
vendored
Normal 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
106
aacenc/external/aacenc/src/bit_cnt.h
vendored
Normal 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
150
aacenc/external/aacenc/src/bitbuffer.c
vendored
Normal 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
89
aacenc/external/aacenc/src/bitbuffer.h
vendored
Normal 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
693
aacenc/external/aacenc/src/bitenc.c
vendored
Normal 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
50
aacenc/external/aacenc/src/bitenc.h
vendored
Normal 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 */
|
404
aacenc/external/aacenc/src/block_switch.c
vendored
Normal file
404
aacenc/external/aacenc/src/block_switch.c
vendored
Normal 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);
|
||||
}
|
72
aacenc/external/aacenc/src/block_switch.h
vendored
Normal file
72
aacenc/external/aacenc/src/block_switch.h
vendored
Normal 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
123
aacenc/external/aacenc/src/channel_map.c
vendored
Normal 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;
|
||||
}
|
37
aacenc/external/aacenc/src/channel_map.h
vendored
Normal file
37
aacenc/external/aacenc/src/channel_map.h
vendored
Normal 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
89
aacenc/external/aacenc/src/cmnMemory.c
vendored
Normal 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
106
aacenc/external/aacenc/src/cmnMemory.h
vendored
Normal 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
36
aacenc/external/aacenc/src/config.h
vendored
Normal 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
544
aacenc/external/aacenc/src/dyn_bits.c
vendored
Normal 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
82
aacenc/external/aacenc/src/dyn_bits.h
vendored
Normal 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
188
aacenc/external/aacenc/src/grp_data.c
vendored
Normal 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
44
aacenc/external/aacenc/src/grp_data.h
vendored
Normal 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
112
aacenc/external/aacenc/src/interface.c
vendored
Normal 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
106
aacenc/external/aacenc/src/interface.h
vendored
Normal 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
145
aacenc/external/aacenc/src/line_pe.c
vendored
Normal 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
75
aacenc/external/aacenc/src/line_pe.h
vendored
Normal 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
112
aacenc/external/aacenc/src/memalign.c
vendored
Normal 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
35
aacenc/external/aacenc/src/memalign.h
vendored
Normal 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
138
aacenc/external/aacenc/src/ms_stereo.c
vendored
Normal 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
45
aacenc/external/aacenc/src/ms_stereo.h
vendored
Normal 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
363
aacenc/external/aacenc/src/oper_32b.c
vendored
Normal 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
89
aacenc/external/aacenc/src/oper_32b.h
vendored
Normal 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
|
113
aacenc/external/aacenc/src/pre_echo_control.c
vendored
Normal file
113
aacenc/external/aacenc/src/pre_echo_control.c
vendored
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
aacenc/external/aacenc/src/pre_echo_control.h
vendored
Normal file
42
aacenc/external/aacenc/src/pre_echo_control.h
vendored
Normal 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
|
||||
|
505
aacenc/external/aacenc/src/psy_configuration.c
vendored
Normal file
505
aacenc/external/aacenc/src/psy_configuration.c
vendored
Normal 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);
|
||||
}
|
||||
|
107
aacenc/external/aacenc/src/psy_configuration.h
vendored
Normal file
107
aacenc/external/aacenc/src/psy_configuration.h
vendored
Normal 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
80
aacenc/external/aacenc/src/psy_const.h
vendored
Normal 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
66
aacenc/external/aacenc/src/psy_data.h
vendored
Normal 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
815
aacenc/external/aacenc/src/psy_main.c
vendored
Normal 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
69
aacenc/external/aacenc/src/psy_main.h
vendored
Normal 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
143
aacenc/external/aacenc/src/qc_data.h
vendored
Normal 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
578
aacenc/external/aacenc/src/qc_main.c
vendored
Normal 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
64
aacenc/external/aacenc/src/qc_main.h
vendored
Normal 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
445
aacenc/external/aacenc/src/quantize.c
vendored
Normal 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
42
aacenc/external/aacenc/src/quantize.h
vendored
Normal 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
882
aacenc/external/aacenc/src/sf_estim.c
vendored
Normal 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
46
aacenc/external/aacenc/src/sf_estim.h
vendored
Normal 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
52
aacenc/external/aacenc/src/spreading.c
vendored
Normal 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
33
aacenc/external/aacenc/src/spreading.h
vendored
Normal 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
237
aacenc/external/aacenc/src/stat_bits.c
vendored
Normal 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
34
aacenc/external/aacenc/src/stat_bits.h
vendored
Normal 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
908
aacenc/external/aacenc/src/tns.c
vendored
Normal 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
108
aacenc/external/aacenc/src/tns.h
vendored
Normal 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
75
aacenc/external/aacenc/src/tns_func.h
vendored
Normal 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
52
aacenc/external/aacenc/src/tns_param.h
vendored
Normal 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
677
aacenc/external/aacenc/src/transform.c
vendored
Normal 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
36
aacenc/external/aacenc/src/transform.h
vendored
Normal 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
63
aacenc/external/aacenc/src/typedef.h
vendored
Normal 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
187
aacenc/external/aacenc/src/typedefs.h
vendored
Normal 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
116
encode.go
Normal 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(¶ms))
|
||||
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
50
encode_test.go
Normal 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
49
examples/basic/basic.go
Normal 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
BIN
testdata/test.wav
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue