mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Initial commit
This commit is contained in:
commit
bbe9ba3e6c
26
.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
name: 提交Bug / Submit Bug
|
||||||
|
about: 向我们报告一个Bug以帮助我们改进
|
||||||
|
title: 'bug: '
|
||||||
|
labels: bug
|
||||||
|
---
|
||||||
|
|
||||||
|
警告: 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭
|
||||||
|
- 确保您使用的是 [最新开发版本](https://github.com/whitechi73/Shamrock/actions/workflows/build-apk.yml) 的 Shamrock.
|
||||||
|
- 确保您的问题尚未在 Issues 列表中提出.
|
||||||
|
- 确保您的问题不是由于您的代码错误导致的.
|
||||||
|
|
||||||
|
### 描述 Bug
|
||||||
|
|
||||||
|
请清晰地描述此 Bug 的具体表现,并提供错误日志。
|
||||||
|
|
||||||
|
### 复现 Bug
|
||||||
|
|
||||||
|
请提供复现 Bug 的详细步骤,以确保我们可以理解并定位问题。
|
||||||
|
|
||||||
|
## 系统信息
|
||||||
|
|
||||||
|
- Shamrock 版本:
|
||||||
|
- Android 版本:
|
||||||
|
- 设备的制造商和型号:
|
||||||
|
- 设备的 CPU 架构:
|
21
.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
name: 功能请求 / Feature Request
|
||||||
|
about: 向我们提交一个新功能的请求
|
||||||
|
title: 'feat: '
|
||||||
|
labels: enhancement
|
||||||
|
---
|
||||||
|
|
||||||
|
警告: 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭
|
||||||
|
|
||||||
|
- 确保您使用的是 [最新开发版本](https://github.com/whitechi73/Shamrock/actions/workflows/build-apk.yml) 的 Shamrock.
|
||||||
|
- 确保您的功能请求尚未在 Issues 列表中提出.
|
||||||
|
- 确保您的功能请求是与 Shamrock 相关的,且可以实现.
|
||||||
|
|
||||||
|
### 描述功能
|
||||||
|
|
||||||
|
请清晰地描述您想要的功能,并提供相关的信息。
|
||||||
|
|
||||||
|
### 实现方法
|
||||||
|
|
||||||
|
请提供您认为可以实现此功能的方法,如果您不知道如何实现,可以留空。
|
||||||
|
当然,如果您有兴趣,也可以自己实现并向我们提交 Pull Request。
|
87
.github/workflows/build-apk.yml
vendored
Normal file
87
.github/workflows/build-apk.yml
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
name: Build Shamrock APK
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
- '**.txt'
|
||||||
|
- '.github/**'
|
||||||
|
- '.idea/**'
|
||||||
|
- '!.github/workflows/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build APK
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: "temurin"
|
||||||
|
java-version: 17
|
||||||
|
cache: 'gradle'
|
||||||
|
|
||||||
|
- name: Setup cmake
|
||||||
|
run: |
|
||||||
|
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.22.1" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
|
||||||
|
echo "sdk.dir=${ANDROID_HOME}" > local.properties
|
||||||
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/gradle-build-action@v2.9.0
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: |
|
||||||
|
echo ${{ secrets.SIGN_KEYSTORE_BASE64 }} | base64 -d > keystore.jks
|
||||||
|
chmod +x ./gradlew
|
||||||
|
./gradlew :app:assembleRelease --build-cache --parallel --daemon --warning-mode all --stacktrace
|
||||||
|
echo "APK_FILE_ALL=$(find app/build/outputs/apk/app/release -name '*.apk')" >> $GITHUB_ENV
|
||||||
|
echo "APK_FILE_ARM64=$(find app/build/outputs/apk/arm64/release -name '*.apk')" >> $GITHUB_ENV
|
||||||
|
echo "APK_FILE_X86_64=$(find app/build/outputs/apk/x64/release -name '*.apk')" >> $GITHUB_ENV
|
||||||
|
env:
|
||||||
|
KEYSTORE_PATH: "../keystore.jks"
|
||||||
|
KEYSTORE_PASSWORD: ${{ secrets.SIGN_KEYSTORE_PASSWORD }}
|
||||||
|
KEY_ALIAS: ${{ secrets.SIGN_ALIAS }}
|
||||||
|
KEY_PASSWORD: ${{ secrets.SIGN_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Install aapt
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y aapt
|
||||||
|
|
||||||
|
- name: Set Shamrock Version
|
||||||
|
run: |
|
||||||
|
apk_file=${{ env.APK_FILE_ALL }}
|
||||||
|
apk_dump=$(aapt dump badging "$apk_file")
|
||||||
|
version_name=$(sed -n "s/.*versionName='\([^']*\)'.*/\1/p" <<< "$apk_dump")
|
||||||
|
echo "SHAMROCK_VERSION=$version_name" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Show Artifacts SHA256
|
||||||
|
run: |
|
||||||
|
echo "### Build Success :rocket:" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|ABI|SHA256|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|:--------:|:----------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
all=($(sha256sum ${{ env.APK_FILE_ALL }}))
|
||||||
|
echo "|all|$all" >> $GITHUB_STEP_SUMMARY
|
||||||
|
arm64=($(sha256sum ${{ env.APK_FILE_ARM64 }}))
|
||||||
|
echo "|arm64|$arm64" >> $GITHUB_STEP_SUMMARY
|
||||||
|
x86_64=($(sha256sum ${{ env.APK_FILE_X86_64 }}))
|
||||||
|
echo "|x86_64|$x86_64" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
- name: Upload ALL APK RELEASE
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Shamrock-v${{ env.SHAMROCK_VERSION }}-all
|
||||||
|
path: ${{ env.APK_FILE_ALL }}
|
||||||
|
|
||||||
|
- name: Upload ARM64 APK RELEASE
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Shamrock-v${{ env.SHAMROCK_VERSION }}-arm64
|
||||||
|
path: ${{ env.APK_FILE_ARM64 }}
|
||||||
|
|
||||||
|
- name: Upload X86_64 APK RELEASE
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Shamrock-v${{ env.SHAMROCK_VERSION }}-x86_64
|
||||||
|
path: ${{ env.APK_FILE_X86_64 }}
|
57
.github/workflows/codeql.yml
vendored
Normal file
57
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
schedule:
|
||||||
|
- cron: '24 7 * * 4'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 360
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'cpp', 'java' ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3.6.0
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
|
||||||
|
- name: Setup JDK 17
|
||||||
|
uses: actions/setup-java@v3.12.0
|
||||||
|
with:
|
||||||
|
distribution: "temurin"
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/gradle-build-action@v2.8.0
|
||||||
|
|
||||||
|
- name: Setup cmake
|
||||||
|
run: |
|
||||||
|
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.22.1" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
|
||||||
|
echo "sdk.dir=${ANDROID_HOME}" > local.properties
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
chmod +x ./gradlew
|
||||||
|
./gradlew :app:assembleAppRelease
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
73
.github/workflows/release.yml
vendored
Normal file
73
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
name: Shamrock Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: "temurin"
|
||||||
|
java-version: 17
|
||||||
|
cache: 'gradle'
|
||||||
|
|
||||||
|
- name: Setup cmake
|
||||||
|
run: |
|
||||||
|
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.22.1" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
|
||||||
|
echo "sdk.dir=${ANDROID_HOME}" > local.properties
|
||||||
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/gradle-build-action@v2.9.0
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: |
|
||||||
|
echo ${{ secrets.SIGN_KEYSTORE_BASE64 }} | base64 -d > keystore.jks
|
||||||
|
chmod +x ./gradlew
|
||||||
|
./gradlew :app:assembleRelease --build-cache --parallel --daemon --warning-mode all --stacktrace
|
||||||
|
echo "APK_FILE_ALL=$(find app/build/outputs/apk/app/release -name '*.apk')" >> $GITHUB_ENV
|
||||||
|
echo "APK_FILE_ARM64=$(find app/build/outputs/apk/arm64/release -name '*.apk')" >> $GITHUB_ENV
|
||||||
|
echo "APK_FILE_X86_64=$(find app/build/outputs/apk/x64/release -name '*.apk')" >> $GITHUB_ENV
|
||||||
|
env:
|
||||||
|
KEYSTORE_PATH: "../keystore.jks"
|
||||||
|
KEYSTORE_PASSWORD: ${{ secrets.SIGN_KEYSTORE_PASSWORD }}
|
||||||
|
KEY_ALIAS: ${{ secrets.SIGN_ALIAS }}
|
||||||
|
KEY_PASSWORD: ${{ secrets.SIGN_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Install aapt
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y aapt
|
||||||
|
|
||||||
|
- name: Set Shamrock Version
|
||||||
|
run: |
|
||||||
|
apk_file=${{ env.APK_FILE_ALL }}
|
||||||
|
apk_dump=$(aapt dump badging "$apk_file")
|
||||||
|
version_name=$(sed -n "s/.*versionName='\([^']*\)'.*/\1/p" <<< "$apk_dump")
|
||||||
|
echo "SHAMROCK_VERSION=$version_name" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Show Artifacts SHA256
|
||||||
|
run: |
|
||||||
|
echo "### Build Success :rocket:" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|ABI|SHA256|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|:--------:|:----------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
all=($(sha256sum ${{ env.APK_FILE_ALL }}))
|
||||||
|
echo "|all|$all" >> $GITHUB_STEP_SUMMARY
|
||||||
|
arm64=($(sha256sum ${{ env.APK_FILE_ARM64 }}))
|
||||||
|
echo "|arm64|$arm64" >> $GITHUB_STEP_SUMMARY
|
||||||
|
x86_64=($(sha256sum ${{ env.APK_FILE_X86_64 }}))
|
||||||
|
echo "|x86_64|$x86_64" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: marvinpinto/action-automatic-releases@latest
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
automatic_release_tag: Shamrock v${{ env.SHAMROCK_VERSION }}
|
||||||
|
files: |
|
||||||
|
${{ env.APK_FILE_ALL }}
|
||||||
|
${{ env.APK_FILE_ARM64 }}
|
||||||
|
${{ env.APK_FILE_X86_64 }}
|
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle/
|
||||||
|
local.properties
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
build/
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
app/app/release
|
||||||
|
app/arm64/release
|
||||||
|
app/x64/release
|
BIN
AudioLibrary.zip
Normal file
BIN
AudioLibrary.zip
Normal file
Binary file not shown.
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
mut@vip.qq.com.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
1
CONTRIBUTING.md
Normal file
1
CONTRIBUTING.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
docs
|
674
LICENSE
Normal file
674
LICENSE
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
106
README.md
Normal file
106
README.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
![][banner]
|
||||||
|
|
||||||
|
[![][actions]][actions-link]
|
||||||
|
[![][releases]][releases-link]
|
||||||
|
[![][downloads]][releases-link]
|
||||||
|
|
||||||
|
![][onebot-11]
|
||||||
|
![][onebot-12]
|
||||||
|
[![][license]](LICENSE)
|
||||||
|
|
||||||
|
[下载][download-link] | [部署][deploy-link] | [接口][api-link] | [文档][docs-link] | [加群][group-link]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
☘ 基于 Xposed 实现 OneBot 标准的 QQ 机器人框架,原作者**fuqiuluo**已脱离开发,接下来由白池接手哦!本项目为OpenShamrock,不会有任何收费行为,欢迎大家的加入!
|
||||||
|
|
||||||
|
> 本项目仅提供学习与交流用途,请在24小时内删除。
|
||||||
|
> 本项目目的是研究 Xposed 和 LSPosed 框架的使用。 Epic 框架开发相关知识。
|
||||||
|
> 如有违反法律,请联系删除。
|
||||||
|
> 请勿在任何平台宣传,宣扬,转发本项目,请勿恶意修改企业安装包造成相关企业产生损失,如有违背,必将追责到底。
|
||||||
|
|
||||||
|
## 兼容|迁移|替代 说明
|
||||||
|
|
||||||
|
- 一键移植:本项目基于 go-cqhttp 的文档进行开发实现。
|
||||||
|
- 平行部署:可多平台部署,未来将会支持 Docker 部署的教程。
|
||||||
|
|
||||||
|
> 若您追求小而轻便的Bot服务, [Chronocat](https://chronocat.vercel.app/)是您的不二之选,而不是迁移到闭源框架。
|
||||||
|
|
||||||
|
## 权限声明
|
||||||
|
|
||||||
|
如出现未在此处声明的权限,请警惕 Shamrock 是否被修改/植入恶意代码
|
||||||
|
|
||||||
|
- 网络访问权限: Shamrock 进程需要使用 HTTP API 来进行一些操作
|
||||||
|
- [Hook 系统框架][hook-system]: 为了保证息屏状态下服务不被杀死,Shamrock 需要 Hook 系统框架
|
||||||
|
- 后台启动 Activity: 自动唤醒 QQ 时需要使用
|
||||||
|
|
||||||
|
## 语音解码
|
||||||
|
|
||||||
|
请参考文档中 [语音支持][voice-support] 部分
|
||||||
|
|
||||||
|
## 贡献说明
|
||||||
|
|
||||||
|
<img src="https://github.com/whitechi73/Shamrock/assets/61898844/b7b1f44a-2ab3-4eae-a955-4f8a7ef696f5" width="160px"> **我可爱吗?欢迎你的到来,这里是一个很大的地方,有着无限可能,主要是有你啦!**
|
||||||
|
|
||||||
|
## 开源协议
|
||||||
|
|
||||||
|
本项目使用 [GPL-3.0](LICENSE) 协议开放源代码
|
||||||
|
|
||||||
|
```text
|
||||||
|
Shamrock - OneBot standard QQ robot framework based on Xposed implementation
|
||||||
|
Copyright (C) 2023 Shamrock Team
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
```
|
||||||
|
|
||||||
|
## 贡献者
|
||||||
|
|
||||||
|
[![][contrib-image]][contrib-link]
|
||||||
|
|
||||||
|
[banner]: https://socialify.git.ci/whitechi73/Shamrock/image?description=1&forks=1&issues=1&logo=https%3A%2F%2Fwhitechi73.github.io%2FShamrock%2Fshamrock.jpg&pattern=Plus&pulls=1&stargazers=1&theme=Auto
|
||||||
|
|
||||||
|
[actions]: https://img.shields.io/github/actions/workflow/status/whitechi73/Shamrock/build-apk.yml?style=for-the-badge
|
||||||
|
|
||||||
|
[actions-link]: https://github.com/whitechi73/Shamrock/actions/workflows/build-apk.yml
|
||||||
|
|
||||||
|
[releases]: https://img.shields.io/github/v/release/whitechi73/Shamrock?style=for-the-badge
|
||||||
|
|
||||||
|
[releases-link]: https://github.com/whitechi73/Shamrock/releases
|
||||||
|
|
||||||
|
[downloads]: https://img.shields.io/github/downloads/whitechi73/Shamrock/total?style=for-the-badge
|
||||||
|
|
||||||
|
[license]: https://img.shields.io/github/license/whitechi73/Shamrock?style=for-the-badge
|
||||||
|
|
||||||
|
[onebot-11]: https://img.shields.io/badge/OneBot-11-black?style=for-the-badge
|
||||||
|
|
||||||
|
[onebot-12]: https://img.shields.io/badge/OneBot-12-black?style=for-the-badge
|
||||||
|
|
||||||
|
[download-link]: https://whitechi73.github.io/Shamrock/guide/getting-started.html#%E4%B8%8B%E8%BD%BD
|
||||||
|
|
||||||
|
[deploy-link]: https://whitechi73.github.io/Shamrock/guide/getting-started.html#%E9%83%A8%E7%BD%B2
|
||||||
|
|
||||||
|
[api-link]: https://whitechi73.github.io/Shamrock/api
|
||||||
|
|
||||||
|
[docs-link]: https://whitechi73.github.io/Shamrock/
|
||||||
|
|
||||||
|
[group-link]: https://whitechi73.github.io/Shamrock/group.html
|
||||||
|
|
||||||
|
[hook-system]: https://github.com/whitechi73/Shamrock/wiki/perm_hook_android
|
||||||
|
|
||||||
|
[voice-support]: https://whitechi73.github.io/Shamrock/advanced/voice.html
|
||||||
|
|
||||||
|
[contrib-image]: https://contrib.rocks/image?repo=whitechi73/Shamrock
|
||||||
|
|
||||||
|
[contrib-link]: https://github.com/whitechi73/Shamrock/graphs/contributors
|
11
SECURITY.md
Normal file
11
SECURITY.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Support Version
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 8.9.75 | :white_check_mark: |
|
||||||
|
| 8.9.73 | :white_check_mark: |
|
||||||
|
| 8.9.98 | :white_check_mark: |
|
||||||
|
| < 8.9.68| :x: |
|
||||||
|
|
2
app/.gitignore
vendored
Normal file
2
app/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/build
|
||||||
|
/release/
|
204
app/build.gradle.kts
Normal file
204
app/build.gradle.kts
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
import com.android.build.api.dsl.ApplicationExtension
|
||||||
|
|
||||||
|
fun gitCommitHash(): String {
|
||||||
|
val builder = ProcessBuilder("git", "rev-parse", "--short", "HEAD")
|
||||||
|
val process = builder.start()
|
||||||
|
val reader = process.inputReader()
|
||||||
|
val hash = reader.readText().trim()
|
||||||
|
return if (hash.isNotEmpty()) ".$hash" else ""
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
id("org.jetbrains.kotlin.android")
|
||||||
|
kotlin("plugin.serialization") version "1.8.10"
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "moe.fuqiuluo.shamrock"
|
||||||
|
ndkVersion = "25.1.8937393"
|
||||||
|
compileSdk = 33
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "moe.fuqiuluo.shamrock"
|
||||||
|
minSdk = 24
|
||||||
|
targetSdk = 33
|
||||||
|
versionCode = (System.currentTimeMillis() / 1000).toInt()
|
||||||
|
versionName = "1.0.5-dev" + gitCommitHash()
|
||||||
|
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
vectorDrawables {
|
||||||
|
useSupportLibrary = true
|
||||||
|
}
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
cppFlags += ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = false
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android.applicationVariants.all {
|
||||||
|
outputs.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
|
||||||
|
.forEach {
|
||||||
|
val abi = it.outputFileName.split("-")[1].split(".apk")[0]
|
||||||
|
val abiName = when (abi) {
|
||||||
|
"app" -> "all"
|
||||||
|
"x64" -> "x86_64"
|
||||||
|
else -> abi
|
||||||
|
}
|
||||||
|
it.outputFileName = "Shamrock-v${versionName}-${abiName}.apk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flavorDimensions.add("mode")
|
||||||
|
|
||||||
|
productFlavors {
|
||||||
|
create("app") {
|
||||||
|
dimension = "mode"
|
||||||
|
ndk {
|
||||||
|
abiFilters.add("arm64-v8a")
|
||||||
|
abiFilters.add("x86_64")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create("arm64") {
|
||||||
|
dimension = "mode"
|
||||||
|
ndk {
|
||||||
|
abiFilters.add("arm64-v8a")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create("x64") {
|
||||||
|
dimension = "mode"
|
||||||
|
ndk {
|
||||||
|
abiFilters.add("x86_64")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "17"
|
||||||
|
}
|
||||||
|
buildFeatures {
|
||||||
|
compose = true
|
||||||
|
}
|
||||||
|
composeOptions {
|
||||||
|
kotlinCompilerExtensionVersion = "1.4.3"
|
||||||
|
}
|
||||||
|
packaging {
|
||||||
|
jniLibs {
|
||||||
|
useLegacyPackaging = true
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||||
|
excludes += "/META-INF/*"
|
||||||
|
excludes += "/META-INF/NOTICE.txt"
|
||||||
|
excludes += "/META-INF/DEPENDENCIES.txt"
|
||||||
|
excludes += "/META-INF/NOTICE"
|
||||||
|
excludes += "/META-INF/LICENSE"
|
||||||
|
excludes += "/META-INF/DEPENDENCIES"
|
||||||
|
excludes += "/META-INF/notice.txt"
|
||||||
|
excludes += "/META-INF/dependencies.txt"
|
||||||
|
excludes += "/META-INF/LGPL2.1"
|
||||||
|
excludes += "/META-INF/ASL2.0"
|
||||||
|
excludes += "/META-INF/INDEX.LIST"
|
||||||
|
excludes += "/META-INF/io.netty.versions.properties"
|
||||||
|
excludes += "/META-INF/INDEX.LIST"
|
||||||
|
excludes += "/META-INF/LICENSE.txt"
|
||||||
|
excludes += "/META-INF/license.txt"
|
||||||
|
excludes += "/META-INF/*.kotlin_module"
|
||||||
|
excludes += "/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path = file("src/main/cpp/CMakeLists.txt")
|
||||||
|
version = "3.22.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configureAppSigningConfigsForRelease(project)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun configureAppSigningConfigsForRelease(project: Project) {
|
||||||
|
val keystorePath: String? = System.getenv("KEYSTORE_PATH")
|
||||||
|
if (keystorePath.isNullOrBlank()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
project.configure<ApplicationExtension> {
|
||||||
|
signingConfigs {
|
||||||
|
create("release") {
|
||||||
|
storeFile = file(System.getenv("KEYSTORE_PATH"))
|
||||||
|
storePassword = System.getenv("KEYSTORE_PASSWORD")
|
||||||
|
keyAlias = System.getenv("KEY_ALIAS")
|
||||||
|
keyPassword = System.getenv("KEY_PASSWORD")
|
||||||
|
enableV2Signing = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
signingConfig = signingConfigs.findByName("release")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("androidx.core:core-ktx:1.9.0")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
|
||||||
|
implementation("androidx.activity:activity-compose:1.7.2")
|
||||||
|
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
|
||||||
|
implementation("androidx.compose.ui:ui")
|
||||||
|
implementation("androidx.compose.ui:ui-graphics")
|
||||||
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||||
|
implementation("androidx.compose.material3:material3")
|
||||||
|
//noinspection GradleDynamicVersion
|
||||||
|
implementation("com.google.accompanist:accompanist-pager:0.31.5+")
|
||||||
|
//noinspection GradleDynamicVersion
|
||||||
|
implementation("com.google.accompanist:accompanist-systemuicontroller:0.31.5+")
|
||||||
|
//noinspection GradleDynamicVersion useless
|
||||||
|
// implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0+")
|
||||||
|
implementation("io.coil-kt:coil:2.4.0")
|
||||||
|
implementation("io.coil-kt:coil-compose:2.4.0")
|
||||||
|
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.1.16")
|
||||||
|
implementation("io.ktor:ktor-server-core:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-server-host-common:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-server-status-pages:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-server-netty:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-server-content-negotiation:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-client-core:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-client-cio:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-client-content-negotiation:2.3.3")
|
||||||
|
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.3")
|
||||||
|
// useless
|
||||||
|
//implementation ("com.maxkeppeler.sheets-compose-dialogs:core:1.2.0")
|
||||||
|
//implementation ("com.maxkeppeler.sheets-compose-dialogs:info:1.2.0")
|
||||||
|
//implementation ("com.maxkeppeler.sheets-compose-dialogs:input:1.2.0")
|
||||||
|
//implementation ("com.maxkeppeler.sheets-compose-dialogs:list:1.2.0")
|
||||||
|
//implementation ("com.maxkeppeler.sheets-compose-dialogs:state:1.2.0")
|
||||||
|
|
||||||
|
implementation(project(":xposed"))
|
||||||
|
|
||||||
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
androidTestImplementation(platform("androidx.compose:compose-bom:2023.06.01"))
|
||||||
|
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||||
|
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||||
|
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||||
|
}
|
215
app/proguard-rules.pro
vendored
Normal file
215
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
|
||||||
|
# Never inline methods, but allow shrinking and obfuscation.
|
||||||
|
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.view.ViewCompat$Api* {
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.view.WindowInsetsCompat$*Impl* {
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.app.NotificationCompat$*$Api*Impl {
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.os.UserHandleCompat$Api*Impl {
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.widget.EdgeEffectCompat$Api*Impl {
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep metadata about inner emulated classes. This helps with
|
||||||
|
# reflection on older platforms, but can be omitted if the
|
||||||
|
# metadata usage is not present in the app.
|
||||||
|
|
||||||
|
-keepclassmembers class * {
|
||||||
|
** CREATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep the special static methods that are required in all enumeration
|
||||||
|
# classes.
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep public class androidx.appcompat.widget.** { *; }
|
||||||
|
-keep public class androidx.appcompat.app.** { *; }
|
||||||
|
-keep public class androidx.appcompat.view.menu.** { *; }
|
||||||
|
|
||||||
|
# Ensure that reflectively-loaded inflater is not obfuscated. This can be
|
||||||
|
# removed when we stop supporting AAPT1 builds.
|
||||||
|
-keepnames class androidx.appcompat.app.AppCompatViewInflater
|
||||||
|
# aapt is not able to read app::actionViewClass and app:actionProviderClass to produce proguard
|
||||||
|
# keep rules. Add a commonly used SearchView to the keep list until b/109831488 is resolved.
|
||||||
|
-keep class androidx.appcompat.widget.SearchView { <init>(...); }
|
||||||
|
|
||||||
|
# CoordinatorLayout resolves the behaviors of its child components with reflection.
|
||||||
|
-keep public class * extends androidx.coordinatorlayout.widget.CoordinatorLayout$Behavior {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
public <init>();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make sure we keep annotations for CoordinatorLayout's DefaultBehavior
|
||||||
|
-keepattributes RuntimeVisible*Annotation*
|
||||||
|
|
||||||
|
|
||||||
|
# Keep `Companion` object fields of serializable classes.
|
||||||
|
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
|
||||||
|
-if @kotlinx.serialization.Serializable class **
|
||||||
|
-keepclassmembers class <1> {
|
||||||
|
static <1>$Companion Companion;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep `serializer()` on companion objects (both default and named) of serializable classes.
|
||||||
|
-if @kotlinx.serialization.Serializable class ** {
|
||||||
|
static **$* *;
|
||||||
|
}
|
||||||
|
-keepclassmembers class <2>$<3> {
|
||||||
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep `INSTANCE.serializer()` of serializable objects.
|
||||||
|
-if @kotlinx.serialization.Serializable class ** {
|
||||||
|
public static ** INSTANCE;
|
||||||
|
}
|
||||||
|
-keepclassmembers class <1> {
|
||||||
|
public static <1> INSTANCE;
|
||||||
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
|
||||||
|
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
|
||||||
|
|
||||||
|
# Don't print notes about potential mistakes or omissions in the configuration for kotlinx-serialization classes
|
||||||
|
# See also https://github.com/Kotlin/kotlinx.serialization/issues/1900
|
||||||
|
-dontnote kotlinx.serialization.**
|
||||||
|
|
||||||
|
# Serialization core uses `java.lang.ClassValue` for caching inside these specified classes.
|
||||||
|
# If there is no `java.lang.ClassValue` (for example, in Android), then R8/ProGuard will print a warning.
|
||||||
|
# However, since in this case they will not be used, we can disable these warnings
|
||||||
|
-dontwarn kotlinx.serialization.internal.ClassValueReferences
|
||||||
|
|
||||||
|
# Rule to save runtime annotations on serializable class.
|
||||||
|
# If the R8 full mode is used, annotations are removed from classes-files.
|
||||||
|
#
|
||||||
|
# For the annotation serializer, it is necessary to read the `Serializable` annotation inside the serializer<T>() function - if it is present,
|
||||||
|
# then `SealedClassSerializer` is used, if absent, then `PolymorphicSerializer'.
|
||||||
|
#
|
||||||
|
# When using R8 full mode, all interfaces will be serialized using `PolymorphicSerializer`.
|
||||||
|
#
|
||||||
|
# see https://github.com/Kotlin/kotlinx.serialization/issues/2050
|
||||||
|
|
||||||
|
-if @kotlinx.serialization.Serializable class **
|
||||||
|
-keep, allowshrinking, allowoptimization, allowobfuscation class <1>
|
||||||
|
|
||||||
|
# Entry point for retaining MainDispatcherLoader which uses a ServiceLoader.
|
||||||
|
-keep class kotlinx.coroutines.Dispatchers {
|
||||||
|
** getMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Entry point for retaining CoroutineExceptionHandlerImpl.handlers which uses a ServiceLoader.
|
||||||
|
-keep class kotlinx.coroutines.CoroutineExceptionHandlerKt {
|
||||||
|
void handleCoroutineException(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Entry point for the rest of coroutines machinery
|
||||||
|
-keep class kotlinx.coroutines.BuildersKt {
|
||||||
|
** runBlocking(...);
|
||||||
|
** launch(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# We are cheating a bit by not having android.jar on R8's library classpath. Ignore those warnings.
|
||||||
|
-ignorewarnings
|
||||||
|
|
||||||
|
-keep class kotlinx.coroutines.android.AndroidDispatcherFactory {*;}
|
||||||
|
-keep class kotlinx.coroutines.android.AndroidExceptionPreHandler {*;}
|
||||||
|
|
||||||
|
# Statically turn off all debugging facilities and assertions
|
||||||
|
-keepclassmembers class io.ktor.** { volatile <fields>; }
|
||||||
|
-keep class io.ktor.** { *; }
|
||||||
|
-keep class kotlinx.coroutines.** { *; }
|
||||||
|
-dontwarn kotlinx.atomicfu.**
|
||||||
|
-dontwarn io.netty.**
|
||||||
|
-dontwarn com.typesafe.**
|
||||||
|
-assumenosideeffects class * implements org.slf4j.Logger {
|
||||||
|
public *** trace(...);
|
||||||
|
public *** debug(...);
|
||||||
|
public *** info(...);
|
||||||
|
public *** warn(...);
|
||||||
|
public *** error(...);
|
||||||
|
}
|
||||||
|
-keep class kotlin.reflect.jvm.internal.** { *; }
|
||||||
|
|
||||||
|
-keep class com.arthenica.ffmpegkit.FFmpegKitConfig {
|
||||||
|
native <methods>;
|
||||||
|
void log(long, int, byte[]);
|
||||||
|
void statistics(long, int, float, float, long , int, double, double);
|
||||||
|
int safOpen(int);
|
||||||
|
int safClose(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class com.arthenica.ffmpegkit.AbiDetect {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-dontwarn android.view.RenderNode
|
||||||
|
-dontwarn android.view.DisplayListCanvas
|
||||||
|
|
||||||
|
-keepclassmembers class androidx.compose.ui.platform.ViewLayerContainer {
|
||||||
|
protected void dispatchGetDisplayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class androidx.compose.ui.platform.AndroidComposeView {
|
||||||
|
android.view.View findViewByAccessibilityIdTraversal(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Users can create Modifier.Node instances that implement multiple Modifier.Node interfaces,
|
||||||
|
# so we cannot tell whether two modifier.node instances are of the same type without using
|
||||||
|
# reflection to determine the class type. See b/265188224 for more context.
|
||||||
|
-keep,allowshrinking class * extends androidx.compose.ui.node.ModifierNodeElement
|
||||||
|
-keep class org.jetbrains.skia.** { *; }
|
||||||
|
-keep class org.jetbrains.skiko.** { *; }
|
||||||
|
|
||||||
|
-assumenosideeffects public class androidx.compose.runtime.ComposerKt {
|
||||||
|
void sourceInformation(androidx.compose.runtime.Composer,java.lang.String);
|
||||||
|
void sourceInformationMarkerStart(androidx.compose.runtime.Composer,int,java.lang.String);
|
||||||
|
void sourceInformationMarkerEnd(androidx.compose.runtime.Composer);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class com.arthenica.ffmpegkit.NativeLoader { *; }
|
||||||
|
|
||||||
|
-keep class moe.fuqiuluo.** { *; }
|
||||||
|
-keep class com.tencent.** { *; }
|
||||||
|
-keep class com.qq.** { *; }
|
||||||
|
-keep class com.google.gson.** { *; }
|
||||||
|
-keep class de.** { *; }
|
||||||
|
-keep class mqq.** { *; }
|
||||||
|
-keep class QQService.** { *; }
|
||||||
|
-keep class SummaryCard.** { *; }
|
||||||
|
-keep class tencent.** { *; }
|
||||||
|
|
||||||
|
-keepclassmembers class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
-keep class io.netty.** { *; }
|
@ -0,0 +1,24 @@
|
|||||||
|
package moe.fuqiuluo.shamrock
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
assertEquals("moe.fuqiuluo.shamrock", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
65
app/src/main/AndroidManifest.xml
Normal file
65
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".app.MyApplication"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.Shamrock"
|
||||||
|
android:zygotePreloadName="@string/app_name"
|
||||||
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/Theme.Shamrock"
|
||||||
|
tools:ignore="RedundantLabel">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name=".ui.service.internal.MultifunctionalProvider"
|
||||||
|
android:authorities="moe.fuqiuluo.xqbot.provider"
|
||||||
|
android:exported="true"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
tools:ignore="ExportedContentProvider" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="xposedmodule"
|
||||||
|
android:value="true" />
|
||||||
|
<meta-data
|
||||||
|
android:name="xposeddescription"
|
||||||
|
android:value="基于 Xposed 实现 OneBot 标准的 QQ 机器人框架" />
|
||||||
|
<meta-data
|
||||||
|
android:name="xposedminversion"
|
||||||
|
android:value="23" />
|
||||||
|
<meta-data
|
||||||
|
android:name="xposedscope"
|
||||||
|
android:resource="@array/xposed_scope" />
|
||||||
|
|
||||||
|
<!--适配华为(huawei)刘海屏-->
|
||||||
|
<meta-data
|
||||||
|
android:name="android.notch_support"
|
||||||
|
android:value="true" />
|
||||||
|
<!--适配小米(xiaomi)刘海屏-->
|
||||||
|
<meta-data
|
||||||
|
android:name="notch.config"
|
||||||
|
android:value="portrait|landscape" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
52
app/src/main/cpp/CMakeLists.txt
Normal file
52
app/src/main/cpp/CMakeLists.txt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
# For more information about using CMake with Android Studio, read the
|
||||||
|
# documentation: https://d.android.com/studio/projects/add-native-code.html.
|
||||||
|
# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
|
||||||
|
|
||||||
|
# Sets the minimum CMake version required for this project.
|
||||||
|
cmake_minimum_required(VERSION 3.22.1)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
|
||||||
|
# Since this is the top level CMakeLists.txt, the project name is also accessible
|
||||||
|
# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
|
||||||
|
# build script scope).
|
||||||
|
project("shamrock")
|
||||||
|
|
||||||
|
# Creates and names a library, sets it as either STATIC
|
||||||
|
# or SHARED, and provides the relative paths to its source code.
|
||||||
|
# You can define multiple libraries, and CMake builds them for you.
|
||||||
|
# Gradle automatically packages shared libraries with your APK.
|
||||||
|
#
|
||||||
|
# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define
|
||||||
|
# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME}
|
||||||
|
# is preferred for the same purpose.
|
||||||
|
#
|
||||||
|
# In order to load a library into your app from Java/Kotlin, you must call
|
||||||
|
# System.loadLibrary() and pass the name of the library defined here;
|
||||||
|
# for GameActivity/NativeActivity derived applications, the same library name must be
|
||||||
|
# used in the AndroidManifest.xml file.
|
||||||
|
include_directories(interface)
|
||||||
|
include_directories(src)
|
||||||
|
|
||||||
|
AUX_SOURCE_DIRECTORY(src SRC_DIR)
|
||||||
|
|
||||||
|
add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||||
|
# List C/C++ source files with relative paths to this CMakeLists.txt.
|
||||||
|
${SRC_DIR}
|
||||||
|
md5.cpp
|
||||||
|
cqcode.cpp
|
||||||
|
silk.cpp
|
||||||
|
group_honor.cpp
|
||||||
|
message.cpp
|
||||||
|
shamrock.cpp)
|
||||||
|
|
||||||
|
# Specifies libraries CMake should link to your target library. You
|
||||||
|
# can link libraries from various origins, such as libraries defined in this
|
||||||
|
# build script, prebuilt third-party libraries, or Android system libraries.
|
||||||
|
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
|
# List libraries link to the target library
|
||||||
|
android
|
||||||
|
log)
|
123
app/src/main/cpp/cqcode.cpp
Normal file
123
app/src/main/cpp/cqcode.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#include <stdexcept>
|
||||||
|
#include "cqcode.h"
|
||||||
|
|
||||||
|
inline void replace_string(std::string& str, const std::string& from, const std::string& to) {
|
||||||
|
size_t startPos = 0;
|
||||||
|
while ((startPos = str.find(from, startPos)) != std::string::npos) {
|
||||||
|
str.replace(startPos, from.length(), to);
|
||||||
|
startPos += to.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode_cqcode(const std::string& code, std::vector<std::unordered_map<std::string, std::string>>& dest) {
|
||||||
|
std::string cache;
|
||||||
|
bool is_start = false;
|
||||||
|
std::string key_tmp;
|
||||||
|
std::unordered_map<std::string, std::string> kv;
|
||||||
|
for(int i = 0; i < code.size(); i++) {
|
||||||
|
auto c = code[i];
|
||||||
|
if (c == '[') {
|
||||||
|
if (is_start) {
|
||||||
|
throw illegal_code();
|
||||||
|
} else {
|
||||||
|
if (!cache.empty()) {
|
||||||
|
std::unordered_map<std::string, std::string> kv;
|
||||||
|
kv.emplace("_type", "text");
|
||||||
|
kv.emplace("text", cache);
|
||||||
|
dest.push_back(kv);
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
auto c1 = code[i + 1];
|
||||||
|
if (c1 == 'C') {
|
||||||
|
i++;
|
||||||
|
auto c2 = code[i + 1];
|
||||||
|
if(c2 == 'Q') {
|
||||||
|
i++;
|
||||||
|
auto c3 = code[i + 1];
|
||||||
|
if (c3 == ':') {
|
||||||
|
i++;
|
||||||
|
is_start = true;
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
cache += c1;
|
||||||
|
cache += c2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
cache += c1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == '=') {
|
||||||
|
if (is_start) {
|
||||||
|
if (cache.empty()) {
|
||||||
|
throw illegal_code();
|
||||||
|
} else {
|
||||||
|
if (key_tmp.empty()) {
|
||||||
|
key_tmp.append(cache);
|
||||||
|
cache.clear();
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == ',') {
|
||||||
|
if (is_start) {
|
||||||
|
if (kv.count("_type") == 0 && !cache.empty()) {
|
||||||
|
kv.emplace("_type", cache);
|
||||||
|
cache.clear();
|
||||||
|
} else {
|
||||||
|
if (!key_tmp.empty()) {
|
||||||
|
replace_string(cache, "&", "&");
|
||||||
|
replace_string(cache, "[", "[");
|
||||||
|
replace_string(cache, "]", "]");
|
||||||
|
replace_string(cache, ",", ",");
|
||||||
|
kv.emplace(key_tmp, cache);
|
||||||
|
cache.clear();
|
||||||
|
key_tmp.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == ']') {
|
||||||
|
if (is_start) {
|
||||||
|
if (!cache.empty()) {
|
||||||
|
if (!key_tmp.empty()) {
|
||||||
|
replace_string(cache, "&", "&");
|
||||||
|
replace_string(cache, "[", "[");
|
||||||
|
replace_string(cache, "]", "]");
|
||||||
|
replace_string(cache, ",", ",");
|
||||||
|
kv.emplace(key_tmp, cache);
|
||||||
|
}
|
||||||
|
dest.push_back(kv);
|
||||||
|
kv.clear();
|
||||||
|
key_tmp.clear();
|
||||||
|
cache.clear();
|
||||||
|
is_start = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cache += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cache += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!cache.empty()) {
|
||||||
|
std::unordered_map<std::string, std::string> kv;
|
||||||
|
kv.emplace("_type", "text");
|
||||||
|
kv.emplace("text", cache);
|
||||||
|
dest.push_back(kv);
|
||||||
|
}
|
||||||
|
}
|
87
app/src/main/cpp/group_honor.cpp
Normal file
87
app/src/main/cpp/group_honor.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "jni.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
struct Honor {
|
||||||
|
int id;
|
||||||
|
std::string name;
|
||||||
|
std::string icon_url;
|
||||||
|
int priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
int calc_honor_flag(int honor_id, char honor_flag);
|
||||||
|
|
||||||
|
jobject make_honor_object(JNIEnv *env, jobject user_id, const Honor& honor);
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_remote_action_handlers_GetTroopHonor_nativeDecodeHonor(JNIEnv *env, jobject thiz,
|
||||||
|
jstring user_id,
|
||||||
|
jint honor_id,
|
||||||
|
jbyte honor_flag) {
|
||||||
|
static std::vector<Honor> honor_list = {
|
||||||
|
Honor{1, "龙王", "https://qzonestyle.gtimg.cn/aoi/sola/20200213150116_n4PxCiurbm.png", 1},
|
||||||
|
Honor{2, "群聊之火", "https://qzonestyle.gtimg.cn/aoi/sola/20200217190136_92JEGFKC5k.png", 3},
|
||||||
|
Honor{3, "群聊炽焰", "https://qzonestyle.gtimg.cn/aoi/sola/20200217190204_zgCTeSrMq1.png", 4},
|
||||||
|
Honor{5, "冒尖小春笋", "https://qzonestyle.gtimg.cn/aoi/sola/20200213150335_tUJCAtoKVP.png", 5},
|
||||||
|
Honor{6, "快乐源泉", "https://qzonestyle.gtimg.cn/aoi/sola/20200213150434_3tDmsJExCP.png", 7},
|
||||||
|
Honor{7, "学术新星", "https://sola.gtimg.cn/aoi/sola/20200515140645_j0X6gbuHNP.png", 8},
|
||||||
|
Honor{8, "顶尖学霸", "https://sola.gtimg.cn/aoi/sola/20200515140639_0CtWOpfVzK.png", 9},
|
||||||
|
Honor{9, "至尊学神", "https://sola.gtimg.cn/aoi/sola/20200515140628_P8UEYBjMBT.png", 10},
|
||||||
|
Honor{10, "一笔当先", "https://sola.gtimg.cn/aoi/sola/20200515140654_4r94tSCdaB.png", 11},
|
||||||
|
Honor{11, "奋进小翠竹", "https://sola.gtimg.cn/aoi/sola/20200812151819_wbj6z2NGoB.png", 6},
|
||||||
|
Honor{12, "氛围魔杖", "https://sola.gtimg.cn/aoi/sola/20200812151831_4ZJgQCaD1H.png", 2},
|
||||||
|
Honor{13, "壕礼皇冠", "https://sola.gtimg.cn/aoi/sola/20200930154050_juZOAMg7pt.png", 12},
|
||||||
|
};
|
||||||
|
int flag = calc_honor_flag(honor_id, honor_flag);
|
||||||
|
if ((honor_id != 1 && honor_id != 2 && honor_id != 3) || flag != 1) {
|
||||||
|
auto honor = *std::find_if(honor_list.begin(), honor_list.end(), [&honor_id](auto &honor) {
|
||||||
|
return honor.id == honor_id;
|
||||||
|
});
|
||||||
|
return make_honor_object(env, user_id, honor);
|
||||||
|
} else {
|
||||||
|
auto honor = *std::find_if(honor_list.begin(), honor_list.end(), [&honor_id](auto &honor) {
|
||||||
|
return honor.id == honor_id;
|
||||||
|
});
|
||||||
|
std::string url = "https://static-res.qq.com/static-res/groupInteract/vas/a/" + std::to_string(honor_id) + "_1.png";
|
||||||
|
honor = Honor{honor_id, honor.name, url, honor.priority};
|
||||||
|
return make_honor_object(env, user_id, honor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int calc_honor_flag(int honor_id, char honor_flag) {
|
||||||
|
int flag;
|
||||||
|
if (honor_flag == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (honor_id == 1) {
|
||||||
|
flag = honor_flag;
|
||||||
|
} else if (honor_id == 2 || honor_id == 3) {
|
||||||
|
flag = honor_flag >> 2;
|
||||||
|
} else if (honor_id != 4) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
flag = honor_flag >> 4;
|
||||||
|
}
|
||||||
|
return flag & 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject make_honor_object(JNIEnv *env, jobject user_id, const Honor& honor) {
|
||||||
|
jclass GroupMemberHonor = env->FindClass("moe/fuqiuluo/shamrock/remote/service/data/GroupMemberHonor");
|
||||||
|
jmethodID GroupMemberHonor_init = env->GetMethodID(GroupMemberHonor, "<init>",
|
||||||
|
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
|
||||||
|
auto user_id_str = (jstring) user_id;
|
||||||
|
jstring honor_desc = env->NewStringUTF(honor.name.c_str());
|
||||||
|
jstring uin_name = env->NewStringUTF("");
|
||||||
|
jstring honor_icon_url = env->NewStringUTF(honor.icon_url.c_str());
|
||||||
|
jobject ret = env->NewObject(GroupMemberHonor, GroupMemberHonor_init, user_id_str, uin_name, honor_icon_url, 0, honor.id, honor_desc);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(GroupMemberHonor);
|
||||||
|
env->DeleteLocalRef(user_id_str);
|
||||||
|
env->DeleteLocalRef(honor_desc);
|
||||||
|
env->DeleteLocalRef(honor_icon_url);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
152
app/src/main/cpp/interface/SKP_Silk_SDK_API.h
Normal file
152
app/src/main/cpp/interface/SKP_Silk_SDK_API.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SKP_SILK_SDK_API_H
|
||||||
|
#define SKP_SILK_SDK_API_H
|
||||||
|
|
||||||
|
#include "SKP_Silk_control.h"
|
||||||
|
#include "SKP_Silk_typedef.h"
|
||||||
|
#include "SKP_Silk_errors.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SILK_MAX_FRAMES_PER_PACKET 5
|
||||||
|
|
||||||
|
/* Struct for TOC (Table of Contents) */
|
||||||
|
typedef struct {
|
||||||
|
SKP_int framesInPacket; /* Number of 20 ms frames in packet */
|
||||||
|
SKP_int fs_kHz; /* Sampling frequency in packet */
|
||||||
|
SKP_int inbandLBRR; /* Does packet contain LBRR information */
|
||||||
|
SKP_int corrupt; /* Packet is corrupt */
|
||||||
|
SKP_int vadFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet */
|
||||||
|
SKP_int sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */
|
||||||
|
} SKP_Silk_TOC_struct;
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Encoder functions */
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/* Get size in bytes of the Silk encoder state */
|
||||||
|
/***********************************************/
|
||||||
|
SKP_int SKP_Silk_SDK_Get_Encoder_Size(
|
||||||
|
SKP_int32 *encSizeBytes /* O: Number of bytes in SILK encoder state */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*************************/
|
||||||
|
/* Init or reset encoder */
|
||||||
|
/*************************/
|
||||||
|
SKP_int SKP_Silk_SDK_InitEncoder(
|
||||||
|
void *encState, /* I/O: State */
|
||||||
|
SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************/
|
||||||
|
/* Read control structure from encoder */
|
||||||
|
/***************************************/
|
||||||
|
SKP_int SKP_Silk_SDK_QueryEncoder(
|
||||||
|
const void *encState, /* I: State */
|
||||||
|
SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Encode frame with Silk */
|
||||||
|
/**************************/
|
||||||
|
SKP_int SKP_Silk_SDK_Encode(
|
||||||
|
void *encState, /* I/O: State */
|
||||||
|
const SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control status */
|
||||||
|
const SKP_int16 *samplesIn, /* I: Speech sample input vector */
|
||||||
|
SKP_int nSamplesIn, /* I: Number of samples in input vector */
|
||||||
|
SKP_uint8 *outData, /* O: Encoded output vector */
|
||||||
|
SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
|
||||||
|
);
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Decoder functions */
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/* Get size in bytes of the Silk decoder state */
|
||||||
|
/***********************************************/
|
||||||
|
SKP_int SKP_Silk_SDK_Get_Decoder_Size(
|
||||||
|
SKP_int32 *decSizeBytes /* O: Number of bytes in SILK decoder state */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*************************/
|
||||||
|
/* Init or Reset decoder */
|
||||||
|
/*************************/
|
||||||
|
SKP_int SKP_Silk_SDK_InitDecoder(
|
||||||
|
void *decState /* I/O: State */
|
||||||
|
);
|
||||||
|
|
||||||
|
/******************/
|
||||||
|
/* Decode a frame */
|
||||||
|
/******************/
|
||||||
|
SKP_int SKP_Silk_SDK_Decode(
|
||||||
|
void* decState, /* I/O: State */
|
||||||
|
SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control Structure */
|
||||||
|
SKP_int lostFlag, /* I: 0: no loss, 1 loss */
|
||||||
|
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||||
|
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||||
|
SKP_int16 *samplesOut, /* O: Decoded output speech vector */
|
||||||
|
SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************/
|
||||||
|
/* Find Low Bit Rate Redundancy (LBRR) information in a packet */
|
||||||
|
/***************************************************************/
|
||||||
|
void SKP_Silk_SDK_search_for_LBRR(
|
||||||
|
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||||
|
const SKP_int nBytesIn, /* I: Number of input Bytes */
|
||||||
|
SKP_int lost_offset, /* I: Offset from lost packet */
|
||||||
|
SKP_uint8 *LBRRData, /* O: LBRR payload */
|
||||||
|
SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**************************************/
|
||||||
|
/* Get table of contents for a packet */
|
||||||
|
/**************************************/
|
||||||
|
void SKP_Silk_SDK_get_TOC(
|
||||||
|
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||||
|
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||||
|
SKP_Silk_TOC_struct *Silk_TOC /* O: Table of contents */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Get the version number */
|
||||||
|
/**************************/
|
||||||
|
/* Return a pointer to string specifying the version */
|
||||||
|
const char *SKP_Silk_SDK_get_version(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
91
app/src/main/cpp/interface/SKP_Silk_control.h
Normal file
91
app/src/main/cpp/interface/SKP_Silk_control.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SKP_SILK_CONTROL_H
|
||||||
|
#define SKP_SILK_CONTROL_H
|
||||||
|
|
||||||
|
#include "SKP_Silk_typedef.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/* Structure for controlling encoder operation */
|
||||||
|
/***********************************************/
|
||||||
|
typedef struct {
|
||||||
|
/* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||||
|
SKP_int32 API_sampleRate;
|
||||||
|
|
||||||
|
/* I: Maximum internal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||||
|
SKP_int32 maxInternalSampleRate;
|
||||||
|
|
||||||
|
/* I: Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms */
|
||||||
|
SKP_int packetSize;
|
||||||
|
|
||||||
|
/* I: Bitrate during active speech in bits/second; internally limited */
|
||||||
|
SKP_int32 bitRate;
|
||||||
|
|
||||||
|
/* I: Uplink packet loss in percent (0-100) */
|
||||||
|
SKP_int packetLossPercentage;
|
||||||
|
|
||||||
|
/* I: Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity */
|
||||||
|
SKP_int complexity;
|
||||||
|
|
||||||
|
/* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
|
||||||
|
SKP_int useInBandFEC;
|
||||||
|
|
||||||
|
/* I: Flag to enable discontinuous transmission (DTX); 0/1 */
|
||||||
|
SKP_int useDTX;
|
||||||
|
} SKP_SILK_SDK_EncControlStruct;
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Structure for controlling decoder operation and reading decoder status */
|
||||||
|
/**************************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
/* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||||
|
SKP_int32 API_sampleRate;
|
||||||
|
|
||||||
|
/* O: Number of samples per frame */
|
||||||
|
SKP_int frameSize;
|
||||||
|
|
||||||
|
/* O: Frames per packet 1, 2, 3, 4, 5 */
|
||||||
|
SKP_int framesPerPacket;
|
||||||
|
|
||||||
|
/* O: Flag to indicate that the decoder has remaining payloads internally */
|
||||||
|
SKP_int moreInternalDecoderFrames;
|
||||||
|
|
||||||
|
/* O: Distance between main payload and redundant payload in packets */
|
||||||
|
SKP_int inBandFECOffset;
|
||||||
|
} SKP_SILK_SDK_DecControlStruct;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
89
app/src/main/cpp/interface/SKP_Silk_errors.h
Normal file
89
app/src/main/cpp/interface/SKP_Silk_errors.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SKP_SILK_ERRORS_H
|
||||||
|
#define SKP_SILK_ERRORS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************/
|
||||||
|
/* Error messages */
|
||||||
|
/******************/
|
||||||
|
#define SKP_SILK_NO_ERROR 0
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Encoder error messages */
|
||||||
|
/**************************/
|
||||||
|
|
||||||
|
/* Input length is not a multiplum of 10 ms, or length is longer than the packet length */
|
||||||
|
#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1
|
||||||
|
|
||||||
|
/* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */
|
||||||
|
#define SKP_SILK_ENC_FS_NOT_SUPPORTED -2
|
||||||
|
|
||||||
|
/* Packet size not 20, 40, 60, 80 or 100 ms */
|
||||||
|
#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3
|
||||||
|
|
||||||
|
/* Allocated payload buffer too short */
|
||||||
|
#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4
|
||||||
|
|
||||||
|
/* Loss rate not between 0 and 100 percent */
|
||||||
|
#define SKP_SILK_ENC_INVALID_LOSS_RATE -5
|
||||||
|
|
||||||
|
/* Complexity setting not valid, use 0, 1 or 2 */
|
||||||
|
#define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING -6
|
||||||
|
|
||||||
|
/* Inband FEC setting not valid, use 0 or 1 */
|
||||||
|
#define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING -7
|
||||||
|
|
||||||
|
/* DTX setting not valid, use 0 or 1 */
|
||||||
|
#define SKP_SILK_ENC_INVALID_DTX_SETTING -8
|
||||||
|
|
||||||
|
/* Internal encoder error */
|
||||||
|
#define SKP_SILK_ENC_INTERNAL_ERROR -9
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Decoder error messages */
|
||||||
|
/**************************/
|
||||||
|
|
||||||
|
/* Output sampling frequency lower than internal decoded sampling frequency */
|
||||||
|
#define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY -10
|
||||||
|
|
||||||
|
/* Payload size exceeded the maximum allowed 1024 bytes */
|
||||||
|
#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE -11
|
||||||
|
|
||||||
|
/* Payload has bit errors */
|
||||||
|
#define SKP_SILK_DEC_PAYLOAD_ERROR -12
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
107
app/src/main/cpp/interface/SKP_Silk_typedef.h
Normal file
107
app/src/main/cpp/interface/SKP_Silk_typedef.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef _SKP_SILK_API_TYPDEF_H_
|
||||||
|
#define _SKP_SILK_API_TYPDEF_H_
|
||||||
|
|
||||||
|
#ifndef SKP_USE_DOUBLE_PRECISION_FLOATS
|
||||||
|
#define SKP_USE_DOUBLE_PRECISION_FLOATS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#if defined( __GNUC__ )
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SKP_int int /* used for counters etc; at least 16 bits */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define SKP_int64 int64_t
|
||||||
|
#else
|
||||||
|
# define SKP_int64 long long
|
||||||
|
#endif
|
||||||
|
#define SKP_int32 int
|
||||||
|
#define SKP_int16 short
|
||||||
|
#define SKP_int8 signed char
|
||||||
|
|
||||||
|
#define SKP_uint unsigned int /* used for counters etc; at least 16 bits */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define SKP_uint64 uint64_t
|
||||||
|
#else
|
||||||
|
# define SKP_uint64 unsigned long long
|
||||||
|
#endif
|
||||||
|
#define SKP_uint32 unsigned int
|
||||||
|
#define SKP_uint16 unsigned short
|
||||||
|
#define SKP_uint8 unsigned char
|
||||||
|
|
||||||
|
#define SKP_int_ptr_size intptr_t
|
||||||
|
|
||||||
|
#if SKP_USE_DOUBLE_PRECISION_FLOATS
|
||||||
|
# define SKP_float double
|
||||||
|
# define SKP_float_MAX DBL_MAX
|
||||||
|
#else
|
||||||
|
# define SKP_float float
|
||||||
|
# define SKP_float_MAX FLT_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SKP_INLINE static __inline
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
|
||||||
|
#else
|
||||||
|
# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SKP_int64_MAX ((SKP_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */
|
||||||
|
#define SKP_int64_MIN ((SKP_int64)0x8000000000000000LL) /* -2^63 */
|
||||||
|
#define SKP_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647*/
|
||||||
|
#define SKP_int32_MIN ((SKP_int32)0x80000000) /* -2^31 = -2147483648*/
|
||||||
|
#define SKP_int16_MAX 0x7FFF /* 2^15 - 1 = 32767*/
|
||||||
|
#define SKP_int16_MIN ((SKP_int16)0x8000) /* -2^15 = -32768*/
|
||||||
|
#define SKP_int8_MAX 0x7F /* 2^7 - 1 = 127*/
|
||||||
|
#define SKP_int8_MIN ((SKP_int8)0x80) /* -2^7 = -128*/
|
||||||
|
|
||||||
|
#define SKP_uint32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4294967295 */
|
||||||
|
#define SKP_uint32_MIN 0x00000000
|
||||||
|
#define SKP_uint16_MAX 0xFFFF /* 2^16 - 1 = 65535 */
|
||||||
|
#define SKP_uint16_MIN 0x0000
|
||||||
|
#define SKP_uint8_MAX 0xFF /* 2^8 - 1 = 255 */
|
||||||
|
#define SKP_uint8_MIN 0x00
|
||||||
|
|
||||||
|
#define SKP_TRUE 1
|
||||||
|
#define SKP_FALSE 0
|
||||||
|
|
||||||
|
/* assertions */
|
||||||
|
#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))
|
||||||
|
# ifndef SKP_assert
|
||||||
|
# include <crtdbg.h> /* ASSERTE() */
|
||||||
|
# define SKP_assert(COND) _ASSERTE(COND)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define SKP_assert(COND)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
20
app/src/main/cpp/interface/cqcode.h
Normal file
20
app/src/main/cpp/interface/cqcode.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef UNTITLED_CQCODE_H
|
||||||
|
#define UNTITLED_CQCODE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
class illegal_code: std::exception {
|
||||||
|
public:
|
||||||
|
[[nodiscard]] const char * what() const noexcept override {
|
||||||
|
return "Error cq code.";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void decode_cqcode(const std::string& code, std::vector<std::unordered_map<std::string, std::string>>& dest);
|
||||||
|
|
||||||
|
void encode_cqcode(const std::vector<std::unordered_map<std::string, std::string>>& segment, std::string& dest);
|
||||||
|
|
||||||
|
#endif //UNTITLED_CQCODE_H
|
52
app/src/main/cpp/interface/md5.h
Normal file
52
app/src/main/cpp/interface/md5.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef MD5_H
|
||||||
|
#define MD5_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
/* Type define */
|
||||||
|
using byte = std::byte;
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::ifstream;
|
||||||
|
|
||||||
|
/* MD5 declaration. */
|
||||||
|
class MD5 {
|
||||||
|
public:
|
||||||
|
MD5();
|
||||||
|
MD5(const void* input, size_t length);
|
||||||
|
MD5(const string& str);
|
||||||
|
MD5(ifstream& in);
|
||||||
|
void update(const void* input, size_t length);
|
||||||
|
void update(const string& str);
|
||||||
|
void update(ifstream& in);
|
||||||
|
const byte* digest();
|
||||||
|
string toString();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update(const byte* input, size_t length);
|
||||||
|
void final();
|
||||||
|
void transform(const byte block[64]);
|
||||||
|
void encode(const uint32* input, byte* output, size_t length);
|
||||||
|
void decode(const byte* input, uint32* output, size_t length);
|
||||||
|
string bytesToHexString(const byte* input, size_t length);
|
||||||
|
|
||||||
|
/* class uncopyable */
|
||||||
|
MD5(const MD5&);
|
||||||
|
MD5& operator=(const MD5&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 _state[4]; /* state (ABCD) */
|
||||||
|
uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */
|
||||||
|
byte _buffer[64]; /* input buffer */
|
||||||
|
byte _digest[16]; /* message digest */
|
||||||
|
bool _finished; /* calculate finished ? */
|
||||||
|
|
||||||
|
static const byte PADDING[64]; /* padding for calculate */
|
||||||
|
static const char HEX[16];
|
||||||
|
enum { BUFFER_SIZE = 1024 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*MD5_H*/
|
344
app/src/main/cpp/md5.cpp
Normal file
344
app/src/main/cpp/md5.cpp
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/* Constants for MD5Transform routine. */
|
||||||
|
#define S11 7
|
||||||
|
#define S12 12
|
||||||
|
#define S13 17
|
||||||
|
#define S14 22
|
||||||
|
#define S21 5
|
||||||
|
#define S22 9
|
||||||
|
#define S23 14
|
||||||
|
#define S24 20
|
||||||
|
#define S31 4
|
||||||
|
#define S32 11
|
||||||
|
#define S33 16
|
||||||
|
#define S34 23
|
||||||
|
#define S41 6
|
||||||
|
#define S42 10
|
||||||
|
#define S43 15
|
||||||
|
#define S44 21
|
||||||
|
|
||||||
|
|
||||||
|
/* F, G, H and I are basic MD5 functions.
|
||||||
|
*/
|
||||||
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||||
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||||
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||||
|
|
||||||
|
/* ROTATE_LEFT rotates x left n bits.
|
||||||
|
*/
|
||||||
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||||
|
Rotation is separate from addition to prevent recomputation.
|
||||||
|
*/
|
||||||
|
#define FF(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += F ((b), (c), (d)) + (x) + ac; \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define GG(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += G ((b), (c), (d)) + (x) + ac; \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define HH(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += H ((b), (c), (d)) + (x) + ac; \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define II(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += I ((b), (c), (d)) + (x) + ac; \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::byte MD5::PADDING[64] = { (byte) 0x80 };
|
||||||
|
const char MD5::HEX[16] = {
|
||||||
|
'0', '1', '2', '3',
|
||||||
|
'4', '5', '6', '7',
|
||||||
|
'8', '9', 'a', 'b',
|
||||||
|
'c', 'd', 'e', 'f'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Default construct. */
|
||||||
|
MD5::MD5() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Construct a MD5 object with a input buffer. */
|
||||||
|
MD5::MD5(const void* input, size_t length) {
|
||||||
|
reset();
|
||||||
|
update(input, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Construct a MD5 object with a string. */
|
||||||
|
MD5::MD5(const string& str) {
|
||||||
|
reset();
|
||||||
|
update(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Construct a MD5 object with a file. */
|
||||||
|
MD5::MD5(ifstream& in) {
|
||||||
|
reset();
|
||||||
|
update(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the message-digest */
|
||||||
|
const byte* MD5::digest() {
|
||||||
|
|
||||||
|
if (!_finished) {
|
||||||
|
_finished = true;
|
||||||
|
final();
|
||||||
|
}
|
||||||
|
return _digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the calculate state */
|
||||||
|
void MD5::reset() {
|
||||||
|
|
||||||
|
_finished = false;
|
||||||
|
/* reset number of bits. */
|
||||||
|
_count[0] = _count[1] = 0;
|
||||||
|
/* Load magic initialization constants. */
|
||||||
|
_state[0] = 0x67452301;
|
||||||
|
_state[1] = 0xefcdab89;
|
||||||
|
_state[2] = 0x98badcfe;
|
||||||
|
_state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Updating the context with a input buffer. */
|
||||||
|
void MD5::update(const void* input, size_t length) {
|
||||||
|
update((const byte*)input, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Updating the context with a string. */
|
||||||
|
void MD5::update(const string& str) {
|
||||||
|
update((const byte*)str.c_str(), str.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Updating the context with a file. */
|
||||||
|
void MD5::update(ifstream& in) {
|
||||||
|
|
||||||
|
if (!in) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::streamsize length;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
while (!in.eof()) {
|
||||||
|
in.read(buffer, BUFFER_SIZE);
|
||||||
|
length = in.gcount();
|
||||||
|
if (length > 0) {
|
||||||
|
update(buffer, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 block update operation. Continues an MD5 message-digest
|
||||||
|
operation, processing another message block, and updating the
|
||||||
|
context.
|
||||||
|
*/
|
||||||
|
void MD5::update(const byte* input, size_t length) {
|
||||||
|
|
||||||
|
uint32 i, index, partLen;
|
||||||
|
|
||||||
|
_finished = false;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
index = (uint32)((_count[0] >> 3) & 0x3f);
|
||||||
|
|
||||||
|
/* update number of bits */
|
||||||
|
if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) {
|
||||||
|
++_count[1];
|
||||||
|
}
|
||||||
|
_count[1] += ((uint32)length >> 29);
|
||||||
|
|
||||||
|
partLen = 64 - index;
|
||||||
|
|
||||||
|
/* transform as many times as possible. */
|
||||||
|
if (length >= partLen) {
|
||||||
|
|
||||||
|
memcpy(&_buffer[index], input, partLen);
|
||||||
|
transform(_buffer);
|
||||||
|
|
||||||
|
for (i = partLen; i + 63 < length; i += 64) {
|
||||||
|
transform(&input[i]);
|
||||||
|
}
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
memcpy(&_buffer[index], &input[i], length - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 finalization. Ends an MD5 message-_digest operation, writing the
|
||||||
|
the message _digest and zeroizing the context.
|
||||||
|
*/
|
||||||
|
void MD5::final() {
|
||||||
|
|
||||||
|
byte bits[8];
|
||||||
|
uint32 oldState[4];
|
||||||
|
uint32 oldCount[2];
|
||||||
|
uint32 index, padLen;
|
||||||
|
|
||||||
|
/* Save current state and count. */
|
||||||
|
memcpy(oldState, _state, 16);
|
||||||
|
memcpy(oldCount, _count, 8);
|
||||||
|
|
||||||
|
/* Save number of bits */
|
||||||
|
encode(_count, bits, 8);
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64. */
|
||||||
|
index = (uint32)((_count[0] >> 3) & 0x3f);
|
||||||
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
|
update(PADDING, padLen);
|
||||||
|
|
||||||
|
/* Append length (before padding) */
|
||||||
|
update(bits, 8);
|
||||||
|
|
||||||
|
/* Store state in digest */
|
||||||
|
encode(_state, _digest, 16);
|
||||||
|
|
||||||
|
/* Restore current state and count. */
|
||||||
|
memcpy(_state, oldState, 16);
|
||||||
|
memcpy(_count, oldCount, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 basic transformation. Transforms _state based on block. */
|
||||||
|
void MD5::transform(const byte block[64]) {
|
||||||
|
|
||||||
|
uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16];
|
||||||
|
|
||||||
|
decode(block, x, 64);
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||||
|
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||||
|
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||||
|
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||||
|
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||||
|
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||||
|
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||||
|
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||||
|
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||||
|
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||||
|
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||||
|
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||||
|
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||||
|
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||||
|
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||||
|
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||||
|
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||||
|
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||||
|
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||||
|
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||||
|
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||||
|
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||||
|
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||||
|
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||||
|
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||||
|
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||||
|
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||||
|
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||||
|
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||||
|
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||||
|
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||||
|
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||||
|
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||||
|
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||||
|
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||||
|
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||||
|
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||||
|
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||||
|
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||||
|
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||||
|
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||||
|
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||||
|
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||||
|
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||||
|
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||||
|
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||||
|
|
||||||
|
/* Round 4 */
|
||||||
|
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||||
|
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||||
|
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||||
|
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||||
|
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||||
|
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||||
|
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||||
|
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||||
|
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||||
|
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||||
|
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||||
|
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||||
|
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||||
|
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||||
|
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||||
|
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||||
|
|
||||||
|
_state[0] += a;
|
||||||
|
_state[1] += b;
|
||||||
|
_state[2] += c;
|
||||||
|
_state[3] += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encodes input (ulong) into output (byte). Assumes length is
|
||||||
|
a multiple of 4.
|
||||||
|
*/
|
||||||
|
void MD5::encode(const uint32* input, byte* output, size_t length) {
|
||||||
|
|
||||||
|
for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
|
||||||
|
output[j]= (byte)(input[i] & 0xff);
|
||||||
|
output[j + 1] = (byte)((input[i] >> 8) & 0xff);
|
||||||
|
output[j + 2] = (byte)((input[i] >> 16) & 0xff);
|
||||||
|
output[j + 3] = (byte)((input[i] >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decodes input (byte) into output (ulong). Assumes length is
|
||||||
|
a multiple of 4.
|
||||||
|
*/
|
||||||
|
void MD5::decode(const byte* input, uint32* output, size_t length) {
|
||||||
|
|
||||||
|
for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
|
||||||
|
output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) |
|
||||||
|
(((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert byte array to hex string. */
|
||||||
|
string MD5::bytesToHexString(const byte* input, size_t length) {
|
||||||
|
|
||||||
|
string str;
|
||||||
|
str.reserve(length << 1);
|
||||||
|
for (size_t i = 0; i < length; ++i) {
|
||||||
|
int t = (int) input[i];
|
||||||
|
int a = t / 16;
|
||||||
|
int b = t % 16;
|
||||||
|
str.append(1, HEX[a]);
|
||||||
|
str.append(1, HEX[b]);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert digest to string value */
|
||||||
|
string MD5::toString() {
|
||||||
|
return bytesToHexString(digest(), 16);
|
||||||
|
}
|
157
app/src/main/cpp/message.cpp
Normal file
157
app/src/main/cpp/message.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#include "jni.h"
|
||||||
|
#include "cqcode.h"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
inline void replace_string(std::string& str, const std::string& from, const std::string& to) {
|
||||||
|
size_t startPos = 0;
|
||||||
|
while ((startPos = str.find(from, startPos)) != std::string::npos) {
|
||||||
|
str.replace(startPos, from.length(), to);
|
||||||
|
startPos += to.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_helper_MessageHelper_createMessageUniseq(JNIEnv *env, jobject thiz,
|
||||||
|
jint chat_type,
|
||||||
|
jlong time) {
|
||||||
|
static std::random_device rd;
|
||||||
|
static std::mt19937 generator(rd());
|
||||||
|
static std::uniform_int_distribution<int> distribution(INT32_MIN, INT32_MAX);
|
||||||
|
int64_t uniseq = (time / 1000) << (8 * 4);
|
||||||
|
auto msgtype = (int64_t) chat_type;
|
||||||
|
int64_t random = abs(distribution(generator)) & 0xffffff00L;
|
||||||
|
return uniseq | random | msgtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_helper_MessageHelper_getChatType(JNIEnv *env, jobject thiz,
|
||||||
|
jlong msg_id) {
|
||||||
|
return (int32_t) ((int64_t) msg_id & 0xffL);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_helper_MessageHelper_nativeDecodeCQCode(JNIEnv *env, jobject thiz,
|
||||||
|
jstring code) {
|
||||||
|
jclass ArrayList = env->FindClass("java/util/ArrayList");
|
||||||
|
jmethodID NewArrayList = env->GetMethodID(ArrayList, "<init>", "()V");
|
||||||
|
jmethodID ArrayListAdd = env->GetMethodID(ArrayList, "add", "(Ljava/lang/Object;)Z");
|
||||||
|
jobject arrayList = env->NewObject(ArrayList, NewArrayList);
|
||||||
|
|
||||||
|
const char* cCode = env->GetStringUTFChars(code, nullptr);
|
||||||
|
std::string cppCode = cCode;
|
||||||
|
std::vector<std::unordered_map<std::string, std::string>> dest;
|
||||||
|
try {
|
||||||
|
decode_cqcode(cppCode, dest);
|
||||||
|
} catch (illegal_code& code) {
|
||||||
|
return arrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass HashMap = env->FindClass("java/util/HashMap");
|
||||||
|
jmethodID NewHashMap = env->GetMethodID(HashMap, "<init>", "()V");
|
||||||
|
jclass String = env->FindClass("java/lang/String");
|
||||||
|
jmethodID NewString = env->GetMethodID(String, "<init>", "([BLjava/lang/String;)V");
|
||||||
|
jstring charset = env->NewStringUTF("UTF-8");
|
||||||
|
jmethodID put = env->GetMethodID(HashMap, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
for (auto& map : dest) {
|
||||||
|
jobject hashMap = env->NewObject(HashMap, NewHashMap);
|
||||||
|
for (const auto& pair : map) {
|
||||||
|
jbyteArray keyArray = env->NewByteArray((int) pair.first.size());
|
||||||
|
jbyteArray valueArray = env->NewByteArray((int) pair.second.size());
|
||||||
|
env->SetByteArrayRegion(keyArray, 0, (int) pair.first.size(), (jbyte*)pair.first.c_str());
|
||||||
|
env->SetByteArrayRegion(valueArray, 0, (int) pair.second.size(), (jbyte*)pair.second.c_str());
|
||||||
|
auto key = (jstring) env->NewObject(String, NewString, keyArray, charset);
|
||||||
|
auto value = (jstring) env->NewObject(String, NewString, valueArray, charset);
|
||||||
|
env->CallObjectMethod(hashMap, put, key, value);
|
||||||
|
}
|
||||||
|
env->CallBooleanMethod(arrayList, ArrayListAdd, hashMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteLocalRef(ArrayList);
|
||||||
|
env->DeleteLocalRef(HashMap);
|
||||||
|
env->DeleteLocalRef(String);
|
||||||
|
env->DeleteLocalRef(charset);
|
||||||
|
env->ReleaseStringUTFChars(code, cCode);
|
||||||
|
|
||||||
|
return arrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_helper_MessageHelper_nativeEncodeCQCode(JNIEnv *env, jobject thiz,
|
||||||
|
jobject segment_list) {
|
||||||
|
jclass List = env->FindClass("java/util/List");
|
||||||
|
jmethodID ListSize = env->GetMethodID(List, "size", "()I");
|
||||||
|
jmethodID ListGet = env->GetMethodID(List, "get", "(I)Ljava/lang/Object;");
|
||||||
|
jclass Map = env->FindClass("java/util/Map");
|
||||||
|
jmethodID MapGet = env->GetMethodID(Map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
jmethodID entrySetMethod = env->GetMethodID(Map, "entrySet", "()Ljava/util/Set;");
|
||||||
|
jclass setClass = env->FindClass("java/util/Set");
|
||||||
|
jmethodID iteratorMethod = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
|
||||||
|
jclass entryClass = env->FindClass("java/util/Map$Entry");
|
||||||
|
jmethodID getKeyMethod = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
|
||||||
|
jmethodID getValueMethod = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
jint size = env->CallIntMethod(segment_list, ListSize);
|
||||||
|
for (int i = 0; i < size; i++ ) {
|
||||||
|
jobject segment = env->CallObjectMethod(segment_list, ListGet, i);
|
||||||
|
jobject entrySet = env->CallObjectMethod(segment, entrySetMethod);
|
||||||
|
jobject iterator = env->CallObjectMethod(entrySet, iteratorMethod);
|
||||||
|
auto type = (jstring) env->CallObjectMethod(segment, MapGet, env->NewStringUTF("_type"));
|
||||||
|
auto typeString = env->GetStringUTFChars(type, nullptr);
|
||||||
|
if (strcmp(typeString, "text") == 0) {
|
||||||
|
auto text = (jstring) env->CallObjectMethod(segment, MapGet, env->NewStringUTF("text"));
|
||||||
|
auto textString = env->GetStringUTFChars(text, nullptr);
|
||||||
|
std::string tmpValue = textString;
|
||||||
|
replace_string(tmpValue, "&", "&");
|
||||||
|
replace_string(tmpValue, "[", "[");
|
||||||
|
replace_string(tmpValue, "]", "]");
|
||||||
|
replace_string(tmpValue, ",", ",");
|
||||||
|
result.append(tmpValue);
|
||||||
|
env->ReleaseStringUTFChars(text, textString);
|
||||||
|
} else {
|
||||||
|
result.append("[CQ:");
|
||||||
|
result.append(typeString);
|
||||||
|
while (env->CallBooleanMethod(iterator, env->GetMethodID(env->GetObjectClass(iterator), "hasNext", "()Z"))) {
|
||||||
|
jobject entry = env->CallObjectMethod(iterator, env->GetMethodID(env->GetObjectClass(iterator), "next", "()Ljava/lang/Object;"));
|
||||||
|
auto key = (jstring) env->CallObjectMethod(entry, getKeyMethod);
|
||||||
|
auto value = (jstring) env->CallObjectMethod(entry, getValueMethod);
|
||||||
|
auto keyString = env->GetStringUTFChars(key, nullptr);
|
||||||
|
auto valueString = env->GetStringUTFChars(value, nullptr);
|
||||||
|
if (strcmp(keyString, "_type") != 0) {
|
||||||
|
std::string tmpValue = valueString;
|
||||||
|
replace_string(tmpValue, "&", "&");
|
||||||
|
replace_string(tmpValue, "[", "[");
|
||||||
|
replace_string(tmpValue, "]", "]");
|
||||||
|
replace_string(tmpValue, ",", ",");
|
||||||
|
result.append(",").append(keyString).append("=").append(tmpValue);
|
||||||
|
}
|
||||||
|
env->ReleaseStringUTFChars(key, keyString);
|
||||||
|
env->ReleaseStringUTFChars(value, valueString);
|
||||||
|
env->DeleteLocalRef(entry);
|
||||||
|
env->DeleteLocalRef(key);
|
||||||
|
env->DeleteLocalRef(value);
|
||||||
|
}
|
||||||
|
result.append("]");
|
||||||
|
}
|
||||||
|
env->ReleaseStringUTFChars(type, typeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteLocalRef(List);
|
||||||
|
env->DeleteLocalRef(Map);
|
||||||
|
env->DeleteLocalRef(setClass);
|
||||||
|
env->DeleteLocalRef(entryClass);
|
||||||
|
return env->NewStringUTF(result.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_helper_MessageHelper_insertChatTypeToMsgId(JNIEnv *env, jobject thiz,
|
||||||
|
jlong msg_id, jint chat_type) {
|
||||||
|
return (msg_id & 0xffffffffffffff00L) | chat_type;
|
||||||
|
}
|
54
app/src/main/cpp/shamrock.cpp
Normal file
54
app/src/main/cpp/shamrock.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <jni.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <random>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_xposed_actions_PullConfig_testNativeLibrary(JNIEnv *env, jobject thiz) {
|
||||||
|
return env->NewStringUTF("加载Shamrock库成功~");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_utils_MD5_genFileMd5Hex(JNIEnv *env, jobject thiz, jstring file_path) {
|
||||||
|
auto cPathStr = env->GetStringUTFChars(file_path, nullptr);
|
||||||
|
std::filesystem::path filePath(cPathStr);
|
||||||
|
if (!std::filesystem::exists(filePath)) {
|
||||||
|
jclass exClass = env->FindClass("java/io/FileNotFoundException");
|
||||||
|
env->ThrowNew(exClass, "目标文件不存在");
|
||||||
|
env->DeleteLocalRef(exClass);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto file = std::ifstream(filePath.c_str(), std::ios::binary);
|
||||||
|
MD5 md5;
|
||||||
|
md5.update(file);
|
||||||
|
auto md5Hex = md5.toString();
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(file_path, cPathStr);
|
||||||
|
|
||||||
|
return env->NewStringUTF(md5Hex.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_utils_MD5_getMd5Hex(JNIEnv *env, jobject thiz, jbyteArray bytes) {
|
||||||
|
auto len = env->GetArrayLength(bytes);
|
||||||
|
auto *cBytes = new unsigned char[len];
|
||||||
|
env->GetByteArrayRegion(bytes, 0, len, reinterpret_cast<jbyte *>(cBytes));
|
||||||
|
|
||||||
|
MD5 md5;
|
||||||
|
md5.update(cBytes, len);
|
||||||
|
auto md5Hex = md5.toString();
|
||||||
|
|
||||||
|
delete[] cBytes;
|
||||||
|
|
||||||
|
return env->NewStringUTF(md5Hex.c_str());
|
||||||
|
}
|
591
app/src/main/cpp/silk.cpp
Normal file
591
app/src/main/cpp/silk.cpp
Normal file
@ -0,0 +1,591 @@
|
|||||||
|
#include <jni.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <random>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "SKP_Silk_SDK_API.h"
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Define codec specific settings */
|
||||||
|
#define MAX_BYTES_PER_FRAME_ENC 250 // Equals peak bitrate of 100 kbps
|
||||||
|
#define MAX_INPUT_FRAMES 5
|
||||||
|
#define FRAME_LENGTH_MS 20
|
||||||
|
#define MAX_API_FS_KHZ 48
|
||||||
|
|
||||||
|
|
||||||
|
/* Define codec specific settings should be moved to h file */
|
||||||
|
#define MAX_BYTES_PER_FRAME_DEC 1024
|
||||||
|
#define MAX_INPUT_FRAMES 5
|
||||||
|
#define MAX_FRAME_LENGTH 480
|
||||||
|
#define FRAME_LENGTH_MS 20
|
||||||
|
#define MAX_API_FS_KHZ 48
|
||||||
|
#define MAX_LBRR_DELAY 2
|
||||||
|
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
/* Function to convert a little endian int16 to a */
|
||||||
|
/* big endian int16 or vica verca */
|
||||||
|
void swap_endian(
|
||||||
|
SKP_int16 vec[],
|
||||||
|
SKP_int len
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int16 tmp;
|
||||||
|
SKP_uint8 *p1, *p2;
|
||||||
|
|
||||||
|
for( i = 0; i < len; i++ ){
|
||||||
|
tmp = vec[ i ];
|
||||||
|
p1 = (SKP_uint8 *)&vec[ i ]; p2 = (SKP_uint8 *)&tmp;
|
||||||
|
p1[ 0 ] = p2[ 1 ]; p1[ 1 ] = p2[ 0 ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(_WINCE))
|
||||||
|
#include <windows.h> /* timer */
|
||||||
|
#else // Linux or Mac
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
unsigned long GetHighResolutionTime() /* O: time in usec*/
|
||||||
|
{
|
||||||
|
/* Returns a time counter in microsec */
|
||||||
|
/* the resolution is platform dependent */
|
||||||
|
/* but is typically 1.62 us resolution */
|
||||||
|
LARGE_INTEGER lpPerformanceCount;
|
||||||
|
LARGE_INTEGER lpFrequency;
|
||||||
|
QueryPerformanceCounter(&lpPerformanceCount);
|
||||||
|
QueryPerformanceFrequency(&lpFrequency);
|
||||||
|
return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);
|
||||||
|
}
|
||||||
|
#else // Linux or Mac
|
||||||
|
unsigned long GetHighResolutionTime() /* O: time in usec*/
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, 0);
|
||||||
|
return((tv.tv_sec*1000000)+(tv.tv_usec));
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
/* Seed for the random number generator, which is used for simulating packet loss */
|
||||||
|
static SKP_int32 rand_seed = 1;
|
||||||
|
|
||||||
|
int silk_encode(int rate, char type, const char* inputFile, const char* outPutFile);
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_utils_AudioUtils_pcmToSilk(JNIEnv *env, jobject thiz,
|
||||||
|
jint rate,
|
||||||
|
jbyte type,
|
||||||
|
jstring pcm_file,
|
||||||
|
jstring silk_file) {
|
||||||
|
auto pcm = env->GetStringUTFChars(pcm_file, nullptr);
|
||||||
|
auto silk = env->GetStringUTFChars(silk_file, nullptr);
|
||||||
|
return silk_encode(rate, type, pcm, silk);
|
||||||
|
}
|
||||||
|
|
||||||
|
int silk_encode(int rate, char type, const char* inputFile, const char* outPutFile) {
|
||||||
|
double filetime;
|
||||||
|
size_t counter;
|
||||||
|
SKP_int32 k, totPackets, totActPackets, ret;
|
||||||
|
SKP_int16 nBytes;
|
||||||
|
double sumBytes, sumActBytes, nrg;
|
||||||
|
SKP_uint8 payload[ MAX_BYTES_PER_FRAME_ENC * MAX_INPUT_FRAMES ];
|
||||||
|
SKP_int16 in[ FRAME_LENGTH_MS * MAX_API_FS_KHZ * MAX_INPUT_FRAMES ];
|
||||||
|
char speechInFileName[ 150 ], bitOutFileName[ 150 ];
|
||||||
|
FILE *bitOutFile, *speechInFile;
|
||||||
|
SKP_int32 encSizeBytes;
|
||||||
|
void *psEnc;
|
||||||
|
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
SKP_int16 nBytes_LE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* default settings */
|
||||||
|
SKP_int32 API_fs_Hz = rate;
|
||||||
|
SKP_int32 max_internal_fs_Hz;
|
||||||
|
SKP_int32 targetRate_bps = 25000;
|
||||||
|
SKP_int32 smplsSinceLastPacket, packetSize_ms = 20;
|
||||||
|
SKP_int32 frameSizeReadFromFile_ms = 20;
|
||||||
|
SKP_int32 packetLoss_perc = 0;
|
||||||
|
#if LOW_COMPLEXITY_ONLY
|
||||||
|
SKP_int32 complexity_mode = 0;
|
||||||
|
#else
|
||||||
|
SKP_int32 complexity_mode = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SKP_int32 DTX_enabled = 0, INBandFEC_enabled = 0;
|
||||||
|
SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder
|
||||||
|
SKP_SILK_SDK_EncControlStruct encStatus; // Struct for status of encoder
|
||||||
|
|
||||||
|
/* get arguments */
|
||||||
|
strcpy( speechInFileName, inputFile );
|
||||||
|
strcpy( bitOutFileName, outPutFile );
|
||||||
|
|
||||||
|
/* If no max internal is specified, set to minimum of API fs and 24 kHz */
|
||||||
|
max_internal_fs_Hz = rate;
|
||||||
|
|
||||||
|
/* Open files */
|
||||||
|
speechInFile = fopen( speechInFileName, "rb" );
|
||||||
|
if( speechInFile == nullptr ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bitOutFile = fopen( bitOutFileName, "wb" );
|
||||||
|
if( bitOutFile == nullptr ) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add Silk header to stream */
|
||||||
|
{
|
||||||
|
char Tencent_break[1];
|
||||||
|
Tencent_break[0] = type;
|
||||||
|
fwrite( Tencent_break, sizeof( char ), 1, bitOutFile );
|
||||||
|
|
||||||
|
static const char Silk_header[] = "#!SILK_V3";
|
||||||
|
fwrite( Silk_header, sizeof( char ), strlen( Silk_header ), bitOutFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create Encoder */
|
||||||
|
ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Error: SKP_Silk_create_encoder returned %d", ret );
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
psEnc = malloc( encSizeBytes );
|
||||||
|
|
||||||
|
/* Reset Encoder */
|
||||||
|
ret = SKP_Silk_SDK_InitEncoder( psEnc, &encStatus );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Error: SKP_Silk_reset_encoder returned %d", ret );
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Encoder parameters */
|
||||||
|
encControl.API_sampleRate = API_fs_Hz;
|
||||||
|
encControl.maxInternalSampleRate = max_internal_fs_Hz;
|
||||||
|
encControl.packetSize = ( packetSize_ms * API_fs_Hz ) / 1000;
|
||||||
|
encControl.packetLossPercentage = packetLoss_perc;
|
||||||
|
encControl.useInBandFEC = INBandFEC_enabled;
|
||||||
|
encControl.useDTX = DTX_enabled;
|
||||||
|
encControl.complexity = complexity_mode;
|
||||||
|
encControl.bitRate = targetRate_bps;
|
||||||
|
|
||||||
|
totPackets = 0;
|
||||||
|
totActPackets = 0;
|
||||||
|
smplsSinceLastPacket = 0;
|
||||||
|
sumBytes = 0.0;
|
||||||
|
sumActBytes = 0.0;
|
||||||
|
smplsSinceLastPacket = 0;
|
||||||
|
|
||||||
|
while( true ) {
|
||||||
|
/* Read input from file */
|
||||||
|
counter = fread( in, sizeof( SKP_int16 ), ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000, speechInFile );
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
swap_endian( in, counter );
|
||||||
|
#endif
|
||||||
|
if( ( SKP_int )counter < ( ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000 ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* max payload size */
|
||||||
|
nBytes = MAX_BYTES_PER_FRAME_ENC * MAX_INPUT_FRAMES;
|
||||||
|
|
||||||
|
/* Silk Encoder */
|
||||||
|
ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)counter, payload, &nBytes );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "SKP_Silk_Encode returned %d", ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get packet size */
|
||||||
|
packetSize_ms = ( SKP_int )( ( 1000 * ( SKP_int32 )encControl.packetSize ) / encControl.API_sampleRate );
|
||||||
|
smplsSinceLastPacket += ( SKP_int )counter;
|
||||||
|
if( ( ( 1000 * smplsSinceLastPacket ) / API_fs_Hz ) == packetSize_ms ) {
|
||||||
|
/* Sends a dummy zero size packet in case of DTX period */
|
||||||
|
/* to make it work with the decoder test program. */
|
||||||
|
/* In practice should be handled by RTP sequence numbers */
|
||||||
|
totPackets++;
|
||||||
|
sumBytes += nBytes;
|
||||||
|
nrg = 0.0;
|
||||||
|
for( k = 0; k < ( SKP_int )counter; k++ ) {
|
||||||
|
nrg += in[ k ] * (double)in[ k ];
|
||||||
|
}
|
||||||
|
if( ( nrg / ( SKP_int )counter ) > 1e3 ) {
|
||||||
|
sumActBytes += nBytes;
|
||||||
|
totActPackets++;
|
||||||
|
}
|
||||||
|
/* Write payload size */
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
nBytes_LE = nBytes;
|
||||||
|
swap_endian( &nBytes_LE, 1 );
|
||||||
|
fwrite( &nBytes_LE, sizeof( SKP_int16 ), 1, bitOutFile );
|
||||||
|
#else
|
||||||
|
fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
|
||||||
|
#endif
|
||||||
|
/* Write payload */
|
||||||
|
fwrite( payload, sizeof( SKP_uint8 ), nBytes, bitOutFile );
|
||||||
|
smplsSinceLastPacket = 0;
|
||||||
|
//fprintf(stderr, "\rPackets encoded: %d", totPackets);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write dummy because it can not end with 0 bytes */
|
||||||
|
nBytes = -1;
|
||||||
|
|
||||||
|
/* Write payload size */
|
||||||
|
fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
|
||||||
|
|
||||||
|
/* Free Encoder */
|
||||||
|
free( psEnc );
|
||||||
|
|
||||||
|
fclose( speechInFile );
|
||||||
|
fclose( bitOutFile );
|
||||||
|
|
||||||
|
filetime = totPackets * 1e-3 * packetSize_ms;
|
||||||
|
return (int) filetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_moe_fuqiuluo_shamrock_utils_AudioUtils_silkToPcm(JNIEnv *env, jobject thiz, jint rate, jbyte type,
|
||||||
|
jstring pcm_file, jstring silk_file) {
|
||||||
|
auto pcm = env->GetStringUTFChars(pcm_file, nullptr);
|
||||||
|
auto silk = env->GetStringUTFChars(silk_file, nullptr);
|
||||||
|
|
||||||
|
unsigned long tottime, starttime;
|
||||||
|
size_t counter;
|
||||||
|
SKP_int32 totPackets, i, k, ret, tot_len;
|
||||||
|
SKP_int16 len;
|
||||||
|
SKP_int16 nBytes;
|
||||||
|
SKP_uint8 payload[ MAX_BYTES_PER_FRAME_DEC * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];
|
||||||
|
SKP_uint8 *payloadEnd, *payloadToDec = nullptr;
|
||||||
|
SKP_uint8 FECpayload[ MAX_BYTES_PER_FRAME_DEC * MAX_INPUT_FRAMES ], *payloadPtr;
|
||||||
|
SKP_int16 nBytesFEC;
|
||||||
|
SKP_int16 nBytesPerPacket[ MAX_LBRR_DELAY + 1 ], totBytes;
|
||||||
|
SKP_int16 out[ ( ( FRAME_LENGTH_MS * MAX_API_FS_KHZ ) << 1 ) * MAX_INPUT_FRAMES ], *outPtr;
|
||||||
|
char speechOutFileName[ 150 ], bitInFileName[ 150 ];
|
||||||
|
FILE *bitInFile, *speechOutFile;
|
||||||
|
SKP_int32 API_Fs_Hz = rate;
|
||||||
|
SKP_int32 decSizeBytes;
|
||||||
|
void *psDec;
|
||||||
|
SKP_float loss_prob;
|
||||||
|
SKP_int32 frames, lost;
|
||||||
|
SKP_SILK_SDK_DecControlStruct DecControl;
|
||||||
|
|
||||||
|
/* default settings */
|
||||||
|
loss_prob = 0.0f;
|
||||||
|
|
||||||
|
strcpy( bitInFileName, silk);
|
||||||
|
strcpy( speechOutFileName, pcm);
|
||||||
|
|
||||||
|
/* Open files */
|
||||||
|
bitInFile = fopen( bitInFileName, "rb" );
|
||||||
|
if( bitInFile == nullptr ) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Error: could not open input file %s", bitInFileName );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check Silk header */
|
||||||
|
{
|
||||||
|
char header_buf[ 50 ];
|
||||||
|
fread(header_buf, sizeof(char), 1, bitInFile);
|
||||||
|
header_buf[ strlen( "" ) ] = '\0'; /* Terminate with a null character */
|
||||||
|
if( strcmp( header_buf, "" ) != 0 ) {
|
||||||
|
counter = fread( header_buf, sizeof( char ), strlen( "!SILK_V3" ), bitInFile );
|
||||||
|
header_buf[ strlen( "!SILK_V3" ) ] = '\0'; /* Terminate with a null character */
|
||||||
|
if( strcmp( header_buf, "!SILK_V3" ) != 0 ) {
|
||||||
|
/* Non-equal strings */
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Error: Wrong Header %s", header_buf );
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
counter = fread( header_buf, sizeof( char ), strlen( "#!SILK_V3" ), bitInFile );
|
||||||
|
header_buf[ strlen( "#!SILK_V3" ) ] = '\0'; /* Terminate with a null character */
|
||||||
|
if( strcmp( header_buf, "#!SILK_V3" ) != 0 ) {
|
||||||
|
/* Non-equal strings */
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Error: Wrong Header %s", header_buf );
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
speechOutFile = fopen( speechOutFileName, "wb" );
|
||||||
|
if( speechOutFile == nullptr ) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Error: could not open output file %s", speechOutFileName );
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the samplingrate that is requested for the output */
|
||||||
|
if( API_Fs_Hz == 0 ) {
|
||||||
|
DecControl.API_sampleRate = 24000;
|
||||||
|
} else {
|
||||||
|
DecControl.API_sampleRate = API_Fs_Hz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize to one frame per packet, for proper concealment before first packet arrives */
|
||||||
|
DecControl.framesPerPacket = 1;
|
||||||
|
|
||||||
|
/* Create decoder */
|
||||||
|
ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "silk.cpp", "SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );
|
||||||
|
}
|
||||||
|
psDec = malloc( decSizeBytes );
|
||||||
|
|
||||||
|
/* Reset decoder */
|
||||||
|
ret = SKP_Silk_SDK_InitDecoder( psDec );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "silk.cpp", "SKP_Silk_InitDecoder returned %d", ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
totPackets = 0;
|
||||||
|
tottime = 0;
|
||||||
|
payloadEnd = payload;
|
||||||
|
|
||||||
|
/* Simulate the jitter buffer holding MAX_FEC_DELAY packets */
|
||||||
|
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
|
||||||
|
/* Read payload size */
|
||||||
|
counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile );
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
swap_endian( &nBytes, 1 );
|
||||||
|
#endif
|
||||||
|
/* Read payload */
|
||||||
|
counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile );
|
||||||
|
|
||||||
|
if( ( SKP_int16 )counter < nBytes ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nBytesPerPacket[ i ] = nBytes;
|
||||||
|
payloadEnd += nBytes;
|
||||||
|
totPackets++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( 1 ) {
|
||||||
|
/* Read payload size */
|
||||||
|
counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile );
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
swap_endian( &nBytes, 1 );
|
||||||
|
#endif
|
||||||
|
if( nBytes < 0 || counter < 1 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read payload */
|
||||||
|
counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile );
|
||||||
|
if( ( SKP_int16 )counter < nBytes ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulate losses */
|
||||||
|
rand_seed = SKP_RAND( rand_seed );
|
||||||
|
if( ( ( ( float )( ( rand_seed >> 16 ) + ( 1 << 15 ) ) ) / 65535.0f >= ( loss_prob / 100.0f ) ) && ( counter > 0 ) ) {
|
||||||
|
nBytesPerPacket[ MAX_LBRR_DELAY ] = nBytes;
|
||||||
|
payloadEnd += nBytes;
|
||||||
|
} else {
|
||||||
|
nBytesPerPacket[ MAX_LBRR_DELAY ] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( nBytesPerPacket[ 0 ] == 0 ) {
|
||||||
|
/* Indicate lost packet */
|
||||||
|
lost = 1;
|
||||||
|
|
||||||
|
/* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */
|
||||||
|
payloadPtr = payload;
|
||||||
|
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
|
||||||
|
if( nBytesPerPacket[ i + 1 ] > 0 ) {
|
||||||
|
starttime = GetHighResolutionTime();
|
||||||
|
SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC );
|
||||||
|
tottime += GetHighResolutionTime() - starttime;
|
||||||
|
if( nBytesFEC > 0 ) {
|
||||||
|
payloadToDec = FECpayload;
|
||||||
|
nBytes = nBytesFEC;
|
||||||
|
lost = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payloadPtr += nBytesPerPacket[ i + 1 ];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lost = 0;
|
||||||
|
nBytes = nBytesPerPacket[ 0 ];
|
||||||
|
payloadToDec = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Silk decoder */
|
||||||
|
outPtr = out;
|
||||||
|
tot_len = 0;
|
||||||
|
starttime = GetHighResolutionTime();
|
||||||
|
|
||||||
|
if( lost == 0 ) {
|
||||||
|
/* No Loss: Decode all frames in the packet */
|
||||||
|
frames = 0;
|
||||||
|
do {
|
||||||
|
/* Decode 20 ms */
|
||||||
|
ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "silk.cpp", "SKP_Silk_SDK_Decode returned %d", ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
frames++;
|
||||||
|
outPtr += len;
|
||||||
|
tot_len += len;
|
||||||
|
if( frames > MAX_INPUT_FRAMES ) {
|
||||||
|
/* Hack for corrupt stream that could generate too many frames */
|
||||||
|
outPtr = out;
|
||||||
|
tot_len = 0;
|
||||||
|
frames = 0;
|
||||||
|
}
|
||||||
|
/* Until last 20 ms frame of packet has been decoded */
|
||||||
|
} while( DecControl.moreInternalDecoderFrames );
|
||||||
|
} else {
|
||||||
|
/* Loss: Decode enough frames to cover one packet duration */
|
||||||
|
for( i = 0; i < DecControl.framesPerPacket; i++ ) {
|
||||||
|
/* Generate 20 ms */
|
||||||
|
ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "silk.cpp", "SKP_Silk_Decode returned %d", ret );
|
||||||
|
}
|
||||||
|
outPtr += len;
|
||||||
|
tot_len += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tottime += GetHighResolutionTime() - starttime;
|
||||||
|
totPackets++;
|
||||||
|
|
||||||
|
/* Write output to file */
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
swap_endian( out, tot_len );
|
||||||
|
#endif
|
||||||
|
fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile );
|
||||||
|
|
||||||
|
/* Update buffer */
|
||||||
|
totBytes = 0;
|
||||||
|
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
|
||||||
|
totBytes += nBytesPerPacket[ i + 1 ];
|
||||||
|
}
|
||||||
|
/* Check if the received totBytes is valid */
|
||||||
|
if (totBytes < 0 || totBytes > sizeof(payload))
|
||||||
|
{
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "silk.cpp", "Packets decoded: %d", totPackets );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) );
|
||||||
|
payloadEnd -= nBytesPerPacket[ 0 ];
|
||||||
|
SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty the recieve buffer */
|
||||||
|
for( k = 0; k < MAX_LBRR_DELAY; k++ ) {
|
||||||
|
if( nBytesPerPacket[ 0 ] == 0 ) {
|
||||||
|
/* Indicate lost packet */
|
||||||
|
lost = 1;
|
||||||
|
|
||||||
|
/* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */
|
||||||
|
payloadPtr = payload;
|
||||||
|
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
|
||||||
|
if( nBytesPerPacket[ i + 1 ] > 0 ) {
|
||||||
|
starttime = GetHighResolutionTime();
|
||||||
|
SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC );
|
||||||
|
tottime += GetHighResolutionTime() - starttime;
|
||||||
|
if( nBytesFEC > 0 ) {
|
||||||
|
payloadToDec = FECpayload;
|
||||||
|
nBytes = nBytesFEC;
|
||||||
|
lost = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payloadPtr += nBytesPerPacket[ i + 1 ];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lost = 0;
|
||||||
|
nBytes = nBytesPerPacket[ 0 ];
|
||||||
|
payloadToDec = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Silk decoder */
|
||||||
|
outPtr = out;
|
||||||
|
tot_len = 0;
|
||||||
|
starttime = GetHighResolutionTime();
|
||||||
|
|
||||||
|
if( lost == 0 ) {
|
||||||
|
/* No loss: Decode all frames in the packet */
|
||||||
|
frames = 0;
|
||||||
|
do {
|
||||||
|
/* Decode 20 ms */
|
||||||
|
ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "silk.cpp", "SKP_Silk_SDK_Decode returned %d", ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
frames++;
|
||||||
|
outPtr += len;
|
||||||
|
tot_len += len;
|
||||||
|
if( frames > MAX_INPUT_FRAMES ) {
|
||||||
|
/* Hack for corrupt stream that could generate too many frames */
|
||||||
|
outPtr = out;
|
||||||
|
tot_len = 0;
|
||||||
|
frames = 0;
|
||||||
|
}
|
||||||
|
/* Until last 20 ms frame of packet has been decoded */
|
||||||
|
} while( DecControl.moreInternalDecoderFrames );
|
||||||
|
} else {
|
||||||
|
/* Loss: Decode enough frames to cover one packet duration */
|
||||||
|
|
||||||
|
/* Generate 20 ms */
|
||||||
|
for( i = 0; i < DecControl.framesPerPacket; i++ ) {
|
||||||
|
ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len );
|
||||||
|
if( ret ) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "silk.cpp", "SKP_Silk_Decode returned %d", ret );
|
||||||
|
}
|
||||||
|
outPtr += len;
|
||||||
|
tot_len += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tottime += GetHighResolutionTime() - starttime;
|
||||||
|
totPackets++;
|
||||||
|
|
||||||
|
/* Write output to file */
|
||||||
|
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||||
|
swap_endian( out, tot_len );
|
||||||
|
#endif
|
||||||
|
fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile );
|
||||||
|
|
||||||
|
/* Update Buffer */
|
||||||
|
totBytes = 0;
|
||||||
|
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
|
||||||
|
totBytes += nBytesPerPacket[ i + 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the received totBytes is valid */
|
||||||
|
if (totBytes < 0 || totBytes > sizeof(payload))
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf( stderr, "\rPackets decoded: %d", totPackets );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) );
|
||||||
|
payloadEnd -= nBytesPerPacket[ 0 ];
|
||||||
|
SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Free decoder */
|
||||||
|
free( psDec );
|
||||||
|
|
||||||
|
/* Close files */
|
||||||
|
fclose( speechOutFile );
|
||||||
|
fclose( bitInFile );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
287
app/src/main/cpp/src/SKP_Silk_A2NLSF.c
Normal file
287
app/src/main/cpp/src/SKP_Silk_A2NLSF.c
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* Conversion between prediction filter coefficients and NLSFs */
|
||||||
|
/* Requires the order to be an even number */
|
||||||
|
/* A piecewise linear approximation maps LSF <-> cos(LSF) */
|
||||||
|
/* Therefore the result is not accurate NLSFs, but the two */
|
||||||
|
/* function are accurate inverses of each other */
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Number of binary divisions */
|
||||||
|
#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
|
||||||
|
#define QPoly 16
|
||||||
|
#define MAX_ITERATIONS_A2NLSF_FIX 30
|
||||||
|
|
||||||
|
/* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */
|
||||||
|
#define OVERSAMPLE_COSINE_TABLE 0
|
||||||
|
|
||||||
|
/* Helper function for A2NLSF(..) */
|
||||||
|
/* Transforms polynomials from cos(n*f) to cos(f)^n */
|
||||||
|
SKP_INLINE void SKP_Silk_A2NLSF_trans_poly(
|
||||||
|
SKP_int32 *p, /* I/O Polynomial */
|
||||||
|
const SKP_int dd /* I Polynomial order (= filter order / 2 ) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, n;
|
||||||
|
|
||||||
|
for( k = 2; k <= dd; k++ ) {
|
||||||
|
for( n = dd; n > k; n-- ) {
|
||||||
|
p[ n - 2 ] -= p[ n ];
|
||||||
|
}
|
||||||
|
p[ k - 2 ] -= SKP_LSHIFT( p[ k ], 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if EMBEDDED_ARM<6
|
||||||
|
/* Helper function for A2NLSF(..) */
|
||||||
|
/* Polynomial evaluation */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */
|
||||||
|
SKP_int32 *p, /* I Polynomial, QPoly */
|
||||||
|
const SKP_int32 x, /* I Evaluation point, Q12 */
|
||||||
|
const SKP_int dd /* I Order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int n;
|
||||||
|
SKP_int32 x_Q16, y32;
|
||||||
|
|
||||||
|
y32 = p[ dd ]; /* QPoly */
|
||||||
|
x_Q16 = SKP_LSHIFT( x, 4 );
|
||||||
|
for( n = dd - 1; n >= 0; n-- ) {
|
||||||
|
y32 = SKP_SMLAWW( p[ n ], y32, x_Q16 ); /* QPoly */
|
||||||
|
}
|
||||||
|
return y32;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */
|
||||||
|
SKP_int32 *p, /* I Polynomial, QPoly */
|
||||||
|
const SKP_int32 x, /* I Evaluation point, Q12 */
|
||||||
|
const SKP_int dd /* I Order */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_A2NLSF_init(
|
||||||
|
const SKP_int32 *a_Q16,
|
||||||
|
SKP_int32 *P,
|
||||||
|
SKP_int32 *Q,
|
||||||
|
const SKP_int dd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
|
||||||
|
/* Convert filter coefs to even and odd polynomials */
|
||||||
|
P[dd] = SKP_LSHIFT( 1, QPoly );
|
||||||
|
Q[dd] = SKP_LSHIFT( 1, QPoly );
|
||||||
|
for( k = 0; k < dd; k++ ) {
|
||||||
|
#if( QPoly < 16 )
|
||||||
|
P[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
|
||||||
|
Q[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
|
||||||
|
#elif( QPoly == 16 )
|
||||||
|
P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; // QPoly
|
||||||
|
Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; // QPoly
|
||||||
|
#else
|
||||||
|
P[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
|
||||||
|
Q[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Divide out zeros as we have that for even filter orders, */
|
||||||
|
/* z = 1 is always a root in Q, and */
|
||||||
|
/* z = -1 is always a root in P */
|
||||||
|
for( k = dd; k > 0; k-- ) {
|
||||||
|
P[ k - 1 ] -= P[ k ];
|
||||||
|
Q[ k - 1 ] += Q[ k ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transform polynomials from cos(n*f) to cos(f)^n */
|
||||||
|
SKP_Silk_A2NLSF_trans_poly( P, dd );
|
||||||
|
SKP_Silk_A2NLSF_trans_poly( Q, dd );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
|
||||||
|
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
|
||||||
|
void SKP_Silk_A2NLSF(
|
||||||
|
SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
|
||||||
|
SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
|
||||||
|
const SKP_int d /* I Filter order (must be even) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, m, dd, root_ix, ffrac;
|
||||||
|
SKP_int32 xlo, xhi, xmid;
|
||||||
|
SKP_int32 ylo, yhi, ymid;
|
||||||
|
SKP_int32 nom, den;
|
||||||
|
SKP_int32 P[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
|
||||||
|
SKP_int32 Q[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
|
||||||
|
SKP_int32 *PQ[ 2 ];
|
||||||
|
SKP_int32 *p;
|
||||||
|
|
||||||
|
/* Store pointers to array */
|
||||||
|
PQ[ 0 ] = P;
|
||||||
|
PQ[ 1 ] = Q;
|
||||||
|
|
||||||
|
dd = SKP_RSHIFT( d, 1 );
|
||||||
|
|
||||||
|
SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
|
||||||
|
|
||||||
|
/* Find roots, alternating between P and Q */
|
||||||
|
p = P; /* Pointer to polynomial */
|
||||||
|
|
||||||
|
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12
|
||||||
|
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||||
|
|
||||||
|
if( ylo < 0 ) {
|
||||||
|
/* Set the first NLSF to zero and move on to the next */
|
||||||
|
NLSF[ 0 ] = 0;
|
||||||
|
p = Q; /* Pointer to polynomial */
|
||||||
|
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||||
|
root_ix = 1; /* Index of current root */
|
||||||
|
} else {
|
||||||
|
root_ix = 0; /* Index of current root */
|
||||||
|
}
|
||||||
|
k = 1; /* Loop counter */
|
||||||
|
i = 0; /* Counter for bandwidth expansions applied */
|
||||||
|
while( 1 ) {
|
||||||
|
/* Evaluate polynomial */
|
||||||
|
#if OVERSAMPLE_COSINE_TABLE
|
||||||
|
xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] +
|
||||||
|
( ( SKP_Silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] -
|
||||||
|
SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] ) >> 1 ); /* Q12 */
|
||||||
|
#else
|
||||||
|
xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
|
||||||
|
#endif
|
||||||
|
yhi = SKP_Silk_A2NLSF_eval_poly( p, xhi, dd );
|
||||||
|
|
||||||
|
/* Detect zero crossing */
|
||||||
|
if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) {
|
||||||
|
/* Binary division */
|
||||||
|
#if OVERSAMPLE_COSINE_TABLE
|
||||||
|
ffrac = -128;
|
||||||
|
#else
|
||||||
|
ffrac = -256;
|
||||||
|
#endif
|
||||||
|
for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
|
||||||
|
/* Evaluate polynomial */
|
||||||
|
xmid = SKP_RSHIFT_ROUND( xlo + xhi, 1 );
|
||||||
|
ymid = SKP_Silk_A2NLSF_eval_poly( p, xmid, dd );
|
||||||
|
|
||||||
|
/* Detect zero crossing */
|
||||||
|
if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {
|
||||||
|
/* Reduce frequency */
|
||||||
|
xhi = xmid;
|
||||||
|
yhi = ymid;
|
||||||
|
} else {
|
||||||
|
/* Increase frequency */
|
||||||
|
xlo = xmid;
|
||||||
|
ylo = ymid;
|
||||||
|
#if OVERSAMPLE_COSINE_TABLE
|
||||||
|
ffrac = SKP_ADD_RSHIFT( ffrac, 64, m );
|
||||||
|
#else
|
||||||
|
ffrac = SKP_ADD_RSHIFT( ffrac, 128, m );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interpolate */
|
||||||
|
if( SKP_abs( ylo ) < 65536 ) {
|
||||||
|
/* Avoid dividing by zero */
|
||||||
|
den = ylo - yhi;
|
||||||
|
nom = SKP_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + SKP_RSHIFT( den, 1 );
|
||||||
|
if( den != 0 ) {
|
||||||
|
ffrac += SKP_DIV32( nom, den );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
|
||||||
|
ffrac += SKP_DIV32( ylo, SKP_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
|
||||||
|
}
|
||||||
|
#if OVERSAMPLE_COSINE_TABLE
|
||||||
|
NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 7 ) + ffrac, SKP_int16_MAX );
|
||||||
|
#else
|
||||||
|
NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 8 ) + ffrac, SKP_int16_MAX );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SKP_assert( NLSF[ root_ix ] >= 0 );
|
||||||
|
SKP_assert( NLSF[ root_ix ] <= 32767 );
|
||||||
|
|
||||||
|
root_ix++; /* Next root */
|
||||||
|
if( root_ix >= d ) {
|
||||||
|
/* Found all roots */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Alternate pointer to polynomial */
|
||||||
|
p = PQ[ root_ix & 1 ];
|
||||||
|
|
||||||
|
/* Evaluate polynomial */
|
||||||
|
#if OVERSAMPLE_COSINE_TABLE
|
||||||
|
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] +
|
||||||
|
( ( SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] -
|
||||||
|
SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); // Q12
|
||||||
|
#else
|
||||||
|
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ k - 1 ]; // Q12
|
||||||
|
#endif
|
||||||
|
ylo = SKP_LSHIFT( 1 - ( root_ix & 2 ), 12 );
|
||||||
|
} else {
|
||||||
|
/* Increment loop counter */
|
||||||
|
k++;
|
||||||
|
xlo = xhi;
|
||||||
|
ylo = yhi;
|
||||||
|
|
||||||
|
#if OVERSAMPLE_COSINE_TABLE
|
||||||
|
if( k > 2 * LSF_COS_TAB_SZ_FIX ) {
|
||||||
|
#else
|
||||||
|
if( k > LSF_COS_TAB_SZ_FIX ) {
|
||||||
|
#endif
|
||||||
|
i++;
|
||||||
|
if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
|
||||||
|
/* Set NLSFs to white spectrum and exit */
|
||||||
|
NLSF[ 0 ] = SKP_DIV32_16( 1 << 15, d + 1 );
|
||||||
|
for( k = 1; k < d; k++ ) {
|
||||||
|
NLSF[ k ] = SKP_SMULBB( k + 1, NLSF[ 0 ] );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error: Apply progressively more bandwidth expansion and run again */
|
||||||
|
SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 10 + i, i ) ); // 10_Q16 = 0.00015
|
||||||
|
|
||||||
|
SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
|
||||||
|
p = P; /* Pointer to polynomial */
|
||||||
|
xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12
|
||||||
|
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||||
|
if( ylo < 0 ) {
|
||||||
|
/* Set the first NLSF to zero and move on to the next */
|
||||||
|
NLSF[ 0 ] = 0;
|
||||||
|
p = Q; /* Pointer to polynomial */
|
||||||
|
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||||
|
root_ix = 1; /* Index of current root */
|
||||||
|
} else {
|
||||||
|
root_ix = 0; /* Index of current root */
|
||||||
|
}
|
||||||
|
k = 1; /* Reset loop counter */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
app/src/main/cpp/src/SKP_Silk_A2NLSF_arm.S
Normal file
85
app/src/main/cpp/src/SKP_Silk_A2NLSF_arm.S
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
#if EMBEDDED_ARM>=6
|
||||||
|
|
||||||
|
VARDEF y32, r3
|
||||||
|
VARDEF pn1, r4
|
||||||
|
VARDEF pn2, r5
|
||||||
|
VARDEF lo, r6
|
||||||
|
VARDEF hi, r8
|
||||||
|
.globl SYM(SKP_Silk_A2NLSF_eval_poly)
|
||||||
|
SYM(SKP_Silk_A2NLSF_eval_poly):
|
||||||
|
stmdb sp!, {r4-r8, fp, ip, lr}
|
||||||
|
add fp, sp, #28
|
||||||
|
add r0, r0, r2, lsl #2
|
||||||
|
ldr y32, [r0], #-4
|
||||||
|
tst r2, #1
|
||||||
|
beq LR(1, f)
|
||||||
|
ldr pn1, [r0], #-4
|
||||||
|
sub r2, r2, #1
|
||||||
|
mov r1, r1, lsl #4
|
||||||
|
L(0)
|
||||||
|
smull lo, hi, y32, r1
|
||||||
|
subs r2, r2, #1
|
||||||
|
add y32, pn1, hi, lsl #16
|
||||||
|
ldr pn1, [r0], #-4
|
||||||
|
add y32, y32, lo, lsr #16
|
||||||
|
bgt LR(0, b)
|
||||||
|
smull lo, hi, y32, r1
|
||||||
|
add y32, pn1, hi, lsl #16
|
||||||
|
add r0, y32, lo, lsr #16
|
||||||
|
ldmia sp!, {r4-r8, fp, ip, pc}
|
||||||
|
|
||||||
|
L(1)/*EVEN:*/
|
||||||
|
add r0, r0, #4
|
||||||
|
ldmdb r0!, {pn1, pn2}
|
||||||
|
sub r2, r2, #2
|
||||||
|
mov r1, r1, lsl #4
|
||||||
|
L(0)
|
||||||
|
smull lo, hi, y32, r1
|
||||||
|
subs r2, r2, #2
|
||||||
|
add y32, pn2, hi, lsl #16
|
||||||
|
add y32, y32, lo, lsr #16
|
||||||
|
smull lo, hi, y32, r1
|
||||||
|
add y32, pn1, hi, lsl #16
|
||||||
|
ldmdb r0!, {pn1, pn2}
|
||||||
|
add y32, y32, lo, lsr #16
|
||||||
|
bgt LR(0, b)
|
||||||
|
smull lo, hi, y32, r1
|
||||||
|
add y32, pn2, hi, lsl #16
|
||||||
|
add y32, y32, lo, lsr #16
|
||||||
|
smull lo, hi, y32, r1
|
||||||
|
add y32, pn1, hi, lsl #16
|
||||||
|
add r0, y32, lo, lsr #16
|
||||||
|
ldmia sp!, {r4-r8, fp, ip, pc}
|
||||||
|
END
|
||||||
|
#endif
|
||||||
|
#endif
|
180
app/src/main/cpp/src/SKP_Silk_AsmHelper.h
Normal file
180
app/src/main/cpp/src/SKP_Silk_AsmHelper.h
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SKP_Silk_AsmHelper.h
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _SKP_ASM_HELPER_H_
|
||||||
|
#define _SKP_ASM_HELPER_H_
|
||||||
|
|
||||||
|
// Register bank
|
||||||
|
#define _REG 0
|
||||||
|
#define _DREG 1
|
||||||
|
|
||||||
|
// Arg registers
|
||||||
|
#define _R0 0
|
||||||
|
#define _R1 1
|
||||||
|
#define _R2 2
|
||||||
|
#define _R3 3
|
||||||
|
#define _R4 4
|
||||||
|
// GP registers
|
||||||
|
#define _R5 5
|
||||||
|
#define _R6 6
|
||||||
|
#define _R7 7
|
||||||
|
#define _R8 8
|
||||||
|
#define _SB 9
|
||||||
|
#define _SL 10
|
||||||
|
// fp and ip registers
|
||||||
|
#define _FP 11
|
||||||
|
#define _IP 12
|
||||||
|
// lr and sp registers
|
||||||
|
#define _SP 13
|
||||||
|
#define _LR 14
|
||||||
|
|
||||||
|
|
||||||
|
// Extension register bank
|
||||||
|
#define _numDReg
|
||||||
|
|
||||||
|
#define _Q0 0
|
||||||
|
#define _Q1 1
|
||||||
|
#define _Q2 2
|
||||||
|
#define _Q3 3
|
||||||
|
#define _Q4 4
|
||||||
|
#define _Q5 5
|
||||||
|
#define _Q6 6
|
||||||
|
#define _Q7 7
|
||||||
|
#define _Q8 8
|
||||||
|
#define _Q9 9
|
||||||
|
#define _Q10 10
|
||||||
|
#define _Q11 11
|
||||||
|
#define _Q12 12
|
||||||
|
#define _Q13 13
|
||||||
|
#define _Q14 14
|
||||||
|
#define _Q15 15
|
||||||
|
|
||||||
|
#if defined (_WINRT)
|
||||||
|
#else
|
||||||
|
#if defined (IPHONE)
|
||||||
|
#define MACRO .macro
|
||||||
|
#define END_MACRO .endmacro
|
||||||
|
#define ARG0_in
|
||||||
|
#define ARG1_in
|
||||||
|
#define ARG2_in
|
||||||
|
#define ARG3_in
|
||||||
|
#define ARG4_in
|
||||||
|
#define ARG5_in
|
||||||
|
#define ARG6_in
|
||||||
|
#define ARG7_in
|
||||||
|
#define ARG0 $0
|
||||||
|
#define ARG1 $1
|
||||||
|
#define ARG2 $2
|
||||||
|
#define ARG3 $3
|
||||||
|
#define ARG4 $4
|
||||||
|
#define ARG5 $5
|
||||||
|
#define ARG6 $6
|
||||||
|
#define ARG7 $7
|
||||||
|
#define RARG0 r$0
|
||||||
|
#define RARG1 r$1
|
||||||
|
#define QARG0 q$0
|
||||||
|
#define QARG1 q$1
|
||||||
|
|
||||||
|
MACRO CHECK_ABS ARG0_in, ARG1_in
|
||||||
|
.abs is_abs, ARG1
|
||||||
|
.if is_abs==1
|
||||||
|
.set ARG0, ARG1
|
||||||
|
.else
|
||||||
|
.set ARG0, -1
|
||||||
|
.endif
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define MACRO .macro
|
||||||
|
#define END_MACRO .endm
|
||||||
|
#define ARG0_in arg0=-1
|
||||||
|
#define ARG1_in arg1=-1
|
||||||
|
#define ARG2_in arg2=-1
|
||||||
|
#define ARG3_in arg3=-1
|
||||||
|
#define ARG4_in arg4=-1
|
||||||
|
#define ARG5_in arg5=-1
|
||||||
|
#define ARG6_in arg6=-1
|
||||||
|
#define ARG7_in arg7=-1
|
||||||
|
#define ARG0 \arg0
|
||||||
|
#define ARG1 \arg1
|
||||||
|
#define ARG2 \arg2
|
||||||
|
#define ARG3 \arg3
|
||||||
|
#define ARG4 \arg4
|
||||||
|
#define ARG5 \arg5
|
||||||
|
#define ARG6 \arg6
|
||||||
|
#define ARG7 \arg7
|
||||||
|
#define RARG0 r\arg0
|
||||||
|
#define RARG1 r\arg1
|
||||||
|
#define QARG0 q\arg0
|
||||||
|
#define QARG1 q\arg1
|
||||||
|
|
||||||
|
MACRO CHECK_ABS ARG0_in, ARG1_in
|
||||||
|
.set ARG0, ARG1
|
||||||
|
END_MACRO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MACRO VARDEF ARG0_in, ARG1_in
|
||||||
|
ARG0 .req ARG1
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO VARDEFD ARG0_in, ARG1_in
|
||||||
|
ARG0 .req ARG1
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO VARDEFQ ARG0_in, ARG1_in
|
||||||
|
ARG0 .req ARG1
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO END
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO EXTERN ARG0_in
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO ALIGN ARG0_in
|
||||||
|
.align ARG0
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO DATA
|
||||||
|
.data
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO EXPORT ARG0_in
|
||||||
|
.globl ARG0
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
220
app/src/main/cpp/src/SKP_Silk_AsmPreproc.h
Normal file
220
app/src/main/cpp/src/SKP_Silk_AsmPreproc.h
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* SKP_Silk_AsmPreProc.h
|
||||||
|
*
|
||||||
|
* General header for all ARM asms uses SigProcLib.
|
||||||
|
* It contains C preprocessor part and asm preprocessor part.
|
||||||
|
* C preprocessor part:
|
||||||
|
* * Interfacing makefile, arch, fpu and neon support
|
||||||
|
* * Interfacing different symbol styles and asm directives.
|
||||||
|
* * Interfacing compiling time standard output
|
||||||
|
* ASM preprocessor part:
|
||||||
|
* * Defining general asm header/footer for stack/return value
|
||||||
|
* * Allocating stack for local variables and nasted function
|
||||||
|
* * Defining simple syntax checking and debugging routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C preprocessor part
|
||||||
|
*/
|
||||||
|
#ifndef _SKP_ASM_PREPROC_H_
|
||||||
|
#define _SKP_ASM_PREPROC_H_
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmHelper.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Checking compilier __ARMEL__ defines */
|
||||||
|
#if !__ARMEL__ && (!defined(NO_ASM)) && (!defined(_WINRT))
|
||||||
|
#error Currently SKP_Silk_AsmPreProc only supports little endian.
|
||||||
|
// above line can be replaced by
|
||||||
|
// #warning __ARMEL__=0
|
||||||
|
// #define NOASM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Defining macro for different user label prefix. */
|
||||||
|
#ifndef __USER_LABEL_PREFIX__
|
||||||
|
#define __USER_LABEL_PREFIX__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||||
|
#define CONCAT2(a, b) a ## b
|
||||||
|
|
||||||
|
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||||
|
|
||||||
|
/* Remapping register for iphone. */
|
||||||
|
|
||||||
|
#ifdef IPHONE
|
||||||
|
# define _fp r7
|
||||||
|
# define _r7 r11
|
||||||
|
#else
|
||||||
|
# define _fp fp
|
||||||
|
# define _r7 r7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Checking compiler __ARM_EABI__ defines */
|
||||||
|
|
||||||
|
#if __ARMEB__
|
||||||
|
#define NO_ASM //remove asm optimization for ARM big endian.
|
||||||
|
#else
|
||||||
|
#define ARM_LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Interfacing some asm directives to macros*/
|
||||||
|
#define GBL .globl
|
||||||
|
|
||||||
|
/* Legacy definition wrapper */
|
||||||
|
#ifndef NO_ASM
|
||||||
|
#if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__)
|
||||||
|
#define EMBEDDED_ARM 4
|
||||||
|
#define EMBEDDED_ARMv4
|
||||||
|
#elif defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__)
|
||||||
|
#define EMBEDDED_ARM 5
|
||||||
|
#define EMBEDDED_ARMv5
|
||||||
|
#elif defined (__ARM_ARCH_6__) ||defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||||
|
#define EMBEDDED_ARM 6
|
||||||
|
#define EMBEDDED_ARMv6
|
||||||
|
#elif defined (__ARM_ARCH_7A__) && defined (__ARM_NEON__)
|
||||||
|
#define EMBEDDED_ARM 7
|
||||||
|
#define EMBEDDED_ARMv6
|
||||||
|
#elif defined (__ARM_ARCH_7A__)
|
||||||
|
#define EMBEDDED_ARM 6
|
||||||
|
#define EMBEDDED_ARMv6
|
||||||
|
#else
|
||||||
|
#define EMBEDDED_ARM 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINRT
|
||||||
|
#define L(a) a
|
||||||
|
#define LR(a,d) %##d##a
|
||||||
|
|
||||||
|
#define TABLE(L, symbol) symbol
|
||||||
|
#else
|
||||||
|
#define L(a) a:
|
||||||
|
#define LR(a,d) a##d
|
||||||
|
#define DCD .long
|
||||||
|
#define DCW .short
|
||||||
|
#define TABLE(L, symbol) L
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINRT
|
||||||
|
#define streqh strheq
|
||||||
|
#define strneh strhne
|
||||||
|
#define strgth strhgt
|
||||||
|
#define strlth strhlt
|
||||||
|
#define ldrgtsh ldrshgt
|
||||||
|
#define ldmgtia ldmiagt
|
||||||
|
#define ldmgtdb ldmdbgt
|
||||||
|
#define ldrneh ldrhne
|
||||||
|
#define ldmltia ldmialt
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* ASM preprocessor part:
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _WINRT
|
||||||
|
#else
|
||||||
|
// AT&T Format
|
||||||
|
#if EMBEDDED_ARM >= 7
|
||||||
|
.set _ARCH, 7
|
||||||
|
#elif EMBEDDED_ARM >= 6
|
||||||
|
.set _ARCH, 6
|
||||||
|
#elif EMBEDDED_ARM >= 5 // Should be re-considerred as ARMv5 != ARMv5E
|
||||||
|
.set _ARCH, 5
|
||||||
|
#elif EMBEDDED_ARM >= 4
|
||||||
|
.set _ARCH, 4
|
||||||
|
#else
|
||||||
|
.set _ARCH, 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NEON
|
||||||
|
.set _NEON, 1
|
||||||
|
#else
|
||||||
|
.set _NEON, 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MACRO SKP_TABLE ARG0_in, ARG1_in
|
||||||
|
SYM(ARG0):
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MACRO SKP_SMLAD ARG0_in, ARG1_in, ARG2_in, ARG3_in
|
||||||
|
#if EMBEDDED_ARM>=6
|
||||||
|
smlad ARG0, ARG1, ARG2, ARG3
|
||||||
|
#elif EMBEDDED_ARM>=5
|
||||||
|
smlabb ARG0, ARG1, ARG2, ARG3
|
||||||
|
smlatt ARG0, ARG1, ARG2, ARG0
|
||||||
|
#else
|
||||||
|
.abort "SKP_SMUAD can't be used for armv4 or lower device.."
|
||||||
|
#endif
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO SKP_SMUAD ARG0_in, ARG1_in, ARG2_in
|
||||||
|
#if EMBEDDED_ARM>=6
|
||||||
|
smuad ARG0, ARG1, ARG2
|
||||||
|
#elif EMBEDDED_ARM>=5
|
||||||
|
smulbb ARG0, ARG1, ARG2
|
||||||
|
smlatt ARG0, ARG1, ARG2, ARG0
|
||||||
|
#else
|
||||||
|
.abort "SKP_SMUAD can't be used for armv4 or lower device.."
|
||||||
|
#endif
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO SKP_SMLALD ARG0_in, ARG1_in, ARG2_in, ARG3_in
|
||||||
|
#if EMBEDDED_ARM>=6
|
||||||
|
smlald ARG0, ARG1, ARG2, ARG3
|
||||||
|
#elif EMBEDDED_ARM>=5
|
||||||
|
smlalbb ARG0, ARG1, ARG2, ARG3
|
||||||
|
smlaltt ARG0, ARG1, ARG2, ARG3
|
||||||
|
#else
|
||||||
|
.abort "SKP_SMLALD can't be used for armv4 or lower device.."
|
||||||
|
#endif
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO SKP_RSHIFT_ROUND ARG0_in, ARG1_in, ARG2_in
|
||||||
|
#if EMBEDDED_ARM>=4
|
||||||
|
mov ARG0, ARG1, asr #(ARG2-1)
|
||||||
|
add ARG0, ARG0, #1
|
||||||
|
mov ARG0, ARG0, asr #1
|
||||||
|
#else
|
||||||
|
.abort "SKP_RSHIFT_ROUND can't be used for armv3 or lower device.."
|
||||||
|
#endif
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO ADD_SHIFT ARG0_in, ARG1_in, ARG2_in, ARG3_in, ARG4_in
|
||||||
|
add ARG0, ARG1, ARG2, ARG3 ARG4
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
MACRO POST_IR ARG0_in, ARG1_in, ARG2_in, ARG3_in
|
||||||
|
ARG0 ARG1, [ARG2], ARG3
|
||||||
|
END_MACRO
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif //_SKP_ASM_PREPROC_H_
|
149
app/src/main/cpp/src/SKP_Silk_CNG.c
Normal file
149
app/src/main/cpp/src/SKP_Silk_CNG.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* Generates excitation for CNG LPC synthesis */
|
||||||
|
SKP_INLINE void SKP_Silk_CNG_exc(
|
||||||
|
SKP_int16 residual[], /* O CNG residual signal Q0 */
|
||||||
|
SKP_int32 exc_buf_Q10[], /* I Random samples buffer Q10 */
|
||||||
|
SKP_int32 Gain_Q16, /* I Gain to apply */
|
||||||
|
SKP_int length, /* I Length */
|
||||||
|
SKP_int32 *rand_seed /* I/O Seed to random index generator */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int32 seed;
|
||||||
|
SKP_int i, idx, exc_mask;
|
||||||
|
|
||||||
|
exc_mask = CNG_BUF_MASK_MAX;
|
||||||
|
while( exc_mask > length ) {
|
||||||
|
exc_mask = SKP_RSHIFT( exc_mask, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = *rand_seed;
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
seed = SKP_RAND( seed );
|
||||||
|
idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );
|
||||||
|
SKP_assert( idx >= 0 );
|
||||||
|
SKP_assert( idx <= CNG_BUF_MASK_MAX );
|
||||||
|
residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) );
|
||||||
|
}
|
||||||
|
*rand_seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SKP_Silk_CNG_Reset(
|
||||||
|
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, NLSF_step_Q15, NLSF_acc_Q15;
|
||||||
|
|
||||||
|
NLSF_step_Q15 = SKP_DIV32_16( SKP_int16_MAX, psDec->LPC_order + 1 );
|
||||||
|
NLSF_acc_Q15 = 0;
|
||||||
|
for( i = 0; i < psDec->LPC_order; i++ ) {
|
||||||
|
NLSF_acc_Q15 += NLSF_step_Q15;
|
||||||
|
psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15;
|
||||||
|
}
|
||||||
|
psDec->sCNG.CNG_smth_Gain_Q16 = 0;
|
||||||
|
psDec->sCNG.rand_seed = 3176576;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Updates CNG estimate, and applies the CNG when packet was lost */
|
||||||
|
void SKP_Silk_CNG(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[], /* I/O Signal */
|
||||||
|
SKP_int length /* I Length of residual */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, subfr;
|
||||||
|
SKP_int32 tmp_32, Gain_Q26, max_Gain_Q16;
|
||||||
|
SKP_int16 LPC_buf[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int16 CNG_sig[ MAX_FRAME_LENGTH ];
|
||||||
|
SKP_Silk_CNG_struct *psCNG;
|
||||||
|
psCNG = &psDec->sCNG;
|
||||||
|
|
||||||
|
if( psDec->fs_kHz != psCNG->fs_kHz ) {
|
||||||
|
/* Reset state */
|
||||||
|
SKP_Silk_CNG_Reset( psDec );
|
||||||
|
|
||||||
|
psCNG->fs_kHz = psDec->fs_kHz;
|
||||||
|
}
|
||||||
|
if( psDec->lossCnt == 0 && psDec->vadFlag == NO_VOICE_ACTIVITY ) {
|
||||||
|
/* Update CNG parameters */
|
||||||
|
|
||||||
|
/* Smoothing of LSF's */
|
||||||
|
for( i = 0; i < psDec->LPC_order; i++ ) {
|
||||||
|
psCNG->CNG_smth_NLSF_Q15[ i ] += SKP_SMULWB( psDec->prevNLSF_Q15[ i ] - psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 );
|
||||||
|
}
|
||||||
|
/* Find the subframe with the highest gain */
|
||||||
|
max_Gain_Q16 = 0;
|
||||||
|
subfr = 0;
|
||||||
|
for( i = 0; i < NB_SUBFR; i++ ) {
|
||||||
|
if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) {
|
||||||
|
max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];
|
||||||
|
subfr = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Update CNG excitation buffer with excitation from this subframe */
|
||||||
|
SKP_memmove( &psCNG->CNG_exc_buf_Q10[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q10, ( NB_SUBFR - 1 ) * psDec->subfr_length * sizeof( SKP_int32 ) );
|
||||||
|
SKP_memcpy( psCNG->CNG_exc_buf_Q10, &psDec->exc_Q10[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
/* Smooth gains */
|
||||||
|
for( i = 0; i < NB_SUBFR; i++ ) {
|
||||||
|
psCNG->CNG_smth_Gain_Q16 += SKP_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add CNG when packet is lost and / or when low speech activity */
|
||||||
|
if( psDec->lossCnt ) {//|| psDec->vadFlag == NO_VOICE_ACTIVITY ) {
|
||||||
|
|
||||||
|
/* Generate CNG excitation */
|
||||||
|
SKP_Silk_CNG_exc( CNG_sig, psCNG->CNG_exc_buf_Q10,
|
||||||
|
psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
|
||||||
|
|
||||||
|
/* Convert CNG NLSF to filter representation */
|
||||||
|
SKP_Silk_NLSF2A_stable( LPC_buf, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
|
||||||
|
|
||||||
|
Gain_Q26 = ( SKP_int32 )1 << 26; /* 1.0 */
|
||||||
|
|
||||||
|
/* Generate CNG signal, by synthesis filtering */
|
||||||
|
if( psDec->LPC_order == 16 ) {
|
||||||
|
SKP_Silk_LPC_synthesis_order16( CNG_sig, LPC_buf,
|
||||||
|
Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length );
|
||||||
|
} else {
|
||||||
|
SKP_Silk_LPC_synthesis_filter( CNG_sig, LPC_buf,
|
||||||
|
Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length, psDec->LPC_order );
|
||||||
|
}
|
||||||
|
/* Mix with signal */
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
tmp_32 = signal[ i ] + CNG_sig[ i ];
|
||||||
|
signal[ i ] = SKP_SAT16( tmp_32 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
}
|
120
app/src/main/cpp/src/SKP_Silk_HP_variable_cutoff_FIX.c
Normal file
120
app/src/main/cpp/src/SKP_Silk_HP_variable_cutoff_FIX.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_tuning_parameters.h"
|
||||||
|
|
||||||
|
#if HIGH_PASS_INPUT
|
||||||
|
|
||||||
|
#define SKP_RADIANS_CONSTANT_Q19 1482 // 0.45f * 2.0f * 3.14159265359 / 1000
|
||||||
|
#define SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 809 // log(80) in Q7
|
||||||
|
|
||||||
|
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
|
||||||
|
void SKP_Silk_HP_variable_cutoff_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||||
|
SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||||
|
SKP_int16 *out, /* O high-pass filtered output signal */
|
||||||
|
const SKP_int16 *in /* I input signal */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int quality_Q15;
|
||||||
|
SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ];
|
||||||
|
SKP_int32 Fc_Q19, r_Q28, r_Q22;
|
||||||
|
SKP_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Estimate Low End of Pitch Frequency Range */
|
||||||
|
/*********************************************/
|
||||||
|
if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* difference, in log domain */
|
||||||
|
pitch_freq_Hz_Q16 = SKP_DIV32_16( SKP_LSHIFT( SKP_MUL( psEnc->sCmn.fs_kHz, 1000 ), 16 ), psEnc->sCmn.prevLag );
|
||||||
|
pitch_freq_log_Q7 = SKP_Silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); //0x70
|
||||||
|
|
||||||
|
/* adjustment based on quality */
|
||||||
|
quality_Q15 = psEncCtrl->input_quality_bands_Q15[ 0 ];
|
||||||
|
pitch_freq_log_Q7 = SKP_SUB32( pitch_freq_log_Q7, SKP_SMULWB( SKP_SMULWB( SKP_LSHIFT( quality_Q15, 2 ), quality_Q15 ),
|
||||||
|
pitch_freq_log_Q7 - SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 ) );
|
||||||
|
pitch_freq_log_Q7 = SKP_ADD32( pitch_freq_log_Q7, SKP_RSHIFT( SKP_FIX_CONST( 0.6, 15 ) - quality_Q15, 9 ) );
|
||||||
|
|
||||||
|
//delta_freq = pitch_freq_log - psEnc->variable_HP_smth1;
|
||||||
|
delta_freq_Q7 = pitch_freq_log_Q7 - SKP_RSHIFT( psEnc->variable_HP_smth1_Q15, 8 );
|
||||||
|
if( delta_freq_Q7 < 0 ) {
|
||||||
|
/* less smoothing for decreasing pitch frequency, to track something close to the minimum */
|
||||||
|
delta_freq_Q7 = SKP_MUL( delta_freq_Q7, 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* limit delta, to reduce impact of outliers */
|
||||||
|
delta_freq_Q7 = SKP_LIMIT_32( delta_freq_Q7, -SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) );
|
||||||
|
|
||||||
|
/* update smoother */
|
||||||
|
psEnc->variable_HP_smth1_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth1_Q15,
|
||||||
|
SKP_MUL( SKP_LSHIFT( psEnc->speech_activity_Q8, 1 ), delta_freq_Q7 ), SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) );
|
||||||
|
}
|
||||||
|
/* second smoother */
|
||||||
|
psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15,
|
||||||
|
psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );
|
||||||
|
|
||||||
|
/* convert from log scale to Hertz */
|
||||||
|
psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) );
|
||||||
|
|
||||||
|
/* limit frequency range */
|
||||||
|
psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT_32( psEncCtrl->pitch_freq_low_Hz,
|
||||||
|
SKP_FIX_CONST( VARIABLE_HP_MIN_FREQ, 0 ), SKP_FIX_CONST( VARIABLE_HP_MAX_FREQ, 0 ) );
|
||||||
|
|
||||||
|
/********************************/
|
||||||
|
/* Compute Filter Coefficients */
|
||||||
|
/********************************/
|
||||||
|
/* compute cut-off frequency, in radians */
|
||||||
|
//Fc_num = (SKP_float)( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz );
|
||||||
|
//Fc_denom = (SKP_float)( 1e3f * psEnc->sCmn.fs_kHz );
|
||||||
|
SKP_assert( psEncCtrl->pitch_freq_low_Hz <= SKP_int32_MAX / SKP_RADIANS_CONSTANT_Q19 );
|
||||||
|
Fc_Q19 = SKP_DIV32_16( SKP_SMULBB( SKP_RADIANS_CONSTANT_Q19, psEncCtrl->pitch_freq_low_Hz ), psEnc->sCmn.fs_kHz ); // range: 3704 - 27787, 11-15 bits
|
||||||
|
SKP_assert( Fc_Q19 >= 3704 );
|
||||||
|
SKP_assert( Fc_Q19 <= 27787 );
|
||||||
|
|
||||||
|
r_Q28 = SKP_FIX_CONST( 1.0, 28 ) - SKP_MUL( SKP_FIX_CONST( 0.92, 9 ), Fc_Q19 );
|
||||||
|
SKP_assert( r_Q28 >= 255347779 );
|
||||||
|
SKP_assert( r_Q28 <= 266690872 );
|
||||||
|
|
||||||
|
/* b = r * [ 1; -2; 1 ]; */
|
||||||
|
/* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
|
||||||
|
B_Q28[ 0 ] = r_Q28;
|
||||||
|
B_Q28[ 1 ] = SKP_LSHIFT( -r_Q28, 1 );
|
||||||
|
B_Q28[ 2 ] = r_Q28;
|
||||||
|
|
||||||
|
// -r * ( 2 - Fc * Fc );
|
||||||
|
r_Q22 = SKP_RSHIFT( r_Q28, 6 );
|
||||||
|
A_Q28[ 0 ] = SKP_SMULWW( r_Q22, SKP_SMULWW( Fc_Q19, Fc_Q19 ) - SKP_FIX_CONST( 2.0, 22 ) );
|
||||||
|
A_Q28[ 1 ] = SKP_SMULWW( r_Q22, r_Q22 );
|
||||||
|
|
||||||
|
/********************************/
|
||||||
|
/* High-Pass Filter */
|
||||||
|
/********************************/
|
||||||
|
SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HIGH_PASS_INPUT
|
278
app/src/main/cpp/src/SKP_Silk_Inlines.h
Normal file
278
app/src/main/cpp/src/SKP_Silk_Inlines.h
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/*! \file SKP_Silk_Inlines.h
|
||||||
|
* \brief SKP_Silk_Inlines.h defines inline signal processing functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SKP_SILK_FIX_INLINES_H_
|
||||||
|
#define _SKP_SILK_FIX_INLINES_H_
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* count leading zeros of SKP_int64 */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_CLZ64(SKP_int64 in)
|
||||||
|
{
|
||||||
|
SKP_int32 in_upper;
|
||||||
|
|
||||||
|
in_upper = (SKP_int32)SKP_RSHIFT64(in, 32);
|
||||||
|
if (in_upper == 0) {
|
||||||
|
/* Search in the lower 32 bits */
|
||||||
|
return 32 + SKP_Silk_CLZ32( (SKP_int32) in );
|
||||||
|
} else {
|
||||||
|
/* Search in the upper 32 bits */
|
||||||
|
return SKP_Silk_CLZ32( in_upper );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get number of leading zeros and fractional part (the bits right after the leading one */
|
||||||
|
SKP_INLINE void SKP_Silk_CLZ_FRAC(SKP_int32 in, /* I: input */
|
||||||
|
SKP_int32 *lz, /* O: number of leading zeros */
|
||||||
|
SKP_int32 *frac_Q7) /* O: the 7 bits right after the leading one */
|
||||||
|
{
|
||||||
|
SKP_int32 lzeros = SKP_Silk_CLZ32(in);
|
||||||
|
|
||||||
|
* lz = lzeros;
|
||||||
|
* frac_Q7 = SKP_ROR32(in, 24 - lzeros) & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Approximation of square root */
|
||||||
|
/* Accuracy: < +/- 10% for output values > 15 */
|
||||||
|
/* < +/- 2.5% for output values > 120 */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_SQRT_APPROX(SKP_int32 x)
|
||||||
|
{
|
||||||
|
SKP_int32 y, lz, frac_Q7;
|
||||||
|
|
||||||
|
if( x <= 0 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_Silk_CLZ_FRAC(x, &lz, &frac_Q7);
|
||||||
|
|
||||||
|
if( lz & 1 ) {
|
||||||
|
y = 32768;
|
||||||
|
} else {
|
||||||
|
y = 46214; /* 46214 = sqrt(2) * 32768 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get scaling right */
|
||||||
|
y >>= SKP_RSHIFT(lz, 1);
|
||||||
|
|
||||||
|
/* increment using fractional part of input */
|
||||||
|
y = SKP_SMLAWB(y, y, SKP_SMULBB(213, frac_Q7));
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns the number of left shifts before overflow for a 16 bit number (ITU definition with norm(0)=0) */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_norm16(SKP_int16 a) {
|
||||||
|
|
||||||
|
SKP_int32 a32;
|
||||||
|
|
||||||
|
/* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */
|
||||||
|
if ((a << 1) == 0) return(0);
|
||||||
|
|
||||||
|
a32 = a;
|
||||||
|
/* if (a32 < 0) a32 = -a32 - 1; */
|
||||||
|
a32 ^= SKP_RSHIFT(a32, 31);
|
||||||
|
|
||||||
|
return SKP_Silk_CLZ32(a32) - 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns the number of left shifts before overflow for a 32 bit number (ITU definition with norm(0)=0) */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_norm32(SKP_int32 a) {
|
||||||
|
|
||||||
|
/* if ((a == 0) || (a == SKP_int32_MIN)) return(0); */
|
||||||
|
if ((a << 1) == 0) return(0);
|
||||||
|
|
||||||
|
/* if (a < 0) a = -a - 1; */
|
||||||
|
a ^= SKP_RSHIFT(a, 31);
|
||||||
|
|
||||||
|
return SKP_Silk_CLZ32(a) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Divide two int32 values and return result as int32 in a given Q-domain */
|
||||||
|
SKP_INLINE SKP_int32 SKP_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */
|
||||||
|
const SKP_int32 a32, /* I numerator (Q0) */
|
||||||
|
const SKP_int32 b32, /* I denominator (Q0) */
|
||||||
|
const SKP_int Qres /* I Q-domain of result (>= 0) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int a_headrm, b_headrm, lshift;
|
||||||
|
SKP_int32 b32_inv, a32_nrm, b32_nrm, result;
|
||||||
|
|
||||||
|
SKP_assert( b32 != 0 );
|
||||||
|
SKP_assert( Qres >= 0 );
|
||||||
|
|
||||||
|
/* Compute number of bits head room and normalize inputs */
|
||||||
|
a_headrm = SKP_Silk_CLZ32( SKP_abs(a32) ) - 1;
|
||||||
|
a32_nrm = SKP_LSHIFT(a32, a_headrm); /* Q: a_headrm */
|
||||||
|
b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
|
||||||
|
b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */
|
||||||
|
|
||||||
|
/* Inverse of b32, with 14 bits of precision */
|
||||||
|
b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
|
||||||
|
|
||||||
|
/* First approximation */
|
||||||
|
result = SKP_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
|
||||||
|
|
||||||
|
/* Compute residual by subtracting product of denominator and first approximation */
|
||||||
|
a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 ); /* Q: a_headrm */
|
||||||
|
|
||||||
|
/* Refinement */
|
||||||
|
result = SKP_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
|
||||||
|
|
||||||
|
/* Convert to Qres domain */
|
||||||
|
lshift = 29 + a_headrm - b_headrm - Qres;
|
||||||
|
if( lshift <= 0 ) {
|
||||||
|
return SKP_LSHIFT_SAT32(result, -lshift);
|
||||||
|
} else {
|
||||||
|
if( lshift < 32){
|
||||||
|
return SKP_RSHIFT(result, lshift);
|
||||||
|
} else {
|
||||||
|
/* Avoid undefined result */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invert int32 value and return result as int32 in a given Q-domain */
|
||||||
|
SKP_INLINE SKP_int32 SKP_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */
|
||||||
|
const SKP_int32 b32, /* I denominator (Q0) */
|
||||||
|
const SKP_int Qres /* I Q-domain of result (> 0) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int b_headrm, lshift;
|
||||||
|
SKP_int32 b32_inv, b32_nrm, err_Q32, result;
|
||||||
|
|
||||||
|
SKP_assert( b32 != 0 );
|
||||||
|
SKP_assert( b32 != SKP_int32_MIN ); /* SKP_int32_MIN is not handled by SKP_abs */
|
||||||
|
SKP_assert( Qres > 0 );
|
||||||
|
|
||||||
|
/* Compute number of bits head room and normalize input */
|
||||||
|
b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
|
||||||
|
b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */
|
||||||
|
|
||||||
|
/* Inverse of b32, with 14 bits of precision */
|
||||||
|
b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
|
||||||
|
|
||||||
|
/* First approximation */
|
||||||
|
result = SKP_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */
|
||||||
|
|
||||||
|
/* Compute residual by subtracting product of denominator and first approximation from one */
|
||||||
|
err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */
|
||||||
|
|
||||||
|
/* Refinement */
|
||||||
|
result = SKP_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */
|
||||||
|
|
||||||
|
/* Convert to Qres domain */
|
||||||
|
lshift = 61 - b_headrm - Qres;
|
||||||
|
if( lshift <= 0 ) {
|
||||||
|
return SKP_LSHIFT_SAT32(result, -lshift);
|
||||||
|
} else {
|
||||||
|
if( lshift < 32){
|
||||||
|
return SKP_RSHIFT(result, lshift);
|
||||||
|
}else{
|
||||||
|
/* Avoid undefined result */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SKP_SIN_APPROX_CONST0 (1073735400)
|
||||||
|
#define SKP_SIN_APPROX_CONST1 (-82778932)
|
||||||
|
#define SKP_SIN_APPROX_CONST2 (1059577)
|
||||||
|
#define SKP_SIN_APPROX_CONST3 (-5013)
|
||||||
|
|
||||||
|
/* Sine approximation; an input of 65536 corresponds to 2 * pi */
|
||||||
|
/* Uses polynomial expansion of the input to the power 0, 2, 4 and 6 */
|
||||||
|
/* The relative error is below 1e-5 */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_SIN_APPROX_Q24( /* O returns approximately 2^24 * sin(x * 2 * pi / 65536) */
|
||||||
|
SKP_int32 x
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int y_Q30;
|
||||||
|
|
||||||
|
/* Keep only bottom 16 bits (the function repeats itself with period 65536) */
|
||||||
|
x &= 65535;
|
||||||
|
|
||||||
|
/* Split range in four quadrants */
|
||||||
|
if( x <= 32768 ) {
|
||||||
|
if( x < 16384 ) {
|
||||||
|
/* Return cos(pi/2 - x) */
|
||||||
|
x = 16384 - x;
|
||||||
|
} else {
|
||||||
|
/* Return cos(x - pi/2) */
|
||||||
|
x -= 16384;
|
||||||
|
}
|
||||||
|
if( x < 1100 ) {
|
||||||
|
/* Special case: high accuracy */
|
||||||
|
return SKP_SMLAWB( 1 << 24, SKP_MUL( x, x ), -5053 );
|
||||||
|
}
|
||||||
|
x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */
|
||||||
|
y_Q30 = SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 );
|
||||||
|
y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 );
|
||||||
|
y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 );
|
||||||
|
} else {
|
||||||
|
if( x < 49152 ) {
|
||||||
|
/* Return -cos(3*pi/2 - x) */
|
||||||
|
x = 49152 - x;
|
||||||
|
} else {
|
||||||
|
/* Return -cos(x - 3*pi/2) */
|
||||||
|
x -= 49152;
|
||||||
|
}
|
||||||
|
if( x < 1100 ) {
|
||||||
|
/* Special case: high accuracy */
|
||||||
|
return SKP_SMLAWB( -(1 << 24), SKP_MUL( x, x ), 5053 );
|
||||||
|
}
|
||||||
|
x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */
|
||||||
|
y_Q30 = SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 );
|
||||||
|
y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 );
|
||||||
|
y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 );
|
||||||
|
}
|
||||||
|
return SKP_RSHIFT_ROUND( y_Q30, 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cosine approximation; an input of 65536 corresponds to 2 * pi */
|
||||||
|
/* The relative error is below 1e-5 */
|
||||||
|
SKP_INLINE SKP_int32 SKP_Silk_COS_APPROX_Q24( /* O returns approximately 2^24 * cos(x * 2 * pi / 65536) */
|
||||||
|
SKP_int32 x
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return SKP_Silk_SIN_APPROX_Q24( x + 16384 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_SKP_SILK_FIX_INLINES_H_*/
|
40
app/src/main/cpp/src/SKP_Silk_LBRR_reset.c
Normal file
40
app/src/main/cpp/src/SKP_Silk_LBRR_reset.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* Resets LBRR buffer, used if packet size changes */
|
||||||
|
void SKP_Silk_LBRR_reset(
|
||||||
|
SKP_Silk_encoder_state *psEncC /* I/O state */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
|
||||||
|
for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
|
||||||
|
psEncC->LBRR_buffer[ i ].usage = SKP_SILK_NO_LBRR;
|
||||||
|
}
|
||||||
|
}
|
153
app/src/main/cpp/src/SKP_Silk_LPC_inv_pred_gain.c
Normal file
153
app/src/main/cpp/src/SKP_Silk_LPC_inv_pred_gain.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_LPC_inverse_pred_gain.c *
|
||||||
|
* *
|
||||||
|
* Compute inverse of LPC prediction gain, and *
|
||||||
|
* test if LPC coefficients are stable (all poles within unit circle) *
|
||||||
|
* *
|
||||||
|
* Copyright 2008 (c), Skype Limited *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
#define QA 16
|
||||||
|
#define A_LIMIT SKP_FIX_CONST( 0.99975, QA )
|
||||||
|
|
||||||
|
/* Compute inverse of LPC prediction gain, and */
|
||||||
|
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||||
|
static SKP_int LPC_inverse_pred_gain_QA( /* O: Returns 1 if unstable, otherwise 0 */
|
||||||
|
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
||||||
|
SKP_int32 A_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ],
|
||||||
|
/* I: Prediction coefficients */
|
||||||
|
const SKP_int order /* I: Prediction order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, n, headrm;
|
||||||
|
SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16, tmp_QA;
|
||||||
|
SKP_int32 *Aold_QA, *Anew_QA;
|
||||||
|
|
||||||
|
Anew_QA = A_QA[ order & 1 ];
|
||||||
|
|
||||||
|
*invGain_Q30 = ( 1 << 30 );
|
||||||
|
for( k = order - 1; k > 0; k-- ) {
|
||||||
|
/* Check for stability */
|
||||||
|
if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set RC equal to negated AR coef */
|
||||||
|
rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA );
|
||||||
|
|
||||||
|
/* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */
|
||||||
|
rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );
|
||||||
|
SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
|
||||||
|
SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) );
|
||||||
|
|
||||||
|
/* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */
|
||||||
|
rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 ); /* 16 = 46 - 30 */
|
||||||
|
|
||||||
|
/* Update inverse gain */
|
||||||
|
/* invGain_Q30 range: [ 0 : 2^30 ] */
|
||||||
|
*invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
|
||||||
|
SKP_assert( *invGain_Q30 >= 0 );
|
||||||
|
SKP_assert( *invGain_Q30 <= ( 1 << 30 ) );
|
||||||
|
|
||||||
|
/* Swap pointers */
|
||||||
|
Aold_QA = Anew_QA;
|
||||||
|
Anew_QA = A_QA[ k & 1 ];
|
||||||
|
|
||||||
|
/* Update AR coefficient */
|
||||||
|
headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;
|
||||||
|
rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm ); /* Q: 16 + headrm */
|
||||||
|
for( n = 0; n < k; n++ ) {
|
||||||
|
tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 );
|
||||||
|
Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for stability */
|
||||||
|
if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set RC equal to negated AR coef */
|
||||||
|
rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA );
|
||||||
|
|
||||||
|
/* Range: [ 1 : 2^30 ] */
|
||||||
|
rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );
|
||||||
|
|
||||||
|
/* Update inverse gain */
|
||||||
|
/* Range: [ 0 : 2^30 ] */
|
||||||
|
*invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
|
||||||
|
SKP_assert( *invGain_Q30 >= 0 );
|
||||||
|
SKP_assert( *invGain_Q30 <= 1<<30 );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* For input in Q12 domain */
|
||||||
|
SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */
|
||||||
|
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
||||||
|
const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */
|
||||||
|
const SKP_int order /* I: Prediction order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
|
||||||
|
SKP_int32 *Anew_QA;
|
||||||
|
|
||||||
|
Anew_QA = Atmp_QA[ order & 1 ];
|
||||||
|
|
||||||
|
/* Increase Q domain of the AR coefficients */
|
||||||
|
for( k = 0; k < order; k++ ) {
|
||||||
|
Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For input in Q24 domain */
|
||||||
|
SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
|
||||||
|
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
||||||
|
const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */
|
||||||
|
const SKP_int order /* I: Prediction order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
|
||||||
|
SKP_int32 *Anew_QA;
|
||||||
|
|
||||||
|
Anew_QA = Atmp_QA[ order & 1 ];
|
||||||
|
|
||||||
|
/* Increase Q domain of the AR coefficients */
|
||||||
|
for( k = 0; k < order; k++ ) {
|
||||||
|
Anew_QA[ k ] = SKP_RSHIFT_ROUND( A_Q24[ k ], 24 - QA );
|
||||||
|
}
|
||||||
|
|
||||||
|
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
||||||
|
}
|
||||||
|
|
117
app/src/main/cpp/src/SKP_Silk_LPC_synthesis_filter.c
Normal file
117
app/src/main/cpp/src/SKP_Silk_LPC_synthesis_filter.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_LPC_synthesis_filter.c *
|
||||||
|
* Coefficients are in Q12 *
|
||||||
|
* *
|
||||||
|
* even order AR filter *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* even order AR filter */
|
||||||
|
void SKP_Silk_LPC_synthesis_filter(
|
||||||
|
const SKP_int16 *in, /* I: excitation signal */
|
||||||
|
const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
|
||||||
|
const SKP_int32 Gain_Q26, /* I: gain */
|
||||||
|
SKP_int32 *S, /* I/O: state vector [Order] */
|
||||||
|
SKP_int16 *out, /* O: output signal */
|
||||||
|
const SKP_int32 len, /* I: signal length */
|
||||||
|
const SKP_int Order /* I: filter order, must be even */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
|
||||||
|
SKP_int32 SA, SB, out32_Q10, out32;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 Atmp, A_align_Q12[ SKP_Silk_MAX_ORDER_LPC >> 1 ];
|
||||||
|
|
||||||
|
/* combine two A_Q12 values and ensure 32-bit alignment */
|
||||||
|
for( k = 0; k < Order_half; k++ ) {
|
||||||
|
idx = SKP_SMULBB( 2, k );
|
||||||
|
A_align_Q12[ k ] = ( ( ( SKP_int32 )A_Q12[ idx ] ) & 0x0000ffff ) | SKP_LSHIFT( ( SKP_int32 )A_Q12[ idx + 1 ], 16 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Order must be even */
|
||||||
|
SKP_assert( 2 * Order_half == Order );
|
||||||
|
|
||||||
|
/* S[] values are in Q14 */
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
SA = S[ Order - 1 ];
|
||||||
|
out32_Q10 = 0;
|
||||||
|
for( j = 0; j < ( Order_half - 1 ); j++ ) {
|
||||||
|
idx = SKP_SMULBB( 2, j ) + 1;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* multiply-add two prediction coefficients for each loop */
|
||||||
|
/* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
|
||||||
|
/* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
|
||||||
|
/* loaded in reverse order and the code will give the wrong result. In that case swapping */
|
||||||
|
/* the SMLAWB and SMLAWT instructions should solve the problem. */
|
||||||
|
Atmp = A_align_Q12[ j ];
|
||||||
|
SB = S[ Order - 1 - idx ];
|
||||||
|
S[ Order - 1 - idx ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ Order - 2 - idx ];
|
||||||
|
S[ Order - 2 - idx ] = SB;
|
||||||
|
#else
|
||||||
|
SB = S[ Order - 1 - idx ];
|
||||||
|
S[ Order - 1 - idx ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] );
|
||||||
|
SA = S[ Order - 2 - idx ];
|
||||||
|
S[ Order - 2 - idx ] = SB;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* unrolled loop: epilog */
|
||||||
|
Atmp = A_align_Q12[ Order_half - 1 ];
|
||||||
|
SB = S[ 0 ];
|
||||||
|
S[ 0 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp );
|
||||||
|
#else
|
||||||
|
/* unrolled loop: epilog */
|
||||||
|
SB = S[ 0 ];
|
||||||
|
S[ 0 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] );
|
||||||
|
#endif
|
||||||
|
/* apply gain to excitation signal and add to prediction */
|
||||||
|
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
|
||||||
|
|
||||||
|
/* scale to Q0 */
|
||||||
|
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
|
||||||
|
|
||||||
|
/* saturate output */
|
||||||
|
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
|
||||||
|
|
||||||
|
/* move result into delay line */
|
||||||
|
S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
|
||||||
|
}
|
||||||
|
}
|
216
app/src/main/cpp/src/SKP_Silk_LPC_synthesis_order16.c
Normal file
216
app/src/main/cpp/src/SKP_Silk_LPC_synthesis_order16.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_LPC_synthesis_order16.c *
|
||||||
|
* Coefficients are in Q12 *
|
||||||
|
* *
|
||||||
|
* 16th order AR filter *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* 16th order AR filter */
|
||||||
|
void SKP_Silk_LPC_synthesis_order16(const SKP_int16 *in, /* I: excitation signal */
|
||||||
|
const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
|
||||||
|
const SKP_int32 Gain_Q26, /* I: gain */
|
||||||
|
SKP_int32 *S, /* I/O: state vector [16] */
|
||||||
|
SKP_int16 *out, /* O: output signal */
|
||||||
|
const SKP_int32 len /* I: signal length, must be multiple of 16 */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 SA, SB, out32_Q10, out32;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 Atmp, A_align_Q12[ 8 ];
|
||||||
|
/* combine two A_Q12 values and ensure 32-bit alignment */
|
||||||
|
for( k = 0; k < 8; k++ ) {
|
||||||
|
A_align_Q12[ k ] = ( ( ( SKP_int32 )A_Q12[ 2 * k ] ) & 0x0000ffff ) | SKP_LSHIFT( ( SKP_int32 )A_Q12[ 2 * k + 1 ], 16 );
|
||||||
|
}
|
||||||
|
/* S[] values are in Q14 */
|
||||||
|
/* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
|
||||||
|
/* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
|
||||||
|
/* loaded in reverse order and the code will give the wrong result. In that case swapping */
|
||||||
|
/* the SMLAWB and SMLAWT instructions should solve the problem. */
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
/* unrolled loop: prolog */
|
||||||
|
/* multiply-add two prediction coefficients per iteration */
|
||||||
|
SA = S[ 15 ];
|
||||||
|
Atmp = A_align_Q12[ 0 ];
|
||||||
|
SB = S[ 14 ];
|
||||||
|
S[ 14 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMULWB( SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 13 ];
|
||||||
|
S[ 13 ] = SB;
|
||||||
|
|
||||||
|
/* unrolled loop: main loop */
|
||||||
|
Atmp = A_align_Q12[ 1 ];
|
||||||
|
SB = S[ 12 ];
|
||||||
|
S[ 12 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 11 ];
|
||||||
|
S[ 11 ] = SB;
|
||||||
|
|
||||||
|
Atmp = A_align_Q12[ 2 ];
|
||||||
|
SB = S[ 10 ];
|
||||||
|
S[ 10 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 9 ];
|
||||||
|
S[ 9 ] = SB;
|
||||||
|
|
||||||
|
Atmp = A_align_Q12[ 3 ];
|
||||||
|
SB = S[ 8 ];
|
||||||
|
S[ 8 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 7 ];
|
||||||
|
S[ 7 ] = SB;
|
||||||
|
|
||||||
|
Atmp = A_align_Q12[ 4 ];
|
||||||
|
SB = S[ 6 ];
|
||||||
|
S[ 6 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 5 ];
|
||||||
|
S[ 5 ] = SB;
|
||||||
|
|
||||||
|
Atmp = A_align_Q12[ 5 ];
|
||||||
|
SB = S[ 4 ];
|
||||||
|
S[ 4 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 3 ];
|
||||||
|
S[ 3 ] = SB;
|
||||||
|
|
||||||
|
Atmp = A_align_Q12[ 6 ];
|
||||||
|
SB = S[ 2 ];
|
||||||
|
S[ 2 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
SA = S[ 1 ];
|
||||||
|
S[ 1 ] = SB;
|
||||||
|
|
||||||
|
/* unrolled loop: epilog */
|
||||||
|
Atmp = A_align_Q12[ 7 ];
|
||||||
|
SB = S[ 0 ];
|
||||||
|
S[ 0 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
|
||||||
|
out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
|
||||||
|
|
||||||
|
/* unrolled loop: end */
|
||||||
|
/* apply gain to excitation signal and add to prediction */
|
||||||
|
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
|
||||||
|
|
||||||
|
/* scale to Q0 */
|
||||||
|
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
|
||||||
|
|
||||||
|
/* saturate output */
|
||||||
|
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
|
||||||
|
|
||||||
|
/* move result into delay line */
|
||||||
|
S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
/* unrolled loop: prolog */
|
||||||
|
/* multiply-add two prediction coefficients per iteration */
|
||||||
|
SA = S[ 15 ];
|
||||||
|
SB = S[ 14 ];
|
||||||
|
S[ 14 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMULWB( SA, A_Q12[ 0 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] );
|
||||||
|
SA = S[ 13 ];
|
||||||
|
S[ 13 ] = SB;
|
||||||
|
|
||||||
|
/* unrolled loop: main loop */
|
||||||
|
SB = S[ 12 ];
|
||||||
|
S[ 12 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] );
|
||||||
|
SA = S[ 11 ];
|
||||||
|
S[ 11 ] = SB;
|
||||||
|
|
||||||
|
SB = S[ 10 ];
|
||||||
|
S[ 10 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] );
|
||||||
|
SA = S[ 9 ];
|
||||||
|
S[ 9 ] = SB;
|
||||||
|
|
||||||
|
SB = S[ 8 ];
|
||||||
|
S[ 8 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] );
|
||||||
|
SA = S[ 7 ];
|
||||||
|
S[ 7 ] = SB;
|
||||||
|
|
||||||
|
SB = S[ 6 ];
|
||||||
|
S[ 6 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] );
|
||||||
|
SA = S[ 5 ];
|
||||||
|
S[ 5 ] = SB;
|
||||||
|
|
||||||
|
SB = S[ 4 ];
|
||||||
|
S[ 4 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] );
|
||||||
|
SA = S[ 3 ];
|
||||||
|
S[ 3 ] = SB;
|
||||||
|
|
||||||
|
SB = S[ 2 ];
|
||||||
|
S[ 2 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] );
|
||||||
|
SA = S[ 1 ];
|
||||||
|
S[ 1 ] = SB;
|
||||||
|
|
||||||
|
/* unrolled loop: epilog */
|
||||||
|
SB = S[ 0 ];
|
||||||
|
S[ 0 ] = SA;
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] );
|
||||||
|
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] );
|
||||||
|
|
||||||
|
/* unrolled loop: end */
|
||||||
|
/* apply gain to excitation signal and add to prediction */
|
||||||
|
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
|
||||||
|
|
||||||
|
/* scale to Q0 */
|
||||||
|
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
|
||||||
|
|
||||||
|
/* saturate output */
|
||||||
|
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
|
||||||
|
|
||||||
|
/* move result into delay line */
|
||||||
|
S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
194
app/src/main/cpp/src/SKP_Silk_LP_variable_cutoff.c
Normal file
194
app/src/main/cpp/src/SKP_Silk_LP_variable_cutoff.c
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Elliptic/Cauer filters designed with 0.1 dB passband ripple,
|
||||||
|
80 dB minimum stopband attenuation, and
|
||||||
|
[0.95 : 0.15 : 0.35] normalized cut off frequencies.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
|
||||||
|
/* Helper function, that interpolates the filter taps */
|
||||||
|
SKP_INLINE void SKP_Silk_LP_interpolate_filter_taps(
|
||||||
|
SKP_int32 B_Q28[ TRANSITION_NB ],
|
||||||
|
SKP_int32 A_Q28[ TRANSITION_NA ],
|
||||||
|
const SKP_int ind,
|
||||||
|
const SKP_int32 fac_Q16
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int nb, na;
|
||||||
|
|
||||||
|
if( ind < TRANSITION_INT_NUM - 1 ) {
|
||||||
|
if( fac_Q16 > 0 ) {
|
||||||
|
if( fac_Q16 == SKP_SAT16( fac_Q16 ) ) { /* fac_Q16 is in range of a 16-bit int */
|
||||||
|
/* Piece-wise linear interpolation of B and A */
|
||||||
|
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
|
||||||
|
B_Q28[ nb ] = SKP_SMLAWB(
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ],
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ],
|
||||||
|
fac_Q16 );
|
||||||
|
}
|
||||||
|
for( na = 0; na < TRANSITION_NA; na++ ) {
|
||||||
|
A_Q28[ na ] = SKP_SMLAWB(
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ],
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ],
|
||||||
|
fac_Q16 );
|
||||||
|
}
|
||||||
|
} else if( fac_Q16 == ( 1 << 15 ) ) { /* Neither fac_Q16 nor ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */
|
||||||
|
|
||||||
|
/* Piece-wise linear interpolation of B and A */
|
||||||
|
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
|
||||||
|
B_Q28[ nb ] = SKP_RSHIFT(
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] +
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
|
||||||
|
1 );
|
||||||
|
}
|
||||||
|
for( na = 0; na < TRANSITION_NA; na++ ) {
|
||||||
|
A_Q28[ na ] = SKP_RSHIFT(
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] +
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
|
||||||
|
1 );
|
||||||
|
}
|
||||||
|
} else { /* ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */
|
||||||
|
|
||||||
|
SKP_assert( ( ( 1 << 16 ) - fac_Q16 ) == SKP_SAT16( ( ( 1 << 16 ) - fac_Q16) ) );
|
||||||
|
/* Piece-wise linear interpolation of B and A */
|
||||||
|
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
|
||||||
|
B_Q28[ nb ] = SKP_SMLAWB(
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] -
|
||||||
|
SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
|
||||||
|
( 1 << 16 ) - fac_Q16 );
|
||||||
|
}
|
||||||
|
for( na = 0; na < TRANSITION_NA; na++ ) {
|
||||||
|
A_Q28[ na ] = SKP_SMLAWB(
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] -
|
||||||
|
SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
|
||||||
|
( 1 << 16 ) - fac_Q16 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( SKP_int32 ) );
|
||||||
|
SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( SKP_int32 ) );
|
||||||
|
SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Low-pass filter with variable cutoff frequency based on */
|
||||||
|
/* piece-wise linear interpolation between elliptic filters */
|
||||||
|
/* Start by setting psEncC->transition_frame_no = 1; */
|
||||||
|
/* Deactivate by setting psEncC->transition_frame_no = 0; */
|
||||||
|
void SKP_Silk_LP_variable_cutoff(
|
||||||
|
SKP_Silk_LP_state *psLP, /* I/O LP filter state */
|
||||||
|
SKP_int16 *out, /* O Low-pass filtered output signal */
|
||||||
|
const SKP_int16 *in, /* I Input signal */
|
||||||
|
const SKP_int frame_length /* I Frame length */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
|
||||||
|
SKP_int ind = 0;
|
||||||
|
|
||||||
|
SKP_assert( psLP->transition_frame_no >= 0 );
|
||||||
|
SKP_assert( ( ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_DOWN ) && ( psLP->mode == 0 ) ) ||
|
||||||
|
( ( psLP->transition_frame_no <= TRANSITION_FRAMES_UP ) && ( psLP->mode == 1 ) ) ) );
|
||||||
|
|
||||||
|
/* Interpolate filter coefficients if needed */
|
||||||
|
if( psLP->transition_frame_no > 0 ) {
|
||||||
|
if( psLP->mode == 0 ) {
|
||||||
|
if( psLP->transition_frame_no < TRANSITION_FRAMES_DOWN ) {
|
||||||
|
/* Calculate index and interpolation factor for interpolation */
|
||||||
|
#if( TRANSITION_INT_STEPS_DOWN == 32 )
|
||||||
|
fac_Q16 = SKP_LSHIFT( psLP->transition_frame_no, 16 - 5 );
|
||||||
|
#else
|
||||||
|
fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_DOWN );
|
||||||
|
#endif
|
||||||
|
ind = SKP_RSHIFT( fac_Q16, 16 );
|
||||||
|
fac_Q16 -= SKP_LSHIFT( ind, 16 );
|
||||||
|
|
||||||
|
SKP_assert( ind >= 0 );
|
||||||
|
SKP_assert( ind < TRANSITION_INT_NUM );
|
||||||
|
|
||||||
|
/* Interpolate filter coefficients */
|
||||||
|
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
|
||||||
|
|
||||||
|
/* Increment transition frame number for next frame */
|
||||||
|
psLP->transition_frame_no++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_DOWN );
|
||||||
|
/* End of transition phase */
|
||||||
|
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, TRANSITION_INT_NUM - 1, 0 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_assert( psLP->mode == 1 );
|
||||||
|
if( psLP->transition_frame_no < TRANSITION_FRAMES_UP ) {
|
||||||
|
/* Calculate index and interpolation factor for interpolation */
|
||||||
|
#if( TRANSITION_INT_STEPS_UP == 64 )
|
||||||
|
fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 - 6 );
|
||||||
|
#else
|
||||||
|
fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_UP );
|
||||||
|
#endif
|
||||||
|
ind = SKP_RSHIFT( fac_Q16, 16 );
|
||||||
|
fac_Q16 -= SKP_LSHIFT( ind, 16 );
|
||||||
|
|
||||||
|
SKP_assert( ind >= 0 );
|
||||||
|
SKP_assert( ind < TRANSITION_INT_NUM );
|
||||||
|
|
||||||
|
/* Interpolate filter coefficients */
|
||||||
|
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
|
||||||
|
|
||||||
|
/* Increment transition frame number for next frame */
|
||||||
|
psLP->transition_frame_no++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_UP );
|
||||||
|
/* End of transition phase */
|
||||||
|
SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, 0, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( psLP->transition_frame_no > 0 ) {
|
||||||
|
/* ARMA low-pass filtering */
|
||||||
|
SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
|
||||||
|
SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psLP->In_LP_State, out, frame_length );
|
||||||
|
} else {
|
||||||
|
/* Instead of using the filter, copy input directly to output */
|
||||||
|
SKP_memcpy( out, in, frame_length * sizeof( SKP_int16 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
65
app/src/main/cpp/src/SKP_Silk_LSF_cos_table.c
Normal file
65
app/src/main/cpp/src/SKP_Silk_LSF_cos_table.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
// Q12 values (even)
|
||||||
|
const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[LSF_COS_TAB_SZ_FIX + 1] = {
|
||||||
|
8192, 8190, 8182, 8170,
|
||||||
|
8152, 8130, 8104, 8072,
|
||||||
|
8034, 7994, 7946, 7896,
|
||||||
|
7840, 7778, 7714, 7644,
|
||||||
|
7568, 7490, 7406, 7318,
|
||||||
|
7226, 7128, 7026, 6922,
|
||||||
|
6812, 6698, 6580, 6458,
|
||||||
|
6332, 6204, 6070, 5934,
|
||||||
|
5792, 5648, 5502, 5352,
|
||||||
|
5198, 5040, 4880, 4718,
|
||||||
|
4552, 4382, 4212, 4038,
|
||||||
|
3862, 3684, 3502, 3320,
|
||||||
|
3136, 2948, 2760, 2570,
|
||||||
|
2378, 2186, 1990, 1794,
|
||||||
|
1598, 1400, 1202, 1002,
|
||||||
|
802, 602, 402, 202,
|
||||||
|
0, -202, -402, -602,
|
||||||
|
-802, -1002, -1202, -1400,
|
||||||
|
-1598, -1794, -1990, -2186,
|
||||||
|
-2378, -2570, -2760, -2948,
|
||||||
|
-3136, -3320, -3502, -3684,
|
||||||
|
-3862, -4038, -4212, -4382,
|
||||||
|
-4552, -4718, -4880, -5040,
|
||||||
|
-5198, -5352, -5502, -5648,
|
||||||
|
-5792, -5934, -6070, -6204,
|
||||||
|
-6332, -6458, -6580, -6698,
|
||||||
|
-6812, -6922, -7026, -7128,
|
||||||
|
-7226, -7318, -7406, -7490,
|
||||||
|
-7568, -7644, -7714, -7778,
|
||||||
|
-7840, -7896, -7946, -7994,
|
||||||
|
-8034, -8072, -8104, -8130,
|
||||||
|
-8152, -8170, -8182, -8190,
|
||||||
|
-8192
|
||||||
|
};
|
80
app/src/main/cpp/src/SKP_Silk_LTP_analysis_filter_FIX.c
Normal file
80
app/src/main/cpp/src/SKP_Silk_LTP_analysis_filter_FIX.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
void SKP_Silk_LTP_analysis_filter_FIX(
|
||||||
|
SKP_int16 *LTP_res, /* O: LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length ) */
|
||||||
|
const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */
|
||||||
|
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each NB_SUBFR subframe */
|
||||||
|
const SKP_int pitchL[ NB_SUBFR ], /* I: Pitch lag, one for each subframe */
|
||||||
|
const SKP_int32 invGains_Q16[ NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */
|
||||||
|
const SKP_int subfr_length, /* I: Length of each subframe */
|
||||||
|
const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const SKP_int16 *x_ptr, *x_lag_ptr;
|
||||||
|
SKP_int16 Btmp_Q14[ LTP_ORDER ];
|
||||||
|
SKP_int16 *LTP_res_ptr;
|
||||||
|
SKP_int k, i, j;
|
||||||
|
SKP_int32 LTP_est;
|
||||||
|
|
||||||
|
x_ptr = x;
|
||||||
|
LTP_res_ptr = LTP_res;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
|
||||||
|
x_lag_ptr = x_ptr - pitchL[ k ];
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LTP analysis FIR filter */
|
||||||
|
for( i = 0; i < subfr_length + pre_length; i++ ) {
|
||||||
|
LTP_res_ptr[ i ] = x_ptr[ i ];
|
||||||
|
|
||||||
|
/* Long-term prediction */
|
||||||
|
LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
|
||||||
|
for( j = 1; j < LTP_ORDER; j++ ) {
|
||||||
|
LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] );
|
||||||
|
}
|
||||||
|
LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0
|
||||||
|
|
||||||
|
/* Subtract long-term prediction */
|
||||||
|
LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est );
|
||||||
|
|
||||||
|
/* Scale residual */
|
||||||
|
LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
|
||||||
|
|
||||||
|
x_lag_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update pointers */
|
||||||
|
LTP_res_ptr += subfr_length + pre_length;
|
||||||
|
x_ptr += subfr_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
81
app/src/main/cpp/src/SKP_Silk_LTP_scale_ctrl_FIX.c
Normal file
81
app/src/main/cpp/src/SKP_Silk_LTP_scale_ctrl_FIX.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
#define NB_THRESHOLDS 11
|
||||||
|
|
||||||
|
/* Table containing trained thresholds for LTP scaling */
|
||||||
|
static const SKP_int16 LTPScaleThresholds_Q15[ NB_THRESHOLDS ] =
|
||||||
|
{
|
||||||
|
31129, 26214, 16384, 13107, 9830, 6554,
|
||||||
|
4915, 3276, 2621, 2458, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
void SKP_Silk_LTP_scale_ctrl_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state FIX */
|
||||||
|
SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control FIX */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int round_loss, frames_per_packet;
|
||||||
|
SKP_int g_out_Q5, g_limit_Q15, thrld1_Q15, thrld2_Q15;
|
||||||
|
|
||||||
|
/* 1st order high-pass filter */
|
||||||
|
psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - psEnc->prevLTPredCodGain_Q7, 0 )
|
||||||
|
+ SKP_RSHIFT_ROUND( psEnc->HPLTPredCodGain_Q7, 1 );
|
||||||
|
|
||||||
|
psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;
|
||||||
|
|
||||||
|
/* combine input and filtered input */
|
||||||
|
g_out_Q5 = SKP_RSHIFT_ROUND( SKP_RSHIFT( psEncCtrl->LTPredCodGain_Q7, 1 ) + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ), 3 );
|
||||||
|
g_limit_Q15 = SKP_Silk_sigm_Q15( g_out_Q5 - ( 3 << 5 ) );
|
||||||
|
|
||||||
|
/* Default is minimum scaling */
|
||||||
|
psEncCtrl->sCmn.LTP_scaleIndex = 0;
|
||||||
|
|
||||||
|
/* Round the loss measure to whole pct */
|
||||||
|
round_loss = ( SKP_int )psEnc->sCmn.PacketLoss_perc;
|
||||||
|
|
||||||
|
/* Only scale if first frame in packet 0% */
|
||||||
|
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
|
||||||
|
|
||||||
|
frames_per_packet = SKP_DIV32_16( psEnc->sCmn.PacketSize_ms, FRAME_LENGTH_MS );
|
||||||
|
|
||||||
|
round_loss += frames_per_packet - 1;
|
||||||
|
thrld1_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss, NB_THRESHOLDS - 1 ) ];
|
||||||
|
thrld2_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss + 1, NB_THRESHOLDS - 1 ) ];
|
||||||
|
|
||||||
|
if( g_limit_Q15 > thrld1_Q15 ) {
|
||||||
|
/* Maximum scaling */
|
||||||
|
psEncCtrl->sCmn.LTP_scaleIndex = 2;
|
||||||
|
} else if( g_limit_Q15 > thrld2_Q15 ) {
|
||||||
|
/* Medium scaling */
|
||||||
|
psEncCtrl->sCmn.LTP_scaleIndex = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ];
|
||||||
|
}
|
120
app/src/main/cpp/src/SKP_Silk_MA.c
Normal file
120
app/src/main/cpp/src/SKP_Silk_MA.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_MA.c *
|
||||||
|
* *
|
||||||
|
* Variable order MA filter *
|
||||||
|
* *
|
||||||
|
* Copyright 2006 (c), Skype Limited *
|
||||||
|
* Date: 060221 *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM<5
|
||||||
|
/* Variable order MA prediction error filter */
|
||||||
|
void SKP_Silk_MA_Prediction(
|
||||||
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
|
||||||
|
SKP_int32 *S, /* I/O: State vector [order] */
|
||||||
|
SKP_int16 *out, /* O: Output signal */
|
||||||
|
const SKP_int32 len, /* I: Signal length */
|
||||||
|
const SKP_int32 order /* I: Filter order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, d, in16;
|
||||||
|
SKP_int32 out32;
|
||||||
|
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
in16 = in[ k ];
|
||||||
|
out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
|
||||||
|
out32 = SKP_RSHIFT_ROUND( out32, 12 );
|
||||||
|
|
||||||
|
for( d = 0; d < order - 1; d++ ) {
|
||||||
|
S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
|
||||||
|
}
|
||||||
|
S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );
|
||||||
|
|
||||||
|
/* Limit */
|
||||||
|
out[ k ] = (SKP_int16)SKP_SAT16( out32 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM<5
|
||||||
|
|
||||||
|
void SKP_Silk_LPC_analysis_filter(
|
||||||
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
|
||||||
|
SKP_int16 *S, /* I/O: State vector [order] */
|
||||||
|
SKP_int16 *out, /* O: Output signal */
|
||||||
|
const SKP_int32 len, /* I: Signal length */
|
||||||
|
const SKP_int32 Order /* I: Filter order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
|
||||||
|
SKP_int32 out32_Q12, out32;
|
||||||
|
SKP_int16 SA, SB;
|
||||||
|
/* Order must be even */
|
||||||
|
SKP_assert( 2 * Order_half == Order );
|
||||||
|
|
||||||
|
/* S[] values are in Q0 */
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
SA = S[ 0 ];
|
||||||
|
out32_Q12 = 0;
|
||||||
|
for( j = 0; j < ( Order_half - 1 ); j++ ) {
|
||||||
|
idx = SKP_SMULBB( 2, j ) + 1;
|
||||||
|
/* Multiply-add two prediction coefficients for each loop */
|
||||||
|
SB = S[ idx ];
|
||||||
|
S[ idx ] = SA;
|
||||||
|
out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ idx - 1 ] );
|
||||||
|
out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ idx ] );
|
||||||
|
SA = S[ idx + 1 ];
|
||||||
|
S[ idx + 1 ] = SB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unrolled loop: epilog */
|
||||||
|
SB = S[ Order - 1 ];
|
||||||
|
S[ Order - 1 ] = SA;
|
||||||
|
out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ Order - 2 ] );
|
||||||
|
out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ Order - 1 ] );
|
||||||
|
|
||||||
|
/* Subtract prediction */
|
||||||
|
out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 );
|
||||||
|
|
||||||
|
/* Scale to Q0 */
|
||||||
|
out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );
|
||||||
|
|
||||||
|
/* Saturate output */
|
||||||
|
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
|
||||||
|
|
||||||
|
/* Move input line */
|
||||||
|
S[ 0 ] = in[ k ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
1486
app/src/main/cpp/src/SKP_Silk_MA_arm.S
Normal file
1486
app/src/main/cpp/src/SKP_Silk_MA_arm.S
Normal file
File diff suppressed because it is too large
Load Diff
151
app/src/main/cpp/src/SKP_Silk_NLSF2A.c
Normal file
151
app/src/main/cpp/src/SKP_Silk_NLSF2A.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* conversion between prediction filter coefficients and LSFs */
|
||||||
|
/* order should be even */
|
||||||
|
/* a piecewise linear approximation maps LSF <-> cos(LSF) */
|
||||||
|
/* therefore the result is not accurate LSFs, but the two */
|
||||||
|
/* function are accurate inverses of each other */
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* helper function for NLSF2A(..) */
|
||||||
|
SKP_INLINE void SKP_Silk_NLSF2A_find_poly(
|
||||||
|
SKP_int32 *out, /* o intermediate polynomial, Q20 */
|
||||||
|
const SKP_int32 *cLSF, /* i vector of interleaved 2*cos(LSFs), Q20 */
|
||||||
|
SKP_int dd /* i polynomial order (= 1/2 * filter order) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, n;
|
||||||
|
SKP_int32 ftmp;
|
||||||
|
|
||||||
|
out[0] = SKP_LSHIFT( 1, 20 );
|
||||||
|
out[1] = -cLSF[0];
|
||||||
|
for( k = 1; k < dd; k++ ) {
|
||||||
|
ftmp = cLSF[2*k]; // Q20
|
||||||
|
out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 );
|
||||||
|
for( n = k; n > 1; n-- ) {
|
||||||
|
out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 );
|
||||||
|
}
|
||||||
|
out[1] -= ftmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
||||||
|
void SKP_Silk_NLSF2A(
|
||||||
|
SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
|
||||||
|
const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
|
||||||
|
const SKP_int d /* i filter order (should be even) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, i, dd;
|
||||||
|
SKP_int32 cos_LSF_Q20[SKP_Silk_MAX_ORDER_LPC];
|
||||||
|
SKP_int32 P[SKP_Silk_MAX_ORDER_LPC/2+1], Q[SKP_Silk_MAX_ORDER_LPC/2+1];
|
||||||
|
SKP_int32 Ptmp, Qtmp;
|
||||||
|
SKP_int32 f_int;
|
||||||
|
SKP_int32 f_frac;
|
||||||
|
SKP_int32 cos_val, delta;
|
||||||
|
SKP_int32 a_int32[SKP_Silk_MAX_ORDER_LPC];
|
||||||
|
SKP_int32 maxabs, absval, idx=0, sc_Q16;
|
||||||
|
|
||||||
|
SKP_assert(LSF_COS_TAB_SZ_FIX == 128);
|
||||||
|
|
||||||
|
/* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */
|
||||||
|
for( k = 0; k < d; k++ ) {
|
||||||
|
SKP_assert(NLSF[k] >= 0 );
|
||||||
|
SKP_assert(NLSF[k] <= 32767 );
|
||||||
|
|
||||||
|
/* f_int on a scale 0-127 (rounded down) */
|
||||||
|
f_int = SKP_RSHIFT( NLSF[k], 15 - 7 );
|
||||||
|
|
||||||
|
/* f_frac, range: 0..255 */
|
||||||
|
f_frac = NLSF[k] - SKP_LSHIFT( f_int, 15 - 7 );
|
||||||
|
|
||||||
|
SKP_assert(f_int >= 0);
|
||||||
|
SKP_assert(f_int < LSF_COS_TAB_SZ_FIX );
|
||||||
|
|
||||||
|
/* Read start and end value from table */
|
||||||
|
cos_val = SKP_Silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */
|
||||||
|
delta = SKP_Silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */
|
||||||
|
|
||||||
|
/* Linear interpolation */
|
||||||
|
cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */
|
||||||
|
}
|
||||||
|
|
||||||
|
dd = SKP_RSHIFT( d, 1 );
|
||||||
|
|
||||||
|
/* generate even and odd polynomials using convolution */
|
||||||
|
SKP_Silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd );
|
||||||
|
SKP_Silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd );
|
||||||
|
|
||||||
|
/* convert even and odd polynomials to SKP_int32 Q12 filter coefs */
|
||||||
|
for( k = 0; k < dd; k++ ) {
|
||||||
|
Ptmp = P[k+1] + P[k];
|
||||||
|
Qtmp = Q[k+1] - Q[k];
|
||||||
|
|
||||||
|
/* the Ptmp and Qtmp values at this stage need to fit in int32 */
|
||||||
|
|
||||||
|
a_int32[k] = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */
|
||||||
|
a_int32[d-k-1] = SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Limit the maximum absolute value of the prediction coefficients */
|
||||||
|
for( i = 0; i < 10; i++ ) {
|
||||||
|
/* Find maximum absolute value and its index */
|
||||||
|
maxabs = 0;
|
||||||
|
for( k = 0; k < d; k++ ) {
|
||||||
|
absval = SKP_abs( a_int32[k] );
|
||||||
|
if( absval > maxabs ) {
|
||||||
|
maxabs = absval;
|
||||||
|
idx = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( maxabs > SKP_int16_MAX ) {
|
||||||
|
/* Reduce magnitude of prediction coefficients */
|
||||||
|
maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369
|
||||||
|
sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ),
|
||||||
|
SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );
|
||||||
|
SKP_Silk_bwexpander_32( a_int32, d, sc_Q16 );
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reached the last iteration */
|
||||||
|
if( i == 10 ) {
|
||||||
|
SKP_assert(0);
|
||||||
|
for( k = 0; k < d; k++ ) {
|
||||||
|
a_int32[k] = SKP_SAT16( a_int32[k] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return as SKP_int16 Q12 coefficients */
|
||||||
|
for( k = 0; k < d; k++ ) {
|
||||||
|
a[k] = (SKP_int16)a_int32[k];
|
||||||
|
}
|
||||||
|
}
|
58
app/src/main/cpp/src/SKP_Silk_NLSF2A_stable.c
Normal file
58
app/src/main/cpp/src/SKP_Silk_NLSF2A_stable.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* Convert NLSF parameters to stable AR prediction filter coefficients */
|
||||||
|
void SKP_Silk_NLSF2A_stable(
|
||||||
|
SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
|
||||||
|
const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
|
||||||
|
const SKP_int LPC_order /* I LPC/LSF order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int32 invGain_Q30;
|
||||||
|
|
||||||
|
SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );
|
||||||
|
|
||||||
|
/* Ensure stable LPCs */
|
||||||
|
for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
|
||||||
|
if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {
|
||||||
|
SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015 */
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reached the last iteration */
|
||||||
|
if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
for( i = 0; i < LPC_order; i++ ) {
|
||||||
|
pAR_Q12[ i ] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
app/src/main/cpp/src/SKP_Silk_NLSF_MSVQ_decode.c
Normal file
91
app/src/main/cpp/src/SKP_Silk_NLSF_MSVQ_decode.c
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* NLSF vector decoder */
|
||||||
|
void SKP_Silk_NLSF_MSVQ_decode(
|
||||||
|
SKP_int *pNLSF_Q15, /* O Pointer to decoded output vector [LPC_ORDER x 1] */
|
||||||
|
const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */
|
||||||
|
const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */
|
||||||
|
const SKP_int LPC_order /* I LPC order used */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const SKP_int16 *pCB_element;
|
||||||
|
SKP_int s;
|
||||||
|
SKP_int i;
|
||||||
|
|
||||||
|
/* Check that each index is within valid range */
|
||||||
|
SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB->CBStages[ 0 ].nVectors );
|
||||||
|
|
||||||
|
/* Point to the first vector element */
|
||||||
|
pCB_element = &psNLSF_CB->CBStages[ 0 ].CB_NLSF_Q15[ SKP_MUL( NLSFIndices[ 0 ], LPC_order ) ];
|
||||||
|
|
||||||
|
/* Initialize with the codebook vector from stage 0 */
|
||||||
|
for( i = 0; i < LPC_order; i++ ) {
|
||||||
|
pNLSF_Q15[ i ] = ( SKP_int )pCB_element[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
for( s = 1; s < psNLSF_CB->nStages; s++ ) {
|
||||||
|
/* Check that each index is within valid range */
|
||||||
|
SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB->CBStages[ s ].nVectors );
|
||||||
|
|
||||||
|
if( LPC_order == 16 ) {
|
||||||
|
/* Point to the first vector element */
|
||||||
|
pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_LSHIFT( NLSFIndices[ s ], 4 ) ];
|
||||||
|
|
||||||
|
/* Add the codebook vector from the current stage */
|
||||||
|
pNLSF_Q15[ 0 ] += pCB_element[ 0 ];
|
||||||
|
pNLSF_Q15[ 1 ] += pCB_element[ 1 ];
|
||||||
|
pNLSF_Q15[ 2 ] += pCB_element[ 2 ];
|
||||||
|
pNLSF_Q15[ 3 ] += pCB_element[ 3 ];
|
||||||
|
pNLSF_Q15[ 4 ] += pCB_element[ 4 ];
|
||||||
|
pNLSF_Q15[ 5 ] += pCB_element[ 5 ];
|
||||||
|
pNLSF_Q15[ 6 ] += pCB_element[ 6 ];
|
||||||
|
pNLSF_Q15[ 7 ] += pCB_element[ 7 ];
|
||||||
|
pNLSF_Q15[ 8 ] += pCB_element[ 8 ];
|
||||||
|
pNLSF_Q15[ 9 ] += pCB_element[ 9 ];
|
||||||
|
pNLSF_Q15[ 10 ] += pCB_element[ 10 ];
|
||||||
|
pNLSF_Q15[ 11 ] += pCB_element[ 11 ];
|
||||||
|
pNLSF_Q15[ 12 ] += pCB_element[ 12 ];
|
||||||
|
pNLSF_Q15[ 13 ] += pCB_element[ 13 ];
|
||||||
|
pNLSF_Q15[ 14 ] += pCB_element[ 14 ];
|
||||||
|
pNLSF_Q15[ 15 ] += pCB_element[ 15 ];
|
||||||
|
} else {
|
||||||
|
/* Point to the first vector element */
|
||||||
|
pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_SMULBB( NLSFIndices[ s ], LPC_order ) ];
|
||||||
|
|
||||||
|
/* Add the codebook vector from the current stage */
|
||||||
|
for( i = 0; i < LPC_order; i++ ) {
|
||||||
|
pNLSF_Q15[ i ] += pCB_element[ i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NLSF stabilization */
|
||||||
|
SKP_Silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->NDeltaMin_Q15, LPC_order );
|
||||||
|
}
|
239
app/src/main/cpp/src/SKP_Silk_NLSF_MSVQ_encode_FIX.c
Normal file
239
app/src/main/cpp/src/SKP_Silk_NLSF_MSVQ_encode_FIX.c
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* NLSF vector encoder */
|
||||||
|
/***********************/
|
||||||
|
void SKP_Silk_NLSF_MSVQ_encode_FIX(
|
||||||
|
SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */
|
||||||
|
SKP_int *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
|
||||||
|
const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
||||||
|
const SKP_int *pNLSF_q_Q15_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */
|
||||||
|
const SKP_int *pW_Q6, /* I NLSF weight vector [ LPC_ORDER ] */
|
||||||
|
const SKP_int NLSF_mu_Q15, /* I Rate weight for the RD optimization */
|
||||||
|
const SKP_int NLSF_mu_fluc_red_Q16, /* I Fluctuation reduction error weight */
|
||||||
|
const SKP_int NLSF_MSVQ_Survivors, /* I Max survivors from each stage */
|
||||||
|
const SKP_int LPC_order, /* I LPC order */
|
||||||
|
const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, s, k, cur_survivors = 0, prev_survivors, min_survivors, input_index, cb_index, bestIndex;
|
||||||
|
SKP_int32 rateDistThreshold_Q18;
|
||||||
|
#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )
|
||||||
|
SKP_int32 se_Q15, wsse_Q20, bestRateDist_Q20;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( LOW_COMPLEXITY_ONLY == 1 )
|
||||||
|
SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE ];
|
||||||
|
SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
|
||||||
|
SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
|
||||||
|
SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
|
||||||
|
SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];
|
||||||
|
SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];
|
||||||
|
SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];
|
||||||
|
SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];
|
||||||
|
#else
|
||||||
|
SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED ];
|
||||||
|
SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS ];
|
||||||
|
SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS ];
|
||||||
|
SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS ];
|
||||||
|
SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];
|
||||||
|
SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];
|
||||||
|
SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];
|
||||||
|
SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const SKP_int *pConstInt;
|
||||||
|
SKP_int *pInt;
|
||||||
|
const SKP_int16 *pCB_element;
|
||||||
|
const SKP_Silk_NLSF_CBS *pCurrentCBStage;
|
||||||
|
|
||||||
|
#ifdef USE_UNQUANTIZED_LSFS
|
||||||
|
SKP_int NLSF_orig[ MAX_LPC_ORDER ];
|
||||||
|
SKP_memcpy( NLSF_orig, pNLSF_Q15, LPC_order * sizeof( SKP_int ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SKP_assert( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS );
|
||||||
|
SKP_assert( ( LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) );
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************/
|
||||||
|
/* Tree search for the multi-stage vector quantizer */
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
/* Clear accumulated rates */
|
||||||
|
SKP_memset( pRate_Q5, 0, NLSF_MSVQ_Survivors * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
/* Copy NLSFs into residual signal vector */
|
||||||
|
for( i = 0; i < LPC_order; i++ ) {
|
||||||
|
pRes_Q15[ i ] = pNLSF_Q15[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set first stage values */
|
||||||
|
prev_survivors = 1;
|
||||||
|
|
||||||
|
/* Minimum number of survivors */
|
||||||
|
min_survivors = NLSF_MSVQ_Survivors / 2;
|
||||||
|
|
||||||
|
/* Loop over all stages */
|
||||||
|
for( s = 0; s < psNLSF_CB->nStages; s++ ) {
|
||||||
|
|
||||||
|
/* Set a pointer to the current stage codebook */
|
||||||
|
pCurrentCBStage = &psNLSF_CB->CBStages[ s ];
|
||||||
|
|
||||||
|
/* Calculate the number of survivors in the current stage */
|
||||||
|
cur_survivors = SKP_min_32( NLSF_MSVQ_Survivors, SKP_SMULBB( prev_survivors, pCurrentCBStage->nVectors ) );
|
||||||
|
|
||||||
|
#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 )
|
||||||
|
/* Find a single best survivor in the last stage, if we */
|
||||||
|
/* do not need candidates for fluctuation reduction */
|
||||||
|
if( s == psNLSF_CB->nStages - 1 ) {
|
||||||
|
cur_survivors = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Nearest neighbor clustering for multiple input data vectors */
|
||||||
|
SKP_Silk_NLSF_VQ_rate_distortion_FIX( pRateDist_Q18, pCurrentCBStage, pRes_Q15, pW_Q6,
|
||||||
|
pRate_Q5, NLSF_mu_Q15, prev_survivors, LPC_order );
|
||||||
|
|
||||||
|
/* Sort the rate-distortion errors */
|
||||||
|
SKP_Silk_insertion_sort_increasing( pRateDist_Q18, pTempIndices,
|
||||||
|
prev_survivors * pCurrentCBStage->nVectors, cur_survivors );
|
||||||
|
|
||||||
|
/* Discard survivors with rate-distortion values too far above the best one */
|
||||||
|
if( pRateDist_Q18[ 0 ] < SKP_int32_MAX / MAX_NLSF_MSVQ_SURVIVORS ) {
|
||||||
|
rateDistThreshold_Q18 = SKP_SMLAWB( pRateDist_Q18[ 0 ],
|
||||||
|
SKP_MUL( NLSF_MSVQ_Survivors, pRateDist_Q18[ 0 ] ), SKP_FIX_CONST( NLSF_MSVQ_SURV_MAX_REL_RD, 16 ) );
|
||||||
|
while( pRateDist_Q18[ cur_survivors - 1 ] > rateDistThreshold_Q18 && cur_survivors > min_survivors ) {
|
||||||
|
cur_survivors--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */
|
||||||
|
for( k = 0; k < cur_survivors; k++ ) {
|
||||||
|
if( s > 0 ) {
|
||||||
|
/* Find the indices of the input and the codebook vector */
|
||||||
|
if( pCurrentCBStage->nVectors == 8 ) {
|
||||||
|
input_index = SKP_RSHIFT( pTempIndices[ k ], 3 );
|
||||||
|
cb_index = pTempIndices[ k ] & 7;
|
||||||
|
} else {
|
||||||
|
input_index = SKP_DIV32_16( pTempIndices[ k ], pCurrentCBStage->nVectors );
|
||||||
|
cb_index = pTempIndices[ k ] - SKP_SMULBB( input_index, pCurrentCBStage->nVectors );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Find the indices of the input and the codebook vector */
|
||||||
|
input_index = 0;
|
||||||
|
cb_index = pTempIndices[ k ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */
|
||||||
|
pConstInt = &pRes_Q15[ SKP_SMULBB( input_index, LPC_order ) ];
|
||||||
|
pCB_element = &pCurrentCBStage->CB_NLSF_Q15[ SKP_SMULBB( cb_index, LPC_order ) ];
|
||||||
|
pInt = &pRes_new_Q15[ SKP_SMULBB( k, LPC_order ) ];
|
||||||
|
for( i = 0; i < LPC_order; i++ ) {
|
||||||
|
pInt[ i ] = pConstInt[ i ] - ( SKP_int )pCB_element[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update accumulated rate for stage 1 to the current */
|
||||||
|
pRate_new_Q5[ k ] = pRate_Q5[ input_index ] + pCurrentCBStage->Rates_Q5[ cb_index ];
|
||||||
|
|
||||||
|
/* Copy paths from previous matrix, starting with the best path */
|
||||||
|
pConstInt = &pPath[ SKP_SMULBB( input_index, psNLSF_CB->nStages ) ];
|
||||||
|
pInt = &pPath_new[ SKP_SMULBB( k, psNLSF_CB->nStages ) ];
|
||||||
|
for( i = 0; i < s; i++ ) {
|
||||||
|
pInt[ i ] = pConstInt[ i ];
|
||||||
|
}
|
||||||
|
/* Write the current stage indices for the 'cur_survivors' to the best path matrix */
|
||||||
|
pInt[ s ] = cb_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( s < psNLSF_CB->nStages - 1 ) {
|
||||||
|
/* Copy NLSF residual matrix for next stage */
|
||||||
|
SKP_memcpy( pRes_Q15, pRes_new_Q15, SKP_SMULBB( cur_survivors, LPC_order ) * sizeof( SKP_int ) );
|
||||||
|
|
||||||
|
/* Copy rate vector for next stage */
|
||||||
|
SKP_memcpy( pRate_Q5, pRate_new_Q5, cur_survivors * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
/* Copy best path matrix for next stage */
|
||||||
|
SKP_memcpy( pPath, pPath_new, SKP_SMULBB( cur_survivors, psNLSF_CB->nStages ) * sizeof( SKP_int ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_survivors = cur_survivors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (Preliminary) index of the best survivor, later to be decoded */
|
||||||
|
bestIndex = 0;
|
||||||
|
|
||||||
|
#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )
|
||||||
|
/******************************/
|
||||||
|
/* NLSF fluctuation reduction */
|
||||||
|
/******************************/
|
||||||
|
if( deactivate_fluc_red != 1 ) {
|
||||||
|
|
||||||
|
/* Search among all survivors, now taking also weighted fluctuation errors into account */
|
||||||
|
bestRateDist_Q20 = SKP_int32_MAX;
|
||||||
|
for( s = 0; s < cur_survivors; s++ ) {
|
||||||
|
/* Decode survivor to compare with previous quantized NLSF vector */
|
||||||
|
SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, &pPath_new[ SKP_SMULBB( s, psNLSF_CB->nStages ) ], LPC_order );
|
||||||
|
|
||||||
|
/* Compare decoded NLSF vector with the previously quantized vector */
|
||||||
|
wsse_Q20 = 0;
|
||||||
|
for( i = 0; i < LPC_order; i += 2 ) {
|
||||||
|
/* Compute weighted squared quantization error for index i */
|
||||||
|
se_Q15 = pNLSF_Q15[ i ] - pNLSF_q_Q15_prev[ i ]; // range: [ -32767 : 32767 ]
|
||||||
|
wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i ] );
|
||||||
|
|
||||||
|
/* Compute weighted squared quantization error for index i + 1 */
|
||||||
|
se_Q15 = pNLSF_Q15[ i + 1 ] - pNLSF_q_Q15_prev[ i + 1 ]; // range: [ -32767 : 32767 ]
|
||||||
|
wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i + 1 ] );
|
||||||
|
}
|
||||||
|
SKP_assert( wsse_Q20 >= 0 );
|
||||||
|
|
||||||
|
/* Add the fluctuation reduction penalty to the rate distortion error */
|
||||||
|
wsse_Q20 = SKP_ADD_POS_SAT32( pRateDist_Q18[ s ], SKP_SMULWB( wsse_Q20, NLSF_mu_fluc_red_Q16 ) );
|
||||||
|
|
||||||
|
/* Keep index of best survivor */
|
||||||
|
if( wsse_Q20 < bestRateDist_Q20 ) {
|
||||||
|
bestRateDist_Q20 = wsse_Q20;
|
||||||
|
bestIndex = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Copy best path to output argument */
|
||||||
|
SKP_memcpy( NLSFIndices, &pPath_new[ SKP_SMULBB( bestIndex, psNLSF_CB->nStages ) ], psNLSF_CB->nStages * sizeof( SKP_int ) );
|
||||||
|
|
||||||
|
/* Decode and stabilize the best survivor */
|
||||||
|
SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, LPC_order );
|
||||||
|
|
||||||
|
#ifdef USE_UNQUANTIZED_LSFS
|
||||||
|
SKP_memcpy( pNLSF_Q15, NLSF_orig, LPC_order * sizeof( SKP_int ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
61
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c
Normal file
61
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
/* Rate-Distortion calculations for multiple input data vectors */
|
||||||
|
void SKP_Silk_NLSF_VQ_rate_distortion_FIX(
|
||||||
|
SKP_int32 *pRD_Q20, /* O Rate-distortion values [psNLSF_CBS->nVectors*N] */
|
||||||
|
const SKP_Silk_NLSF_CBS *psNLSF_CBS, /* I NLSF codebook stage struct */
|
||||||
|
const SKP_int *in_Q15, /* I Input vectors to be quantized */
|
||||||
|
const SKP_int *w_Q6, /* I Weight vector */
|
||||||
|
const SKP_int32 *rate_acc_Q5, /* I Accumulated rates from previous stage */
|
||||||
|
const SKP_int mu_Q15, /* I Weight between weighted error and rate */
|
||||||
|
const SKP_int N, /* I Number of input vectors to be quantized */
|
||||||
|
const SKP_int LPC_order /* I LPC order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, n;
|
||||||
|
SKP_int32 *pRD_vec_Q20;
|
||||||
|
|
||||||
|
/* Compute weighted quantization errors for all input vectors over one codebook stage */
|
||||||
|
SKP_Silk_NLSF_VQ_sum_error_FIX( pRD_Q20, in_Q15, w_Q6, psNLSF_CBS->CB_NLSF_Q15,
|
||||||
|
N, psNLSF_CBS->nVectors, LPC_order );
|
||||||
|
|
||||||
|
/* Loop over input vectors */
|
||||||
|
pRD_vec_Q20 = pRD_Q20;
|
||||||
|
for( n = 0; n < N; n++ ) {
|
||||||
|
/* Add rate cost to error for each codebook vector */
|
||||||
|
for( i = 0; i < psNLSF_CBS->nVectors; i++ ) {
|
||||||
|
SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] >= 0 );
|
||||||
|
SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] <= SKP_int16_MAX );
|
||||||
|
pRD_vec_Q20[ i ] = SKP_SMLABB( pRD_vec_Q20[ i ], rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ], mu_Q15 );
|
||||||
|
SKP_assert( pRD_vec_Q20[ i ] >= 0 );
|
||||||
|
}
|
||||||
|
pRD_vec_Q20 += psNLSF_CBS->nVectors;
|
||||||
|
}
|
||||||
|
}
|
83
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_sum_error_FIX.c
Normal file
83
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_sum_error_FIX.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
#if (!defined(__mips__)) && (EMBEDDED_ARM < 6)
|
||||||
|
|
||||||
|
/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */
|
||||||
|
void SKP_Silk_NLSF_VQ_sum_error_FIX(
|
||||||
|
SKP_int32 *err_Q20, /* O Weighted quantization errors [N*K] */
|
||||||
|
const SKP_int *in_Q15, /* I Input vectors to be quantized [N*LPC_order] */
|
||||||
|
const SKP_int *w_Q6, /* I Weighting vectors [N*LPC_order] */
|
||||||
|
const SKP_int16 *pCB_Q15, /* I Codebook vectors [K*LPC_order] */
|
||||||
|
const SKP_int N, /* I Number of input vectors */
|
||||||
|
const SKP_int K, /* I Number of codebook vectors */
|
||||||
|
const SKP_int LPC_order /* I Number of LPCs */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, n, m;
|
||||||
|
SKP_int32 diff_Q15, sum_error, Wtmp_Q6;
|
||||||
|
SKP_int32 Wcpy_Q6[ MAX_LPC_ORDER / 2 ];
|
||||||
|
const SKP_int16 *cb_vec_Q15;
|
||||||
|
|
||||||
|
SKP_assert( LPC_order <= 16 );
|
||||||
|
SKP_assert( ( LPC_order & 1 ) == 0 );
|
||||||
|
|
||||||
|
/* Copy to local stack and pack two weights per int32 */
|
||||||
|
for( m = 0; m < SKP_RSHIFT( LPC_order, 1 ); m++ ) {
|
||||||
|
Wcpy_Q6[ m ] = w_Q6[ 2 * m ] | SKP_LSHIFT( ( SKP_int32 )w_Q6[ 2 * m + 1 ], 16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop over input vectors */
|
||||||
|
for( n = 0; n < N; n++ ) {
|
||||||
|
/* Loop over codebook */
|
||||||
|
cb_vec_Q15 = pCB_Q15;
|
||||||
|
for( i = 0; i < K; i++ ) {
|
||||||
|
sum_error = 0;
|
||||||
|
for( m = 0; m < LPC_order; m += 2 ) {
|
||||||
|
/* Get two weights packed in an int32 */
|
||||||
|
Wtmp_Q6 = Wcpy_Q6[ SKP_RSHIFT( m, 1 ) ];
|
||||||
|
|
||||||
|
/* Compute weighted squared quantization error for index m */
|
||||||
|
diff_Q15 = in_Q15[ m ] - *cb_vec_Q15++; // range: [ -32767 : 32767 ]
|
||||||
|
sum_error = SKP_SMLAWB( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 );
|
||||||
|
|
||||||
|
/* Compute weighted squared quantization error for index m + 1 */
|
||||||
|
diff_Q15 = in_Q15[m + 1] - *cb_vec_Q15++; // range: [ -32767 : 32767 ]
|
||||||
|
sum_error = SKP_SMLAWT( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 );
|
||||||
|
}
|
||||||
|
SKP_assert( sum_error >= 0 );
|
||||||
|
err_Q20[ i ] = sum_error;
|
||||||
|
}
|
||||||
|
err_Q20 += K;
|
||||||
|
in_Q15 += LPC_order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
161
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_sum_error_FIX_arm.S
Normal file
161
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_sum_error_FIX_arm.S
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#if __arm__
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
|
||||||
|
#if ( EMBEDDED_ARM >= 6 )
|
||||||
|
|
||||||
|
VARDEF val_N, r4
|
||||||
|
VARDEF val_K, r5
|
||||||
|
VARDEF val_order, r6
|
||||||
|
VARDEF val_in_Q15, _r7
|
||||||
|
VARDEF val_cb_Q15, r8
|
||||||
|
VARDEF val_wtmp_Q6, sb
|
||||||
|
VARDEF val_sum_error, sl
|
||||||
|
VARDEF val_diff, ip
|
||||||
|
VARDEF val_tmp, lr
|
||||||
|
|
||||||
|
VARDEF val_in_Q15_tmp, ip
|
||||||
|
VARDEF val_wtmp_Q6_tmp, lr
|
||||||
|
|
||||||
|
VARDEF ptr_wtmp, _r7
|
||||||
|
VARDEF val0_wtmp, sb
|
||||||
|
VARDEF val1_wtmp, r5
|
||||||
|
VARDEF val2_wtmp, r8
|
||||||
|
|
||||||
|
VARDEF ptr_err_Q20, r0
|
||||||
|
VARDEF ptr_in_Q15, r1
|
||||||
|
VARDEF ptr_w_Q6, r2
|
||||||
|
VARDEF ptr_pCB_Q15, r3
|
||||||
|
|
||||||
|
.set sp_wtmp, 0
|
||||||
|
.set sp_err_Q20, 32
|
||||||
|
.set sp_in_Q15, 36
|
||||||
|
.set sp_w_Q6, 40
|
||||||
|
.set sp_pCB_Q15, 44
|
||||||
|
.globl SYM(SKP_Silk_NLSF_VQ_sum_error_FIX)
|
||||||
|
SYM(SKP_Silk_NLSF_VQ_sum_error_FIX):
|
||||||
|
stmdb sp!, {r4-r10, fp, ip, lr}
|
||||||
|
add fp, sp, #36
|
||||||
|
sub sp, sp, #48
|
||||||
|
.set ptr_N, 88
|
||||||
|
.set ptr_K, 92
|
||||||
|
.set ptr_LPC_order, 96
|
||||||
|
|
||||||
|
str r0, [sp, #sp_err_Q20]
|
||||||
|
str r1, [sp, #sp_in_Q15]
|
||||||
|
str r2, [sp, #sp_w_Q6]
|
||||||
|
str r3, [sp, #sp_pCB_Q15]
|
||||||
|
ldr val_N, [sp, #ptr_N]
|
||||||
|
|
||||||
|
ldr val_order, [sp, #ptr_LPC_order]
|
||||||
|
ldr val1_wtmp, [r2], #4
|
||||||
|
ldr val2_wtmp, [r2], #4
|
||||||
|
sub val_order, val_order, #2
|
||||||
|
add ptr_wtmp, sp, #sp_wtmp
|
||||||
|
L(3)
|
||||||
|
pkhbt val0_wtmp, val1_wtmp, val2_wtmp, lsl #16
|
||||||
|
subs val_order, val_order, #2
|
||||||
|
ldr val1_wtmp, [r2], #4
|
||||||
|
ldr val2_wtmp, [r2], #4
|
||||||
|
str val0_wtmp, [ptr_wtmp], #4
|
||||||
|
bgt LR(3, b)
|
||||||
|
pkhbt val0_wtmp, val1_wtmp, val2_wtmp, lsl #16
|
||||||
|
str val0_wtmp, [ptr_wtmp], #4
|
||||||
|
|
||||||
|
ands val_tmp, ptr_pCB_Q15, #3
|
||||||
|
bgt LR(4, f)
|
||||||
|
/*OUTTER_LOOP*/
|
||||||
|
L(2)
|
||||||
|
ldr ptr_pCB_Q15, [sp, #sp_pCB_Q15]
|
||||||
|
ldr val_K, [sp, #ptr_K]
|
||||||
|
/*MIDDLE_LOOP*/
|
||||||
|
L(1)
|
||||||
|
ldr ptr_in_Q15, [sp, #sp_in_Q15]
|
||||||
|
add ptr_w_Q6, sp, #sp_wtmp
|
||||||
|
ldr val_order, [sp, #ptr_LPC_order]
|
||||||
|
mov val_sum_error, #0
|
||||||
|
/*INNER_LOOP*/
|
||||||
|
L(0)
|
||||||
|
ldmia ptr_in_Q15!, {val_in_Q15, val_in_Q15_tmp}
|
||||||
|
ldr val_wtmp_Q6, [ptr_w_Q6], #4
|
||||||
|
ldr val_cb_Q15, [ptr_pCB_Q15], #4
|
||||||
|
subs val_order, val_order, #2
|
||||||
|
pkhbt val_in_Q15, val_in_Q15, val_in_Q15_tmp, lsl #16
|
||||||
|
ssub16 val_diff, val_in_Q15, val_cb_Q15
|
||||||
|
smulbb val_tmp, val_diff, val_diff
|
||||||
|
smultt val_diff, val_diff, val_diff
|
||||||
|
smlawb val_sum_error, val_tmp, val_wtmp_Q6, val_sum_error
|
||||||
|
smlawt val_sum_error, val_diff, val_wtmp_Q6, val_sum_error
|
||||||
|
bgt LR(0, b)
|
||||||
|
subs val_K, val_K, #1
|
||||||
|
str val_sum_error, [ptr_err_Q20], #4
|
||||||
|
bgt LR(1, b)
|
||||||
|
subs val_N, val_N, #1
|
||||||
|
str ptr_in_Q15, [sp, #sp_in_Q15]
|
||||||
|
bgt LR(2, b)
|
||||||
|
|
||||||
|
add sp, sp, #48
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
|
||||||
|
L(4)
|
||||||
|
ldr ptr_pCB_Q15, [sp, #sp_pCB_Q15]
|
||||||
|
ldr val_K, [sp, #ptr_K]
|
||||||
|
/*MIDDLE_LOOP*/
|
||||||
|
L(1)
|
||||||
|
ldr ptr_in_Q15, [sp, #sp_in_Q15]
|
||||||
|
add ptr_w_Q6, sp, #sp_wtmp
|
||||||
|
ldr val_order, [sp, #ptr_LPC_order]
|
||||||
|
mov val_sum_error, #0
|
||||||
|
/*INNER_LOOP*/
|
||||||
|
L(0)
|
||||||
|
ldmia ptr_in_Q15!, {val_in_Q15, val_in_Q15_tmp}
|
||||||
|
ldr val_wtmp_Q6, [ptr_w_Q6], #4
|
||||||
|
ldrh val_cb_Q15, [ptr_pCB_Q15], #2
|
||||||
|
ldrh val_tmp, [ptr_pCB_Q15], #2
|
||||||
|
subs val_order, val_order, #2
|
||||||
|
pkhbt val_in_Q15, val_in_Q15, val_in_Q15_tmp, lsl #16
|
||||||
|
pkhbt val_cb_Q15, val_cb_Q15, val_tmp, lsl #16
|
||||||
|
ssub16 val_diff, val_in_Q15, val_cb_Q15
|
||||||
|
smulbb val_tmp, val_diff, val_diff
|
||||||
|
smultt val_diff, val_diff, val_diff
|
||||||
|
smlawb val_sum_error, val_tmp, val_wtmp_Q6, val_sum_error
|
||||||
|
smlawt val_sum_error, val_diff, val_wtmp_Q6, val_sum_error
|
||||||
|
bgt LR(0, b)
|
||||||
|
subs val_K, val_K, #1
|
||||||
|
str val_sum_error, [ptr_err_Q20], #4
|
||||||
|
bgt LR(1, b)
|
||||||
|
subs val_N, val_N, #1
|
||||||
|
str ptr_in_Q15, [sp, #sp_in_Q15]
|
||||||
|
bgt LR(4, b)
|
||||||
|
|
||||||
|
add sp, sp, #48
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
END
|
||||||
|
#endif
|
||||||
|
#endif
|
79
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_weights_laroia.c
Normal file
79
app/src/main/cpp/src/SKP_Silk_NLSF_VQ_weights_laroia.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP
|
||||||
|
Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech,
|
||||||
|
Signal Processing, pp. 641-644, 1991.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define Q_OUT 6
|
||||||
|
#define MIN_NDELTA 3
|
||||||
|
|
||||||
|
/* Laroia low complexity NLSF weights */
|
||||||
|
void SKP_Silk_NLSF_VQ_weights_laroia(
|
||||||
|
SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */
|
||||||
|
const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
|
||||||
|
const SKP_int D /* I: Input vector dimension (even) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 tmp1_int, tmp2_int;
|
||||||
|
|
||||||
|
/* Check that we are guaranteed to end up within the required range */
|
||||||
|
SKP_assert( D > 0 );
|
||||||
|
SKP_assert( ( D & 1 ) == 0 );
|
||||||
|
|
||||||
|
/* First value */
|
||||||
|
tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], MIN_NDELTA );
|
||||||
|
tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
|
||||||
|
tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], MIN_NDELTA );
|
||||||
|
tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
|
||||||
|
pNLSFW_Q6[ 0 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
|
SKP_assert( pNLSFW_Q6[ 0 ] > 0 );
|
||||||
|
|
||||||
|
/* Main loop */
|
||||||
|
for( k = 1; k < D - 1; k += 2 ) {
|
||||||
|
tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], MIN_NDELTA );
|
||||||
|
tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
|
||||||
|
pNLSFW_Q6[ k ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
|
SKP_assert( pNLSFW_Q6[ k ] > 0 );
|
||||||
|
|
||||||
|
tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], MIN_NDELTA );
|
||||||
|
tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
|
||||||
|
pNLSFW_Q6[ k + 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
|
SKP_assert( pNLSFW_Q6[ k + 1 ] > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last value */
|
||||||
|
tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], MIN_NDELTA );
|
||||||
|
tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
|
||||||
|
pNLSFW_Q6[ D - 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
|
SKP_assert( pNLSFW_Q6[ D - 1 ] > 0 );
|
||||||
|
}
|
139
app/src/main/cpp/src/SKP_Silk_NLSF_stabilize.c
Normal file
139
app/src/main/cpp/src/SKP_Silk_NLSF_stabilize.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* NLSF stabilizer: */
|
||||||
|
/* */
|
||||||
|
/* - Moves NLSFs futher apart if they are too close */
|
||||||
|
/* - Moves NLSFs away from borders if they are too close */
|
||||||
|
/* - High effort to achieve a modification with minimum */
|
||||||
|
/* Euclidean distance to input vector */
|
||||||
|
/* - Output are sorted NLSF coefficients */
|
||||||
|
/* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Constant Definitions */
|
||||||
|
#define MAX_LOOPS 20
|
||||||
|
|
||||||
|
/* NLSF stabilizer, for a single input data vector */
|
||||||
|
void SKP_Silk_NLSF_stabilize(
|
||||||
|
SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */
|
||||||
|
const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
|
||||||
|
const SKP_int L /* I: Number of NLSF parameters in the input vector */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;
|
||||||
|
SKP_int32 min_diff_Q15;
|
||||||
|
SKP_int loops;
|
||||||
|
SKP_int i, I=0, k;
|
||||||
|
|
||||||
|
/* This is necessary to ensure an output within range of a SKP_int16 */
|
||||||
|
SKP_assert( NDeltaMin_Q15[L] >= 1 );
|
||||||
|
|
||||||
|
for( loops = 0; loops < MAX_LOOPS; loops++ ) {
|
||||||
|
/**************************/
|
||||||
|
/* Find smallest distance */
|
||||||
|
/**************************/
|
||||||
|
/* First element */
|
||||||
|
min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
|
||||||
|
I = 0;
|
||||||
|
/* Middle elements */
|
||||||
|
for( i = 1; i <= L-1; i++ ) {
|
||||||
|
diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
|
||||||
|
if( diff_Q15 < min_diff_Q15 ) {
|
||||||
|
min_diff_Q15 = diff_Q15;
|
||||||
|
I = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Last element */
|
||||||
|
diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
|
||||||
|
if( diff_Q15 < min_diff_Q15 ) {
|
||||||
|
min_diff_Q15 = diff_Q15;
|
||||||
|
I = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
/* Now check if the smallest distance non-negative */
|
||||||
|
/***************************************************/
|
||||||
|
if (min_diff_Q15 >= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( I == 0 ) {
|
||||||
|
/* Move away from lower limit */
|
||||||
|
NLSF_Q15[0] = NDeltaMin_Q15[0];
|
||||||
|
|
||||||
|
} else if( I == L) {
|
||||||
|
/* Move away from higher limit */
|
||||||
|
NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Find the lower extreme for the location of the current center frequency */
|
||||||
|
min_center_Q15 = 0;
|
||||||
|
for( k = 0; k < I; k++ ) {
|
||||||
|
min_center_Q15 += NDeltaMin_Q15[k];
|
||||||
|
}
|
||||||
|
min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||||
|
|
||||||
|
/* Find the upper extreme for the location of the current center frequency */
|
||||||
|
max_center_Q15 = (1<<15);
|
||||||
|
for( k = L; k > I; k-- ) {
|
||||||
|
max_center_Q15 -= NDeltaMin_Q15[k];
|
||||||
|
}
|
||||||
|
max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );
|
||||||
|
|
||||||
|
/* Move apart, sorted by value, keeping the same center frequency */
|
||||||
|
center_freq_Q15 = SKP_LIMIT_32( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
|
||||||
|
min_center_Q15, max_center_Q15 );
|
||||||
|
NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||||
|
NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Safe and simple fall back method, which is less ideal than the above */
|
||||||
|
if( loops == MAX_LOOPS )
|
||||||
|
{
|
||||||
|
/* Insertion sort (fast for already almost sorted arrays): */
|
||||||
|
/* Best case: O(n) for an already sorted array */
|
||||||
|
/* Worst case: O(n^2) for an inversely sorted array */
|
||||||
|
SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L);
|
||||||
|
|
||||||
|
/* First NLSF should be no less than NDeltaMin[0] */
|
||||||
|
NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
|
||||||
|
|
||||||
|
/* Keep delta_min distance between the NLSFs */
|
||||||
|
for( i = 1; i < L; i++ )
|
||||||
|
NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
|
||||||
|
|
||||||
|
/* Last NLSF should be no higher than 1 - NDeltaMin[L] */
|
||||||
|
NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
|
||||||
|
|
||||||
|
/* Keep NDeltaMin distance between the NLSFs */
|
||||||
|
for( i = L-2; i >= 0; i-- )
|
||||||
|
NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
454
app/src/main/cpp/src/SKP_Silk_NSQ.c
Normal file
454
app/src/main/cpp/src/SKP_Silk_NSQ.c
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_nsq_scale_states(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
const SKP_int16 x[], /* I input in Q0 */
|
||||||
|
SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
||||||
|
SKP_int subfr_length, /* I length of input */
|
||||||
|
const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
||||||
|
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
||||||
|
SKP_int subfr, /* I subframe number */
|
||||||
|
const SKP_int LTP_scale_Q14, /* I */
|
||||||
|
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int pitchL[ NB_SUBFR ] /* I */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_noise_shape_quantizer(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
SKP_int sigtype, /* I Signal type */
|
||||||
|
const SKP_int32 x_sc_Q10[], /* I */
|
||||||
|
SKP_int8 q[], /* O */
|
||||||
|
SKP_int16 xq[], /* O */
|
||||||
|
SKP_int32 sLTP_Q16[], /* I/O LTP state */
|
||||||
|
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
|
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
|
const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
||||||
|
SKP_int lag, /* I Pitch lag */
|
||||||
|
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||||
|
SKP_int Tilt_Q14, /* I Spectral tilt */
|
||||||
|
SKP_int32 LF_shp_Q14, /* I */
|
||||||
|
SKP_int32 Gain_Q16, /* I */
|
||||||
|
SKP_int Lambda_Q10, /* I */
|
||||||
|
SKP_int offset_Q10, /* I */
|
||||||
|
SKP_int length, /* I Input length */
|
||||||
|
SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */
|
||||||
|
SKP_int predictLPCOrder /* I Prediction filter order */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_NSQ(
|
||||||
|
SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||||
|
SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
const SKP_int16 x[], /* I prefiltered input signal */
|
||||||
|
SKP_int8 q[], /* O quantized qulse signal */
|
||||||
|
const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
|
||||||
|
const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */
|
||||||
|
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */
|
||||||
|
const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
|
||||||
|
const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
|
||||||
|
const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int Lambda_Q10, /* I */
|
||||||
|
const SKP_int LTP_scale_Q14 /* I LTP state scaling */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, lag, start_idx, LSF_interpolation_flag;
|
||||||
|
const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
||||||
|
SKP_int16 *pxq;
|
||||||
|
SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int32 HarmShapeFIRPacked_Q14;
|
||||||
|
SKP_int offset_Q10;
|
||||||
|
SKP_int32 FiltState[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
|
||||||
|
|
||||||
|
NSQ->rand_seed = psEncCtrlC->Seed;
|
||||||
|
/* Set unvoiced lag to the previous one, overwrite later for voiced */
|
||||||
|
lag = NSQ->lagPrev;
|
||||||
|
|
||||||
|
SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );
|
||||||
|
|
||||||
|
offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];
|
||||||
|
|
||||||
|
if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {
|
||||||
|
LSF_interpolation_flag = 0;
|
||||||
|
} else {
|
||||||
|
LSF_interpolation_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup pointers to start of sub frame */
|
||||||
|
NSQ->sLTP_shp_buf_idx = psEncC->frame_length;
|
||||||
|
NSQ->sLTP_buf_idx = psEncC->frame_length;
|
||||||
|
pxq = &NSQ->xq[ psEncC->frame_length ];
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
|
||||||
|
B_Q14 = <PCoef_Q14[ k * LTP_ORDER ];
|
||||||
|
AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
||||||
|
|
||||||
|
/* Noise shape parameters */
|
||||||
|
SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
||||||
|
HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
||||||
|
HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
||||||
|
|
||||||
|
NSQ->rewhite_flag = 0;
|
||||||
|
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Voiced */
|
||||||
|
lag = psEncCtrlC->pitchL[ k ];
|
||||||
|
|
||||||
|
/* Re-whitening */
|
||||||
|
if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
|
||||||
|
|
||||||
|
/* Rewhiten with new A coefs */
|
||||||
|
start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
|
||||||
|
SKP_assert( start_idx >= 0 );
|
||||||
|
SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder );
|
||||||
|
|
||||||
|
SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );
|
||||||
|
SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * ( psEncC->frame_length >> 2 ) ],
|
||||||
|
A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
|
NSQ->rewhite_flag = 1;
|
||||||
|
NSQ->sLTP_buf_idx = psEncC->frame_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_Silk_nsq_scale_states( NSQ, x, x_sc_Q10, psEncC->subfr_length, sLTP,
|
||||||
|
sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );
|
||||||
|
|
||||||
|
SKP_Silk_noise_shape_quantizer( NSQ, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16, A_Q12, B_Q14,
|
||||||
|
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
|
||||||
|
offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder
|
||||||
|
);
|
||||||
|
|
||||||
|
x += psEncC->subfr_length;
|
||||||
|
q += psEncC->subfr_length;
|
||||||
|
pxq += psEncC->subfr_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update lagPrev for next frame */
|
||||||
|
NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];
|
||||||
|
|
||||||
|
/* Save quantized speech and noise shaping signals */
|
||||||
|
SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );
|
||||||
|
SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
#ifdef USE_UNQUANTIZED_LSFS
|
||||||
|
DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************/
|
||||||
|
/* SKP_Silk_noise_shape_quantizer */
|
||||||
|
/***********************************/
|
||||||
|
SKP_INLINE void SKP_Silk_noise_shape_quantizer(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
SKP_int sigtype, /* I Signal type */
|
||||||
|
const SKP_int32 x_sc_Q10[], /* I */
|
||||||
|
SKP_int8 q[], /* O */
|
||||||
|
SKP_int16 xq[], /* O */
|
||||||
|
SKP_int32 sLTP_Q16[], /* I/O LTP state */
|
||||||
|
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
|
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
|
const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
||||||
|
SKP_int lag, /* I Pitch lag */
|
||||||
|
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||||
|
SKP_int Tilt_Q14, /* I Spectral tilt */
|
||||||
|
SKP_int32 LF_shp_Q14, /* I */
|
||||||
|
SKP_int32 Gain_Q16, /* I */
|
||||||
|
SKP_int Lambda_Q10, /* I */
|
||||||
|
SKP_int offset_Q10, /* I */
|
||||||
|
SKP_int length, /* I Input length */
|
||||||
|
SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */
|
||||||
|
SKP_int predictLPCOrder /* I Prediction filter order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, j;
|
||||||
|
SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
|
||||||
|
SKP_int32 n_LF_Q10, r_Q10, q_Q0, q_Q10;
|
||||||
|
SKP_int32 thr1_Q10, thr2_Q10, thr3_Q10;
|
||||||
|
SKP_int32 dither, exc_Q10, LPC_exc_Q10, xq_Q10;
|
||||||
|
SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10;
|
||||||
|
SKP_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 a_Q12_tmp[ MAX_LPC_ORDER / 2 ], Atmp;
|
||||||
|
/* Preload LPC coefficients to array on stack. Gives small performance gain */
|
||||||
|
SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
||||||
|
pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
|
|
||||||
|
/* Setup short term AR state */
|
||||||
|
psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
|
||||||
|
|
||||||
|
/* Quantization thresholds */
|
||||||
|
thr1_Q10 = SKP_SUB_RSHIFT32( -1536, Lambda_Q10, 1 );
|
||||||
|
thr2_Q10 = SKP_SUB_RSHIFT32( -512, Lambda_Q10, 1 );
|
||||||
|
thr2_Q10 = SKP_ADD_RSHIFT32( thr2_Q10, SKP_SMULBB( offset_Q10, Lambda_Q10 ), 10 );
|
||||||
|
thr3_Q10 = SKP_ADD_RSHIFT32( 512, Lambda_Q10, 1 );
|
||||||
|
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
/* Generate dither */
|
||||||
|
NSQ->rand_seed = SKP_RAND( NSQ->rand_seed );
|
||||||
|
|
||||||
|
/* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
|
||||||
|
dither = SKP_RSHIFT( NSQ->rand_seed, 31 );
|
||||||
|
|
||||||
|
/* Short-term prediction */
|
||||||
|
SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
|
||||||
|
/* check that array starts at 4-byte aligned address */
|
||||||
|
SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )a_Q12 - ( SKP_int8* )0 ) & 3 ) == 0 );
|
||||||
|
SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
|
||||||
|
/* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
|
||||||
|
/* loaded in reverse order and the code will give the wrong result. In that case swapping */
|
||||||
|
/* the SMLAWB and SMLAWT instructions should solve the problem. */
|
||||||
|
/* Partially unrolled */
|
||||||
|
Atmp = a_Q12_tmp[ 0 ]; /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 1 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 2 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 3 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 4 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp );
|
||||||
|
for( j = 10; j < predictLPCOrder; j += 2 ) {
|
||||||
|
Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Partially unrolled */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
||||||
|
for( j = 10; j < predictLPCOrder; j ++ ) {
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Long-term prediction */
|
||||||
|
if( sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Unrolled loop */
|
||||||
|
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
||||||
|
pred_lag_ptr++;
|
||||||
|
} else {
|
||||||
|
LTP_pred_Q14 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Noise shape feedback */
|
||||||
|
SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
|
||||||
|
tmp2 = psLPC_Q14[ 0 ];
|
||||||
|
tmp1 = NSQ->sAR2_Q14[ 0 ];
|
||||||
|
NSQ->sAR2_Q14[ 0 ] = tmp2;
|
||||||
|
n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] );
|
||||||
|
for( j = 2; j < shapingLPCOrder; j += 2 ) {
|
||||||
|
tmp2 = NSQ->sAR2_Q14[ j - 1 ];
|
||||||
|
NSQ->sAR2_Q14[ j - 1 ] = tmp1;
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] );
|
||||||
|
tmp1 = NSQ->sAR2_Q14[ j + 0 ];
|
||||||
|
NSQ->sAR2_Q14[ j + 0 ] = tmp2;
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] );
|
||||||
|
}
|
||||||
|
NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
|
||||||
|
|
||||||
|
n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, NSQ->sLF_AR_shp_Q12, Tilt_Q14 );
|
||||||
|
|
||||||
|
n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ), 2 );
|
||||||
|
n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, NSQ->sLF_AR_shp_Q12, LF_shp_Q14 );
|
||||||
|
|
||||||
|
SKP_assert( lag > 0 || sigtype == SIG_TYPE_UNVOICED );
|
||||||
|
|
||||||
|
/* Long-term shaping */
|
||||||
|
if( lag > 0 ) {
|
||||||
|
/* Symmetric, packed FIR coefficients */
|
||||||
|
n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
||||||
|
n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
||||||
|
n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );
|
||||||
|
shp_lag_ptr++;
|
||||||
|
} else {
|
||||||
|
n_LTP_Q14 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input minus prediction plus noise feedback */
|
||||||
|
//r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP;
|
||||||
|
tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
|
||||||
|
tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */
|
||||||
|
tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
|
||||||
|
tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
|
||||||
|
tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */
|
||||||
|
r_Q10 = SKP_SUB32( x_sc_Q10[ i ], tmp1 );
|
||||||
|
|
||||||
|
/* Flip sign depending on dither */
|
||||||
|
r_Q10 = ( r_Q10 ^ dither ) - dither;
|
||||||
|
r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );
|
||||||
|
r_Q10 = SKP_LIMIT_32( r_Q10, -(64 << 10), 64 << 10 );
|
||||||
|
|
||||||
|
/* Quantize */
|
||||||
|
q_Q0 = 0;
|
||||||
|
q_Q10 = 0;
|
||||||
|
if( r_Q10 < thr2_Q10 ) {
|
||||||
|
if( r_Q10 < thr1_Q10 ) {
|
||||||
|
q_Q0 = SKP_RSHIFT_ROUND( SKP_ADD_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );
|
||||||
|
q_Q10 = SKP_LSHIFT( q_Q0, 10 );
|
||||||
|
} else {
|
||||||
|
q_Q0 = -1;
|
||||||
|
q_Q10 = -1024;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if( r_Q10 > thr3_Q10 ) {
|
||||||
|
q_Q0 = SKP_RSHIFT_ROUND( SKP_SUB_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );
|
||||||
|
q_Q10 = SKP_LSHIFT( q_Q0, 10 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
q[ i ] = ( SKP_int8 )q_Q0; /* No saturation needed because max is 64 */
|
||||||
|
|
||||||
|
/* Excitation */
|
||||||
|
exc_Q10 = SKP_ADD32( q_Q10, offset_Q10 );
|
||||||
|
exc_Q10 = ( exc_Q10 ^ dither ) - dither;
|
||||||
|
|
||||||
|
/* Add predictions */
|
||||||
|
LPC_exc_Q10 = SKP_ADD32( exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
|
||||||
|
xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Scale XQ back to normal level before saving */
|
||||||
|
xq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( xq_Q10, Gain_Q16 ), 10 ) );
|
||||||
|
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
psLPC_Q14++;
|
||||||
|
*psLPC_Q14 = SKP_LSHIFT( xq_Q10, 4 );
|
||||||
|
sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
|
||||||
|
NSQ->sLF_AR_shp_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
|
||||||
|
|
||||||
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
|
||||||
|
sLTP_Q16[ NSQ->sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
|
||||||
|
NSQ->sLTP_shp_buf_idx++;
|
||||||
|
NSQ->sLTP_buf_idx++;
|
||||||
|
|
||||||
|
/* Make dither dependent on quantized signal */
|
||||||
|
NSQ->rand_seed += q[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update LPC synth buffer */
|
||||||
|
SKP_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_nsq_scale_states(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
const SKP_int16 x[], /* I input in Q0 */
|
||||||
|
SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
||||||
|
SKP_int subfr_length, /* I length of input */
|
||||||
|
const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
||||||
|
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
||||||
|
SKP_int subfr, /* I subframe number */
|
||||||
|
const SKP_int LTP_scale_Q14, /* I */
|
||||||
|
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int pitchL[ NB_SUBFR ] /* I */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, lag;
|
||||||
|
SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
|
||||||
|
|
||||||
|
inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 );
|
||||||
|
inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
|
||||||
|
lag = pitchL[ subfr ];
|
||||||
|
|
||||||
|
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
||||||
|
if( NSQ->rewhite_flag ) {
|
||||||
|
inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
|
||||||
|
if( subfr == 0 ) {
|
||||||
|
/* Do LTP downscaling */
|
||||||
|
inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
|
||||||
|
}
|
||||||
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
|
SKP_assert( i < MAX_FRAME_LENGTH );
|
||||||
|
sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust for changing gain */
|
||||||
|
if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {
|
||||||
|
gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );
|
||||||
|
|
||||||
|
/* Scale long-term shaping state */
|
||||||
|
for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) {
|
||||||
|
NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale long-term prediction state */
|
||||||
|
if( NSQ->rewhite_flag == 0 ) {
|
||||||
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
|
sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSQ->sLF_AR_shp_Q12 = SKP_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q12 );
|
||||||
|
|
||||||
|
/* Scale short-term prediction and shaping states */
|
||||||
|
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
|
||||||
|
NSQ->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
|
||||||
|
}
|
||||||
|
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
|
||||||
|
NSQ->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale input */
|
||||||
|
for( i = 0; i < subfr_length; i++ ) {
|
||||||
|
x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save inv_gain */
|
||||||
|
SKP_assert( inv_gain_Q16 != 0 );
|
||||||
|
NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
|
||||||
|
}
|
733
app/src/main/cpp/src/SKP_Silk_NSQ_del_dec.c
Normal file
733
app/src/main/cpp/src/SKP_Silk_NSQ_del_dec.c
Normal file
@ -0,0 +1,733 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SKP_int32 RandState[ DECISION_DELAY ];
|
||||||
|
SKP_int32 Q_Q10[ DECISION_DELAY ];
|
||||||
|
SKP_int32 Xq_Q10[ DECISION_DELAY ];
|
||||||
|
SKP_int32 Pred_Q16[ DECISION_DELAY ];
|
||||||
|
SKP_int32 Shape_Q10[ DECISION_DELAY ];
|
||||||
|
SKP_int32 Gain_Q16[ DECISION_DELAY ];
|
||||||
|
SKP_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
|
||||||
|
SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ];
|
||||||
|
SKP_int32 LF_AR_Q12;
|
||||||
|
SKP_int32 Seed;
|
||||||
|
SKP_int32 SeedInit;
|
||||||
|
SKP_int32 RD_Q10;
|
||||||
|
} NSQ_del_dec_struct;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SKP_int32 Q_Q10;
|
||||||
|
SKP_int32 RD_Q10;
|
||||||
|
SKP_int32 xq_Q14;
|
||||||
|
SKP_int32 LF_AR_Q12;
|
||||||
|
SKP_int32 sLTP_shp_Q10;
|
||||||
|
SKP_int32 LPC_exc_Q16;
|
||||||
|
} NSQ_sample_struct;
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_copy_del_dec_state(
|
||||||
|
NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */
|
||||||
|
NSQ_del_dec_struct *DD_src, /* I Src del dec state */
|
||||||
|
SKP_int LPC_state_idx /* I Index to LPC buffer */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||||
|
const SKP_int16 x[], /* I Input in Q0 */
|
||||||
|
SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
||||||
|
SKP_int subfr_length, /* I Length of input */
|
||||||
|
const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
||||||
|
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
||||||
|
SKP_int subfr, /* I Subframe number */
|
||||||
|
SKP_int nStatesDelayedDecision, /* I Number of del dec states */
|
||||||
|
SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */
|
||||||
|
const SKP_int LTP_scale_Q14, /* I LTP state scaling */
|
||||||
|
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */
|
||||||
|
);
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
/* Noise shape quantizer for one subframe */
|
||||||
|
/******************************************/
|
||||||
|
SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||||
|
SKP_int sigtype, /* I Signal type */
|
||||||
|
const SKP_int32 x_Q10[], /* I */
|
||||||
|
SKP_int8 q[], /* O */
|
||||||
|
SKP_int16 xq[], /* O */
|
||||||
|
SKP_int32 sLTP_Q16[], /* I/O LTP filter state */
|
||||||
|
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
|
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
|
const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */
|
||||||
|
SKP_int lag, /* I Pitch lag */
|
||||||
|
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||||
|
SKP_int Tilt_Q14, /* I Spectral tilt */
|
||||||
|
SKP_int32 LF_shp_Q14, /* I */
|
||||||
|
SKP_int32 Gain_Q16, /* I */
|
||||||
|
SKP_int Lambda_Q10, /* I */
|
||||||
|
SKP_int offset_Q10, /* I */
|
||||||
|
SKP_int length, /* I Input length */
|
||||||
|
SKP_int subfr, /* I Subframe number */
|
||||||
|
SKP_int shapingLPCOrder, /* I Shaping LPC filter order */
|
||||||
|
SKP_int predictLPCOrder, /* I Prediction filter order */
|
||||||
|
SKP_int warping_Q16, /* I */
|
||||||
|
SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */
|
||||||
|
SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */
|
||||||
|
SKP_int decisionDelay /* I */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_NSQ_del_dec(
|
||||||
|
SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||||
|
SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
const SKP_int16 x[], /* I Prefiltered input signal */
|
||||||
|
SKP_int8 q[], /* O Quantized pulse signal */
|
||||||
|
const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
|
||||||
|
const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */
|
||||||
|
const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */
|
||||||
|
const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
|
||||||
|
const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
|
||||||
|
const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int Lambda_Q10, /* I */
|
||||||
|
const SKP_int LTP_scale_Q14 /* I LTP state scaling */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
|
||||||
|
SKP_int last_smple_idx, smpl_buf_idx, decisionDelay, subfr_length;
|
||||||
|
const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
||||||
|
SKP_int16 *pxq;
|
||||||
|
SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int32 HarmShapeFIRPacked_Q14;
|
||||||
|
SKP_int offset_Q10;
|
||||||
|
SKP_int32 FiltState[ MAX_LPC_ORDER ], RDmin_Q10;
|
||||||
|
SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
|
||||||
|
NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ];
|
||||||
|
NSQ_del_dec_struct *psDD;
|
||||||
|
|
||||||
|
subfr_length = psEncC->frame_length / NB_SUBFR;
|
||||||
|
|
||||||
|
/* Set unvoiced lag to the previous one, overwrite later for voiced */
|
||||||
|
lag = NSQ->lagPrev;
|
||||||
|
|
||||||
|
SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );
|
||||||
|
|
||||||
|
/* Initialize delayed decision states */
|
||||||
|
SKP_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
|
||||||
|
for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
|
||||||
|
psDD = &psDelDec[ k ];
|
||||||
|
psDD->Seed = ( k + psEncCtrlC->Seed ) & 3;
|
||||||
|
psDD->SeedInit = psDD->Seed;
|
||||||
|
psDD->RD_Q10 = 0;
|
||||||
|
psDD->LF_AR_Q12 = NSQ->sLF_AR_shp_Q12;
|
||||||
|
psDD->Shape_Q10[ 0 ] = NSQ->sLTP_shp_Q10[ psEncC->frame_length - 1 ];
|
||||||
|
SKP_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
|
||||||
|
SKP_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];
|
||||||
|
smpl_buf_idx = 0; /* index of oldest samples */
|
||||||
|
|
||||||
|
decisionDelay = SKP_min_int( DECISION_DELAY, subfr_length );
|
||||||
|
|
||||||
|
/* For voiced frames limit the decision delay to lower than the pitch lag */
|
||||||
|
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
decisionDelay = SKP_min_int( decisionDelay, psEncCtrlC->pitchL[ k ] - LTP_ORDER / 2 - 1 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if( lag > 0 ) {
|
||||||
|
decisionDelay = SKP_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {
|
||||||
|
LSF_interpolation_flag = 0;
|
||||||
|
} else {
|
||||||
|
LSF_interpolation_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup pointers to start of sub frame */
|
||||||
|
pxq = &NSQ->xq[ psEncC->frame_length ];
|
||||||
|
NSQ->sLTP_shp_buf_idx = psEncC->frame_length;
|
||||||
|
NSQ->sLTP_buf_idx = psEncC->frame_length;
|
||||||
|
subfr = 0;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
|
||||||
|
B_Q14 = <PCoef_Q14[ k * LTP_ORDER ];
|
||||||
|
AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
||||||
|
|
||||||
|
/* Noise shape parameters */
|
||||||
|
SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
||||||
|
HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
||||||
|
HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
||||||
|
|
||||||
|
NSQ->rewhite_flag = 0;
|
||||||
|
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Voiced */
|
||||||
|
lag = psEncCtrlC->pitchL[ k ];
|
||||||
|
|
||||||
|
/* Re-whitening */
|
||||||
|
if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
|
||||||
|
if( k == 2 ) {
|
||||||
|
/* RESET DELAYED DECISIONS */
|
||||||
|
/* Find winner */
|
||||||
|
RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
|
||||||
|
Winner_ind = 0;
|
||||||
|
for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
|
||||||
|
if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
|
||||||
|
RDmin_Q10 = psDelDec[ i ].RD_Q10;
|
||||||
|
Winner_ind = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
|
||||||
|
if( i != Winner_ind ) {
|
||||||
|
psDelDec[ i ].RD_Q10 += ( SKP_int32_MAX >> 4 );
|
||||||
|
SKP_assert( psDelDec[ i ].RD_Q10 >= 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy final part of signals from winner state to output and long-term filter states */
|
||||||
|
psDD = &psDelDec[ Winner_ind ];
|
||||||
|
last_smple_idx = smpl_buf_idx + decisionDelay;
|
||||||
|
for( i = 0; i < decisionDelay; i++ ) {
|
||||||
|
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
||||||
|
q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||||
|
pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
|
||||||
|
SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ],
|
||||||
|
psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
|
||||||
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
|
||||||
|
}
|
||||||
|
|
||||||
|
subfr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rewhiten with new A coefs */
|
||||||
|
start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
|
||||||
|
SKP_assert( start_idx >= 0 );
|
||||||
|
SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder );
|
||||||
|
|
||||||
|
SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );
|
||||||
|
SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
|
||||||
|
A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
|
NSQ->sLTP_buf_idx = psEncC->frame_length;
|
||||||
|
NSQ->rewhite_flag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_Silk_nsq_del_dec_scale_states( NSQ, psDelDec, x, x_sc_Q10,
|
||||||
|
subfr_length, sLTP, sLTP_Q16, k, psEncC->nStatesDelayedDecision, smpl_buf_idx,
|
||||||
|
LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );
|
||||||
|
|
||||||
|
SKP_Silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16,
|
||||||
|
A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ],
|
||||||
|
Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder,
|
||||||
|
psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
|
||||||
|
|
||||||
|
x += psEncC->subfr_length;
|
||||||
|
q += psEncC->subfr_length;
|
||||||
|
pxq += psEncC->subfr_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find winner */
|
||||||
|
RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
|
||||||
|
Winner_ind = 0;
|
||||||
|
for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
|
||||||
|
if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
|
||||||
|
RDmin_Q10 = psDelDec[ k ].RD_Q10;
|
||||||
|
Winner_ind = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy final part of signals from winner state to output and long-term filter states */
|
||||||
|
psDD = &psDelDec[ Winner_ind ];
|
||||||
|
psEncCtrlC->Seed = psDD->SeedInit;
|
||||||
|
last_smple_idx = smpl_buf_idx + decisionDelay;
|
||||||
|
for( i = 0; i < decisionDelay; i++ ) {
|
||||||
|
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
||||||
|
q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||||
|
pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
|
||||||
|
SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
|
||||||
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
|
||||||
|
sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay + i ] = psDD->Pred_Q16[ last_smple_idx ];
|
||||||
|
}
|
||||||
|
SKP_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
|
||||||
|
SKP_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
NSQ->sLF_AR_shp_Q12 = psDD->LF_AR_Q12;
|
||||||
|
NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];
|
||||||
|
|
||||||
|
/* Save quantized speech and noise shaping signals */
|
||||||
|
SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );
|
||||||
|
SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
#ifdef USE_UNQUANTIZED_LSFS
|
||||||
|
DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
/* Noise shape quantizer for one subframe */
|
||||||
|
/******************************************/
|
||||||
|
SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||||
|
SKP_int sigtype, /* I Signal type */
|
||||||
|
const SKP_int32 x_Q10[], /* I */
|
||||||
|
SKP_int8 q[], /* O */
|
||||||
|
SKP_int16 xq[], /* O */
|
||||||
|
SKP_int32 sLTP_Q16[], /* I/O LTP filter state */
|
||||||
|
const SKP_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
|
const SKP_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
|
const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */
|
||||||
|
SKP_int lag, /* I Pitch lag */
|
||||||
|
SKP_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||||
|
SKP_int Tilt_Q14, /* I Spectral tilt */
|
||||||
|
SKP_int32 LF_shp_Q14, /* I */
|
||||||
|
SKP_int32 Gain_Q16, /* I */
|
||||||
|
SKP_int Lambda_Q10, /* I */
|
||||||
|
SKP_int offset_Q10, /* I */
|
||||||
|
SKP_int length, /* I Input length */
|
||||||
|
SKP_int subfr, /* I Subframe number */
|
||||||
|
SKP_int shapingLPCOrder, /* I Shaping LPC filter order */
|
||||||
|
SKP_int predictLPCOrder, /* I Prediction filter order */
|
||||||
|
SKP_int warping_Q16, /* I */
|
||||||
|
SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */
|
||||||
|
SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */
|
||||||
|
SKP_int decisionDelay /* I */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
|
||||||
|
SKP_int32 Winner_rand_state;
|
||||||
|
SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
|
||||||
|
SKP_int32 n_LF_Q10, r_Q10, rr_Q20, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
|
||||||
|
SKP_int32 q1_Q10, q2_Q10, dither, exc_Q10, LPC_exc_Q10, xq_Q10;
|
||||||
|
SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10;
|
||||||
|
SKP_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
|
||||||
|
NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
|
||||||
|
NSQ_del_dec_struct *psDD;
|
||||||
|
NSQ_sample_struct *psSS;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 a_Q12_tmp[ MAX_LPC_ORDER / 2 ], Atmp;
|
||||||
|
|
||||||
|
/* Preload LPC coeficients to array on stack. Gives small performance gain */
|
||||||
|
SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
||||||
|
pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
|
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
/* Perform common calculations used in all states */
|
||||||
|
|
||||||
|
/* Long-term prediction */
|
||||||
|
if( sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Unrolled loop */
|
||||||
|
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
||||||
|
pred_lag_ptr++;
|
||||||
|
} else {
|
||||||
|
LTP_pred_Q14 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Long-term shaping */
|
||||||
|
if( lag > 0 ) {
|
||||||
|
/* Symmetric, packed FIR coefficients */
|
||||||
|
n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
||||||
|
n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
||||||
|
n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );
|
||||||
|
shp_lag_ptr++;
|
||||||
|
} else {
|
||||||
|
n_LTP_Q14 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
/* Delayed decision state */
|
||||||
|
psDD = &psDelDec[ k ];
|
||||||
|
|
||||||
|
/* Sample state */
|
||||||
|
psSS = psSampleState[ k ];
|
||||||
|
|
||||||
|
/* Generate dither */
|
||||||
|
psDD->Seed = SKP_RAND( psDD->Seed );
|
||||||
|
|
||||||
|
/* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
|
||||||
|
dither = SKP_RSHIFT( psDD->Seed, 31 );
|
||||||
|
|
||||||
|
/* Pointer used in short term prediction and shaping */
|
||||||
|
psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
|
||||||
|
/* Short-term prediction */
|
||||||
|
SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
|
||||||
|
SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
|
||||||
|
SKP_assert( ( ( ( int )( ( char* )( a_Q12 ) - ( ( char* ) 0 ) ) ) & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* Partially unrolled */
|
||||||
|
Atmp = a_Q12_tmp[ 0 ]; /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 1 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 2 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 3 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp );
|
||||||
|
Atmp = a_Q12_tmp[ 4 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp );
|
||||||
|
for( j = 10; j < predictLPCOrder; j += 2 ) {
|
||||||
|
Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Partially unrolled */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
||||||
|
for( j = 10; j < predictLPCOrder; j ++ ) {
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Noise shape feedback */
|
||||||
|
SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
|
||||||
|
/* Output of lowpass section */
|
||||||
|
tmp2 = SKP_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
|
||||||
|
/* Output of allpass section */
|
||||||
|
tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
|
||||||
|
psDD->sAR2_Q14[ 0 ] = tmp2;
|
||||||
|
n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] );
|
||||||
|
/* Loop over allpass sections */
|
||||||
|
for( j = 2; j < shapingLPCOrder; j += 2 ) {
|
||||||
|
/* Output of allpass section */
|
||||||
|
tmp2 = SKP_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
|
||||||
|
psDD->sAR2_Q14[ j - 1 ] = tmp1;
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] );
|
||||||
|
/* Output of allpass section */
|
||||||
|
tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
|
||||||
|
psDD->sAR2_Q14[ j + 0 ] = tmp2;
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] );
|
||||||
|
}
|
||||||
|
psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
|
||||||
|
|
||||||
|
n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */
|
||||||
|
n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psDD->LF_AR_Q12, Tilt_Q14 );
|
||||||
|
|
||||||
|
n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( psDD->Shape_Q10[ *smpl_buf_idx ], LF_shp_Q14 ), 2 );
|
||||||
|
n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, psDD->LF_AR_Q12, LF_shp_Q14 );
|
||||||
|
|
||||||
|
/* Input minus prediction plus noise feedback */
|
||||||
|
/* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
|
||||||
|
tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
|
||||||
|
tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */
|
||||||
|
tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
|
||||||
|
tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
|
||||||
|
tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */
|
||||||
|
r_Q10 = SKP_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
|
||||||
|
|
||||||
|
/* Flip sign depending on dither */
|
||||||
|
r_Q10 = ( r_Q10 ^ dither ) - dither;
|
||||||
|
r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );
|
||||||
|
r_Q10 = SKP_LIMIT_32( r_Q10, -(64 << 10), 64 << 10 );
|
||||||
|
|
||||||
|
/* Find two quantization level candidates and measure their rate-distortion */
|
||||||
|
if( r_Q10 < -1536 ) {
|
||||||
|
q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );
|
||||||
|
r_Q10 = SKP_SUB32( r_Q10, q1_Q10 );
|
||||||
|
rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( -SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );
|
||||||
|
rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );
|
||||||
|
rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );
|
||||||
|
q2_Q10 = SKP_ADD32( q1_Q10, 1024 );
|
||||||
|
} else if( r_Q10 > 512 ) {
|
||||||
|
q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );
|
||||||
|
r_Q10 = SKP_SUB32( r_Q10, q1_Q10 );
|
||||||
|
rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );
|
||||||
|
rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );
|
||||||
|
rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_SUB_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );
|
||||||
|
q2_Q10 = SKP_SUB32( q1_Q10, 1024 );
|
||||||
|
} else { /* r_Q10 >= -1536 && q1_Q10 <= 512 */
|
||||||
|
rr_Q20 = SKP_SMULBB( offset_Q10, Lambda_Q10 );
|
||||||
|
rd2_Q10 = SKP_RSHIFT( SKP_SMLABB( rr_Q20, r_Q10, r_Q10 ), 10 );
|
||||||
|
rd1_Q10 = SKP_ADD32( rd2_Q10, 1024 );
|
||||||
|
rd1_Q10 = SKP_ADD32( rd1_Q10, SKP_SUB_RSHIFT32( SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ), rr_Q20, 9 ) );
|
||||||
|
q1_Q10 = -1024;
|
||||||
|
q2_Q10 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rd1_Q10 < rd2_Q10 ) {
|
||||||
|
psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );
|
||||||
|
psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );
|
||||||
|
psSS[ 0 ].Q_Q10 = q1_Q10;
|
||||||
|
psSS[ 1 ].Q_Q10 = q2_Q10;
|
||||||
|
} else {
|
||||||
|
psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );
|
||||||
|
psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );
|
||||||
|
psSS[ 0 ].Q_Q10 = q2_Q10;
|
||||||
|
psSS[ 1 ].Q_Q10 = q1_Q10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update states for best quantization */
|
||||||
|
|
||||||
|
/* Quantized excitation */
|
||||||
|
exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 0 ].Q_Q10 );
|
||||||
|
exc_Q10 = ( exc_Q10 ^ dither ) - dither;
|
||||||
|
|
||||||
|
/* Add predictions */
|
||||||
|
LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );
|
||||||
|
xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
|
||||||
|
psSS[ 0 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
|
||||||
|
psSS[ 0 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
|
||||||
|
psSS[ 0 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 );
|
||||||
|
psSS[ 0 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 );
|
||||||
|
|
||||||
|
/* Update states for second best quantization */
|
||||||
|
|
||||||
|
/* Quantized excitation */
|
||||||
|
exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 1 ].Q_Q10 );
|
||||||
|
exc_Q10 = ( exc_Q10 ^ dither ) - dither;
|
||||||
|
|
||||||
|
/* Add predictions */
|
||||||
|
LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );
|
||||||
|
xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
|
||||||
|
psSS[ 1 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
|
||||||
|
psSS[ 1 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
|
||||||
|
psSS[ 1 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 );
|
||||||
|
psSS[ 1 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
*smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
|
||||||
|
last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
|
||||||
|
|
||||||
|
/* Find winner */
|
||||||
|
RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
|
||||||
|
Winner_ind = 0;
|
||||||
|
for( k = 1; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
|
||||||
|
RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
|
||||||
|
Winner_ind = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase RD values of expired states */
|
||||||
|
Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
|
||||||
|
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
|
||||||
|
psSampleState[ k ][ 0 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 0 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );
|
||||||
|
psSampleState[ k ][ 1 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 1 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );
|
||||||
|
SKP_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find worst in first set and best in second set */
|
||||||
|
RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
|
||||||
|
RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
|
||||||
|
RDmax_ind = 0;
|
||||||
|
RDmin_ind = 0;
|
||||||
|
for( k = 1; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
/* find worst in first set */
|
||||||
|
if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
|
||||||
|
RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
|
||||||
|
RDmax_ind = k;
|
||||||
|
}
|
||||||
|
/* find best in second set */
|
||||||
|
if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
|
||||||
|
RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
|
||||||
|
RDmin_ind = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace a state if best from second set outperforms worst in first set */
|
||||||
|
if( RDmin_Q10 < RDmax_Q10 ) {
|
||||||
|
SKP_Silk_copy_del_dec_state( &psDelDec[ RDmax_ind ], &psDelDec[ RDmin_ind ], i );
|
||||||
|
SKP_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write samples from winner to output and long-term filter states */
|
||||||
|
psDD = &psDelDec[ Winner_ind ];
|
||||||
|
if( subfr > 0 || i >= decisionDelay ) {
|
||||||
|
q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||||
|
xq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
|
||||||
|
SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
|
||||||
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ];
|
||||||
|
sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q16[ last_smple_idx ];
|
||||||
|
}
|
||||||
|
NSQ->sLTP_shp_buf_idx++;
|
||||||
|
NSQ->sLTP_buf_idx++;
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
psDD = &psDelDec[ k ];
|
||||||
|
psSS = &psSampleState[ k ][ 0 ];
|
||||||
|
psDD->LF_AR_Q12 = psSS->LF_AR_Q12;
|
||||||
|
psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
|
||||||
|
psDD->Xq_Q10[ *smpl_buf_idx ] = SKP_RSHIFT( psSS->xq_Q14, 4 );
|
||||||
|
psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
|
||||||
|
psDD->Pred_Q16[ *smpl_buf_idx ] = psSS->LPC_exc_Q16;
|
||||||
|
psDD->Shape_Q10[ *smpl_buf_idx ] = psSS->sLTP_shp_Q10;
|
||||||
|
psDD->Seed = SKP_ADD_RSHIFT32( psDD->Seed, psSS->Q_Q10, 10 );
|
||||||
|
psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
|
||||||
|
psDD->RD_Q10 = psSS->RD_Q10;
|
||||||
|
psDD->Gain_Q16[ *smpl_buf_idx ] = Gain_Q16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Update LPC states */
|
||||||
|
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
psDD = &psDelDec[ k ];
|
||||||
|
SKP_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(
|
||||||
|
SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
|
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||||
|
const SKP_int16 x[], /* I Input in Q0 */
|
||||||
|
SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
||||||
|
SKP_int subfr_length, /* I Length of input */
|
||||||
|
const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
||||||
|
SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
||||||
|
SKP_int subfr, /* I Subframe number */
|
||||||
|
SKP_int nStatesDelayedDecision, /* I Number of del dec states */
|
||||||
|
SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */
|
||||||
|
const SKP_int LTP_scale_Q14, /* I LTP state scaling */
|
||||||
|
const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
|
||||||
|
const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, lag;
|
||||||
|
SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
|
||||||
|
NSQ_del_dec_struct *psDD;
|
||||||
|
|
||||||
|
inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 );
|
||||||
|
inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
|
||||||
|
lag = pitchL[ subfr ];
|
||||||
|
|
||||||
|
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
||||||
|
if( NSQ->rewhite_flag ) {
|
||||||
|
inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
|
||||||
|
if( subfr == 0 ) {
|
||||||
|
/* Do LTP downscaling */
|
||||||
|
inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
|
||||||
|
}
|
||||||
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
|
SKP_assert( i < MAX_FRAME_LENGTH );
|
||||||
|
sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust for changing gain */
|
||||||
|
if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {
|
||||||
|
gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );
|
||||||
|
|
||||||
|
/* Scale long-term shaping state */
|
||||||
|
for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) {
|
||||||
|
NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale long-term prediction state */
|
||||||
|
if( NSQ->rewhite_flag == 0 ) {
|
||||||
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
|
sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||||
|
psDD = &psDelDec[ k ];
|
||||||
|
|
||||||
|
/* Scale scalar states */
|
||||||
|
psDD->LF_AR_Q12 = SKP_SMULWW( gain_adj_Q16, psDD->LF_AR_Q12 );
|
||||||
|
|
||||||
|
/* Scale short-term prediction and shaping states */
|
||||||
|
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
|
||||||
|
psDD->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
|
||||||
|
}
|
||||||
|
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
|
||||||
|
psDD->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
|
||||||
|
}
|
||||||
|
for( i = 0; i < DECISION_DELAY; i++ ) {
|
||||||
|
psDD->Pred_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Pred_Q16[ i ] );
|
||||||
|
psDD->Shape_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Shape_Q10[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale input */
|
||||||
|
for( i = 0; i < subfr_length; i++ ) {
|
||||||
|
x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save inv_gain */
|
||||||
|
SKP_assert( inv_gain_Q16 != 0 );
|
||||||
|
NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE void SKP_Silk_copy_del_dec_state(
|
||||||
|
NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */
|
||||||
|
NSQ_del_dec_struct *DD_src, /* I Src del dec state */
|
||||||
|
SKP_int LPC_state_idx /* I Index to LPC buffer */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_memcpy( DD_dst->RandState, DD_src->RandState, sizeof( DD_src->RandState ) );
|
||||||
|
SKP_memcpy( DD_dst->Q_Q10, DD_src->Q_Q10, sizeof( DD_src->Q_Q10 ) );
|
||||||
|
SKP_memcpy( DD_dst->Pred_Q16, DD_src->Pred_Q16, sizeof( DD_src->Pred_Q16 ) );
|
||||||
|
SKP_memcpy( DD_dst->Shape_Q10, DD_src->Shape_Q10, sizeof( DD_src->Shape_Q10 ) );
|
||||||
|
SKP_memcpy( DD_dst->Xq_Q10, DD_src->Xq_Q10, sizeof( DD_src->Xq_Q10 ) );
|
||||||
|
SKP_memcpy( DD_dst->sAR2_Q14, DD_src->sAR2_Q14, sizeof( DD_src->sAR2_Q14 ) );
|
||||||
|
SKP_memcpy( &DD_dst->sLPC_Q14[ LPC_state_idx ], &DD_src->sLPC_Q14[ LPC_state_idx ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
|
||||||
|
DD_dst->LF_AR_Q12 = DD_src->LF_AR_Q12;
|
||||||
|
DD_dst->Seed = DD_src->Seed;
|
||||||
|
DD_dst->SeedInit = DD_src->SeedInit;
|
||||||
|
DD_dst->RD_Q10 = DD_src->RD_Q10;
|
||||||
|
}
|
418
app/src/main/cpp/src/SKP_Silk_PLC.c
Normal file
418
app/src/main/cpp/src/SKP_Silk_PLC.c
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
#include "SKP_Silk_PLC.h"
|
||||||
|
|
||||||
|
#define NB_ATT 2
|
||||||
|
static const SKP_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */
|
||||||
|
static const SKP_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */
|
||||||
|
static const SKP_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */
|
||||||
|
|
||||||
|
void SKP_Silk_PLC_Reset(
|
||||||
|
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
psDec->sPLC.pitchL_Q8 = SKP_RSHIFT( psDec->frame_length, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SKP_Silk_PLC(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
|
||||||
|
SKP_int16 signal[], /* O Concealed signal */
|
||||||
|
SKP_int length, /* I length of residual */
|
||||||
|
SKP_int lost /* I Loss flag */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* PLC control function */
|
||||||
|
if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) {
|
||||||
|
SKP_Silk_PLC_Reset( psDec );
|
||||||
|
psDec->sPLC.fs_kHz = psDec->fs_kHz;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lost ) {
|
||||||
|
/****************************/
|
||||||
|
/* Generate Signal */
|
||||||
|
/****************************/
|
||||||
|
SKP_Silk_PLC_conceal( psDec, psDecCtrl, signal, length );
|
||||||
|
|
||||||
|
psDec->lossCnt++;
|
||||||
|
} else {
|
||||||
|
/****************************/
|
||||||
|
/* Update state */
|
||||||
|
/****************************/
|
||||||
|
SKP_Silk_PLC_update( psDec, psDecCtrl, signal, length );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/* Update state of PLC */
|
||||||
|
/**************************************************/
|
||||||
|
void SKP_Silk_PLC_update(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* (I/O) Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* (I/O) Decoder control */
|
||||||
|
SKP_int16 signal[],
|
||||||
|
SKP_int length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14;
|
||||||
|
SKP_int i, j;
|
||||||
|
SKP_Silk_PLC_struct *psPLC;
|
||||||
|
|
||||||
|
psPLC = &psDec->sPLC;
|
||||||
|
|
||||||
|
/* Update parameters used in case of packet loss */
|
||||||
|
psDec->prev_sigtype = psDecCtrl->sigtype;
|
||||||
|
LTP_Gain_Q14 = 0;
|
||||||
|
if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Find the parameters for the last subframe which contains a pitch pulse */
|
||||||
|
for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ NB_SUBFR - 1 ]; j++ ) {
|
||||||
|
temp_LTP_Gain_Q14 = 0;
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( NB_SUBFR - 1 - j ) * LTP_ORDER + i ];
|
||||||
|
}
|
||||||
|
if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) {
|
||||||
|
LTP_Gain_Q14 = temp_LTP_Gain_Q14;
|
||||||
|
SKP_memcpy( psPLC->LTPCoef_Q14,
|
||||||
|
&psDecCtrl->LTPCoef_Q14[ SKP_SMULBB( NB_SUBFR - 1 - j, LTP_ORDER ) ],
|
||||||
|
LTP_ORDER * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
psPLC->pitchL_Q8 = SKP_LSHIFT( psDecCtrl->pitchL[ NB_SUBFR - 1 - j ], 8 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_SINGLE_TAP
|
||||||
|
SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );
|
||||||
|
psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Limit LT coefs */
|
||||||
|
if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) {
|
||||||
|
SKP_int scale_Q10;
|
||||||
|
SKP_int32 tmp;
|
||||||
|
|
||||||
|
tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 );
|
||||||
|
scale_Q10 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) );
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 );
|
||||||
|
}
|
||||||
|
} else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) {
|
||||||
|
SKP_int scale_Q14;
|
||||||
|
SKP_int32 tmp;
|
||||||
|
|
||||||
|
tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 );
|
||||||
|
scale_Q14 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) );
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
psPLC->pitchL_Q8 = SKP_LSHIFT( SKP_SMULBB( psDec->fs_kHz, 18 ), 8 );
|
||||||
|
SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save LPC coeficients */
|
||||||
|
SKP_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) );
|
||||||
|
psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;
|
||||||
|
|
||||||
|
/* Save Gains */
|
||||||
|
SKP_memcpy( psPLC->prevGain_Q16, psDecCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SKP_Silk_PLC_conceal(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[], /* O concealed signal */
|
||||||
|
SKP_int length /* I length of residual */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, j, k;
|
||||||
|
SKP_int16 *B_Q14, exc_buf[ MAX_FRAME_LENGTH ], *exc_buf_ptr;
|
||||||
|
SKP_int16 rand_scale_Q14;
|
||||||
|
union {
|
||||||
|
SKP_int16 as_int16[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int32 as_int32[ MAX_LPC_ORDER / 2 ];
|
||||||
|
} A_Q12_tmp;
|
||||||
|
SKP_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15;
|
||||||
|
SKP_int lag, idx, sLTP_buf_idx, shift1, shift2;
|
||||||
|
SKP_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr;
|
||||||
|
SKP_int32 sig_Q10[ MAX_FRAME_LENGTH ], *sig_Q10_ptr, LPC_exc_Q10, LPC_pred_Q10, LTP_pred_Q14;
|
||||||
|
SKP_Silk_PLC_struct *psPLC;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 Atmp;
|
||||||
|
#endif
|
||||||
|
psPLC = &psDec->sPLC;
|
||||||
|
|
||||||
|
/* Update LTP buffer */
|
||||||
|
SKP_memcpy( psDec->sLTP_Q16, &psDec->sLTP_Q16[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
/* LPC concealment. Apply BWE to previous LPC */
|
||||||
|
SKP_Silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, BWE_COEF_Q16 );
|
||||||
|
|
||||||
|
/* Find random noise component */
|
||||||
|
/* Scale previous excitation signal */
|
||||||
|
exc_buf_ptr = exc_buf;
|
||||||
|
for( k = ( NB_SUBFR >> 1 ); k < NB_SUBFR; k++ ) {
|
||||||
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
|
exc_buf_ptr[ i ] = ( SKP_int16 )SKP_RSHIFT(
|
||||||
|
SKP_SMULWW( psDec->exc_Q10[ i + k * psDec->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
|
||||||
|
}
|
||||||
|
exc_buf_ptr += psDec->subfr_length;
|
||||||
|
}
|
||||||
|
/* Find the subframe with lowest energy of the last two and use that as random noise generator */
|
||||||
|
SKP_Silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psDec->subfr_length );
|
||||||
|
SKP_Silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psDec->subfr_length );
|
||||||
|
|
||||||
|
if( SKP_RSHIFT( energy1, shift2 ) < SKP_RSHIFT( energy2, shift1 ) ) {
|
||||||
|
/* First sub-frame has lowest energy */
|
||||||
|
rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, 3 * psDec->subfr_length - RAND_BUF_SIZE ) ];
|
||||||
|
} else {
|
||||||
|
/* Second sub-frame has lowest energy */
|
||||||
|
rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, psDec->frame_length - RAND_BUF_SIZE ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup Gain to random noise component */
|
||||||
|
B_Q14 = psPLC->LTPCoef_Q14;
|
||||||
|
rand_scale_Q14 = psPLC->randScale_Q14;
|
||||||
|
|
||||||
|
/* Setup attenuation gains */
|
||||||
|
harm_Gain_Q15 = HARM_ATT_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||||
|
if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||||
|
} else {
|
||||||
|
rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First Lost frame */
|
||||||
|
if( psDec->lossCnt == 0 ) {
|
||||||
|
rand_scale_Q14 = (1 << 14 );
|
||||||
|
|
||||||
|
/* Reduce random noise Gain for voiced frames */
|
||||||
|
if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
rand_scale_Q14 -= B_Q14[ i ];
|
||||||
|
}
|
||||||
|
rand_scale_Q14 = SKP_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
|
||||||
|
rand_scale_Q14 = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduce random noise for unvoiced frames with high LPC gain */
|
||||||
|
if( psDec->prev_sigtype == SIG_TYPE_UNVOICED ) {
|
||||||
|
SKP_int32 invGain_Q30, down_scale_Q30;
|
||||||
|
|
||||||
|
SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, psPLC->prevLPC_Q12, psDec->LPC_order );
|
||||||
|
|
||||||
|
down_scale_Q30 = SKP_min_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
|
||||||
|
down_scale_Q30 = SKP_max_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
|
||||||
|
down_scale_Q30 = SKP_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES );
|
||||||
|
|
||||||
|
rand_Gain_Q15 = SKP_RSHIFT( SKP_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rand_seed = psPLC->rand_seed;
|
||||||
|
lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
|
||||||
|
sLTP_buf_idx = psDec->frame_length;
|
||||||
|
|
||||||
|
/***************************/
|
||||||
|
/* LTP synthesis filtering */
|
||||||
|
/***************************/
|
||||||
|
sig_Q10_ptr = sig_Q10;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
/* Setup pointer */
|
||||||
|
pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
|
rand_seed = SKP_RAND( rand_seed );
|
||||||
|
idx = SKP_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK;
|
||||||
|
|
||||||
|
/* Unrolled loop */
|
||||||
|
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
|
||||||
|
pred_lag_ptr++;
|
||||||
|
|
||||||
|
/* Generate LPC residual */
|
||||||
|
LPC_exc_Q10 = SKP_LSHIFT( SKP_SMULWB( rand_ptr[ idx ], rand_scale_Q14 ), 2 ); /* Random noise part */
|
||||||
|
LPC_exc_Q10 = SKP_ADD32( LPC_exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); /* Harmonic part */
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
|
||||||
|
sLTP_buf_idx++;
|
||||||
|
|
||||||
|
/* Save LPC residual */
|
||||||
|
sig_Q10_ptr[ i ] = LPC_exc_Q10;
|
||||||
|
}
|
||||||
|
sig_Q10_ptr += psDec->subfr_length;
|
||||||
|
/* Gradually reduce LTP gain */
|
||||||
|
for( j = 0; j < LTP_ORDER; j++ ) {
|
||||||
|
B_Q14[ j ] = SKP_RSHIFT( SKP_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
|
||||||
|
}
|
||||||
|
/* Gradually reduce excitation gain */
|
||||||
|
rand_scale_Q14 = SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
|
||||||
|
|
||||||
|
/* Slowly increase pitch lag */
|
||||||
|
psPLC->pitchL_Q8 += SKP_SMULWB( psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
|
||||||
|
psPLC->pitchL_Q8 = SKP_min_32( psPLC->pitchL_Q8, SKP_LSHIFT( SKP_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) );
|
||||||
|
lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************/
|
||||||
|
/* LPC synthesis filtering */
|
||||||
|
/***************************/
|
||||||
|
sig_Q10_ptr = sig_Q10;
|
||||||
|
/* Preload LPC coeficients to array on stack. Gives small performance gain */
|
||||||
|
SKP_memcpy( A_Q12_tmp.as_int16, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
|
||||||
|
SKP_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
for( i = 0; i < psDec->subfr_length; i++ ){
|
||||||
|
/* partly unrolled */
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
|
||||||
|
/* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
|
||||||
|
/* loaded in reverse order and the code will give the wrong result. In that case swapping */
|
||||||
|
/* the SMLAWB and SMLAWT instructions should solve the problem. */
|
||||||
|
Atmp = A_Q12_tmp.as_int32[ 0 ]; /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp );
|
||||||
|
Atmp = A_Q12_tmp.as_int32[ 1 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp );
|
||||||
|
Atmp = A_Q12_tmp.as_int32[ 2 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp );
|
||||||
|
Atmp = A_Q12_tmp.as_int32[ 3 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp );
|
||||||
|
Atmp = A_Q12_tmp.as_int32[ 4 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
|
||||||
|
for( j = 10 ; j < psDec->LPC_order ; j+=2 ) {
|
||||||
|
Atmp = A_Q12_tmp.as_int32[ j / 2 ];
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 - j ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 - j ], Atmp );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp.as_int16[ 0 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp.as_int16[ 1 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp.as_int16[ 2 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp.as_int16[ 3 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp.as_int16[ 4 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp.as_int16[ 5 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp.as_int16[ 6 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp.as_int16[ 7 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp.as_int16[ 8 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp.as_int16[ 9 ] );
|
||||||
|
|
||||||
|
for( j = 10; j < psDec->LPC_order; j++ ) {
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp.as_int16[ j ] );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Add prediction to LPC residual */
|
||||||
|
sig_Q10_ptr[ i ] = SKP_ADD32( sig_Q10_ptr[ i ], LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( sig_Q10_ptr[ i ], 4 );
|
||||||
|
}
|
||||||
|
sig_Q10_ptr += psDec->subfr_length;
|
||||||
|
/* Update LPC filter state */
|
||||||
|
SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale with Gain */
|
||||||
|
for( i = 0; i < psDec->frame_length; i++ ) {
|
||||||
|
signal[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( sig_Q10[ i ], psPLC->prevGain_Q16[ NB_SUBFR - 1 ] ), 10 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************/
|
||||||
|
/* Update states */
|
||||||
|
/**************************************/
|
||||||
|
psPLC->rand_seed = rand_seed;
|
||||||
|
psPLC->randScale_Q14 = rand_scale_Q14;
|
||||||
|
for( i = 0; i < NB_SUBFR; i++ ) {
|
||||||
|
psDecCtrl->pitchL[ i ] = lag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Glues concealed frames with new good recieved frames */
|
||||||
|
void SKP_Silk_PLC_glue_frames(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[], /* I/O signal */
|
||||||
|
SKP_int length /* I length of residual */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, energy_shift;
|
||||||
|
SKP_int32 energy;
|
||||||
|
SKP_Silk_PLC_struct *psPLC;
|
||||||
|
psPLC = &psDec->sPLC;
|
||||||
|
|
||||||
|
if( psDec->lossCnt ) {
|
||||||
|
/* Calculate energy in concealed residual */
|
||||||
|
SKP_Silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, signal, length );
|
||||||
|
|
||||||
|
psPLC->last_frame_lost = 1;
|
||||||
|
} else {
|
||||||
|
if( psDec->sPLC.last_frame_lost ) {
|
||||||
|
/* Calculate residual in decoded signal if last frame was lost */
|
||||||
|
SKP_Silk_sum_sqr_shift( &energy, &energy_shift, signal, length );
|
||||||
|
|
||||||
|
/* Normalize energies */
|
||||||
|
if( energy_shift > psPLC->conc_energy_shift ) {
|
||||||
|
psPLC->conc_energy = SKP_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift );
|
||||||
|
} else if( energy_shift < psPLC->conc_energy_shift ) {
|
||||||
|
energy = SKP_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fade in the energy difference */
|
||||||
|
if( energy > psPLC->conc_energy ) {
|
||||||
|
SKP_int32 frac_Q24, LZ;
|
||||||
|
SKP_int32 gain_Q12, slope_Q12;
|
||||||
|
|
||||||
|
LZ = SKP_Silk_CLZ32( psPLC->conc_energy );
|
||||||
|
LZ = LZ - 1;
|
||||||
|
psPLC->conc_energy = SKP_LSHIFT( psPLC->conc_energy, LZ );
|
||||||
|
energy = SKP_RSHIFT( energy, SKP_max_32( 24 - LZ, 0 ) );
|
||||||
|
|
||||||
|
frac_Q24 = SKP_DIV32( psPLC->conc_energy, SKP_max( energy, 1 ) );
|
||||||
|
|
||||||
|
gain_Q12 = SKP_Silk_SQRT_APPROX( frac_Q24 );
|
||||||
|
slope_Q12 = SKP_DIV32_16( ( 1 << 12 ) - gain_Q12, length );
|
||||||
|
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
signal[ i ] = SKP_RSHIFT( SKP_MUL( gain_Q12, signal[ i ] ), 12 );
|
||||||
|
gain_Q12 += slope_Q12;
|
||||||
|
gain_Q12 = SKP_min( gain_Q12, ( 1 << 12 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
psPLC->last_frame_lost = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
79
app/src/main/cpp/src/SKP_Silk_PLC.h
Normal file
79
app/src/main/cpp/src/SKP_Silk_PLC.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SKP_SILK_PLC_FIX_H
|
||||||
|
#define SKP_SILK_PLC_FIX_H
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
#define BWE_COEF_Q16 64880 /* 0.99 in Q16 */
|
||||||
|
#define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */
|
||||||
|
#define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */
|
||||||
|
#define MAX_PITCH_LAG_MS 18
|
||||||
|
#define SA_THRES_Q8 50
|
||||||
|
#define USE_SINGLE_TAP 1
|
||||||
|
#define RAND_BUF_SIZE 128
|
||||||
|
#define RAND_BUF_MASK (RAND_BUF_SIZE - 1)
|
||||||
|
#define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */
|
||||||
|
#define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */
|
||||||
|
#define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */
|
||||||
|
|
||||||
|
void SKP_Silk_PLC_Reset(
|
||||||
|
SKP_Silk_decoder_state *psDec /* I/O Decoder state */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_PLC(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[], /* I/O signal */
|
||||||
|
SKP_int length, /* I length of residual */
|
||||||
|
SKP_int lost /* I Loss flag */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_PLC_update(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[],
|
||||||
|
SKP_int length
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_PLC_conceal(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[], /* O LPC residual signal */
|
||||||
|
SKP_int length /* I length of signal */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_PLC_glue_frames(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int16 signal[], /* I/O signal */
|
||||||
|
SKP_int length /* I length of signal */
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
663
app/src/main/cpp/src/SKP_Silk_SigProc_FIX.h
Normal file
663
app/src/main/cpp/src/SKP_Silk_SigProc_FIX.h
Normal file
@ -0,0 +1,663 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef _SKP_SILK_SIGPROC_FIX_H_
|
||||||
|
#define _SKP_SILK_SIGPROC_FIX_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SKP_Silk_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */
|
||||||
|
#define SKP_Silk_MAX_CORRELATION_LENGTH 640 /* max input length to the correlation */
|
||||||
|
#include "SKP_Silk_typedef.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h> /* for abs() */
|
||||||
|
#include "SKP_Silk_resampler_structs.h"
|
||||||
|
|
||||||
|
#ifndef NO_ASM
|
||||||
|
# if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__)
|
||||||
|
# define EMBEDDED_ARM 4
|
||||||
|
# define EMBEDDED_ARMv4
|
||||||
|
# include "SKP_Silk_macros_arm.h"
|
||||||
|
# elif defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__)
|
||||||
|
# define EMBEDDED_ARM 5
|
||||||
|
# define EMBEDDED_ARMv5
|
||||||
|
# include "SKP_Silk_macros_arm.h"
|
||||||
|
# elif defined (__ARM_ARCH_6__) ||defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||||
|
# define EMBEDDED_ARM 6
|
||||||
|
# define EMBEDDED_ARMv6
|
||||||
|
# include "SKP_Silk_macros_arm.h"
|
||||||
|
# elif defined (__ARM_ARCH_7A__) && defined (__ARM_NEON__)
|
||||||
|
# define EMBEDDED_ARM 7
|
||||||
|
# define EMBEDDED_ARMv6
|
||||||
|
# include "SKP_Silk_macros_arm.h"
|
||||||
|
# elif defined (__ARM_ARCH_7A__)
|
||||||
|
# define EMBEDDED_ARM 6
|
||||||
|
# define EMBEDDED_ARMv6
|
||||||
|
# include "SKP_Silk_macros_arm.h"
|
||||||
|
# else
|
||||||
|
# include "SKP_Silk_macros.h"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define EMBEDDED_ARM 0
|
||||||
|
# include "SKP_Silk_macros.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* SIGNAL PROCESSING FUNCTIONS */
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initialize/reset the resampler state for a given pair of input/output sampling rates
|
||||||
|
*/
|
||||||
|
SKP_int SKP_Silk_resampler_init(
|
||||||
|
SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
|
||||||
|
SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */
|
||||||
|
SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Clear the states of all resampling filters, without resetting sampling rate ratio
|
||||||
|
*/
|
||||||
|
SKP_int SKP_Silk_resampler_clear(
|
||||||
|
SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Resampler: convert from one sampling rate to another
|
||||||
|
*/
|
||||||
|
SKP_int SKP_Silk_resampler(
|
||||||
|
SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
|
||||||
|
SKP_int16 out[], /* O: Output signal */
|
||||||
|
const SKP_int16 in[], /* I: Input signal */
|
||||||
|
SKP_int32 inLen /* I: Number of input samples */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Upsample 2x, low quality
|
||||||
|
*/
|
||||||
|
void SKP_Silk_resampler_up2(
|
||||||
|
SKP_int32 *S, /* I/O: State vector [ 2 ] */
|
||||||
|
SKP_int16 *out, /* O: Output signal [ 2 * len ] */
|
||||||
|
const SKP_int16 *in, /* I: Input signal [ len ] */
|
||||||
|
SKP_int32 len /* I: Number of input samples */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Downsample 2x, mediocre quality
|
||||||
|
*/
|
||||||
|
void SKP_Silk_resampler_down2(
|
||||||
|
SKP_int32 *S, /* I/O: State vector [ 2 ] */
|
||||||
|
SKP_int16 *out, /* O: Output signal [ len ] */
|
||||||
|
const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */
|
||||||
|
SKP_int32 inLen /* I: Number of input samples */
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Downsample by a factor 2/3, low quality
|
||||||
|
*/
|
||||||
|
void SKP_Silk_resampler_down2_3(
|
||||||
|
SKP_int32 *S, /* I/O: State vector [ 6 ] */
|
||||||
|
SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */
|
||||||
|
const SKP_int16 *in, /* I: Input signal [ inLen ] */
|
||||||
|
SKP_int32 inLen /* I: Number of input samples */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Downsample by a factor 3, low quality
|
||||||
|
*/
|
||||||
|
void SKP_Silk_resampler_down3(
|
||||||
|
SKP_int32 *S, /* I/O: State vector [ 8 ] */
|
||||||
|
SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */
|
||||||
|
const SKP_int16 *in, /* I: Input signal [ inLen ] */
|
||||||
|
SKP_int32 inLen /* I: Number of input samples */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* second order ARMA filter
|
||||||
|
* can handle (slowly) varying coefficients
|
||||||
|
*/
|
||||||
|
void SKP_Silk_biquad(
|
||||||
|
const SKP_int16 *in, /* I: input signal */
|
||||||
|
const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */
|
||||||
|
const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */
|
||||||
|
SKP_int32 *S, /* I/O: state vector [2] */
|
||||||
|
SKP_int16 *out, /* O: output signal */
|
||||||
|
const SKP_int32 len /* I: signal length */
|
||||||
|
);
|
||||||
|
/*!
|
||||||
|
* Second order ARMA filter;
|
||||||
|
* slower than biquad() but uses more precise coefficients
|
||||||
|
* can handle (slowly) varying coefficients
|
||||||
|
*/
|
||||||
|
void SKP_Silk_biquad_alt(
|
||||||
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
const SKP_int32 *B_Q28, /* I: MA coefficients [3] */
|
||||||
|
const SKP_int32 *A_Q28, /* I: AR coefficients [2] */
|
||||||
|
SKP_int32 *S, /* I/O: State vector [2] */
|
||||||
|
SKP_int16 *out, /* O: Output signal */
|
||||||
|
const SKP_int32 len /* I: Signal length (must be even) */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* variable order MA filter. Prediction error filter implementation. Coeficients negated and starting with coef to x[n - 1]
|
||||||
|
*/
|
||||||
|
void SKP_Silk_MA_Prediction(
|
||||||
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
|
||||||
|
SKP_int32 *S, /* I/O: State vector [order] */
|
||||||
|
SKP_int16 *out, /* O: Output signal */
|
||||||
|
const SKP_int32 len, /* I: Signal length */
|
||||||
|
const SKP_int32 order /* I: Filter order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* 16th order AR filter for LPC synthesis, coefficients are in Q12
|
||||||
|
*/
|
||||||
|
void SKP_Silk_LPC_synthesis_order16(
|
||||||
|
const SKP_int16 *in, /* I: excitation signal */
|
||||||
|
const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
|
||||||
|
const SKP_int32 Gain_Q26, /* I: gain */
|
||||||
|
SKP_int32 *S, /* I/O: state vector [16] */
|
||||||
|
SKP_int16 *out, /* O: output signal */
|
||||||
|
const SKP_int32 len /* I: signal length, must be multiple of 16 */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* variable order MA prediction error filter. */
|
||||||
|
/* Inverse filter of SKP_Silk_LPC_synthesis_filter */
|
||||||
|
void SKP_Silk_LPC_analysis_filter(
|
||||||
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
|
||||||
|
SKP_int16 *S, /* I/O: State vector [order] */
|
||||||
|
SKP_int16 *out, /* O: Output signal */
|
||||||
|
const SKP_int32 len, /* I: Signal length */
|
||||||
|
const SKP_int32 Order /* I: Filter order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* even order AR filter */
|
||||||
|
void SKP_Silk_LPC_synthesis_filter(
|
||||||
|
const SKP_int16 *in, /* I: excitation signal */
|
||||||
|
const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
|
||||||
|
const SKP_int32 Gain_Q26, /* I: gain */
|
||||||
|
SKP_int32 *S, /* I/O: state vector [Order] */
|
||||||
|
SKP_int16 *out, /* O: output signal */
|
||||||
|
const SKP_int32 len, /* I: signal length */
|
||||||
|
const SKP_int Order /* I: filter order, must be even */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Chirp (bandwidth expand) LP AR filter */
|
||||||
|
void SKP_Silk_bwexpander(
|
||||||
|
SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||||
|
const SKP_int d, /* I Length of ar */
|
||||||
|
SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Chirp (bandwidth expand) LP AR filter */
|
||||||
|
void SKP_Silk_bwexpander_32(
|
||||||
|
SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||||
|
const SKP_int d, /* I Length of ar */
|
||||||
|
SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Compute inverse of LPC prediction gain, and */
|
||||||
|
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||||
|
SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */
|
||||||
|
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
||||||
|
const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */
|
||||||
|
const SKP_int order /* I: Prediction order */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
|
||||||
|
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
||||||
|
const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */
|
||||||
|
const SKP_int order /* I: Prediction order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* split signal in two decimated bands using first-order allpass filters */
|
||||||
|
void SKP_Silk_ana_filt_bank_1(
|
||||||
|
const SKP_int16 *in, /* I: Input signal [N] */
|
||||||
|
SKP_int32 *S, /* I/O: State vector [2] */
|
||||||
|
SKP_int16 *outL, /* O: Low band [N/2] */
|
||||||
|
SKP_int16 *outH, /* O: High band [N/2] */
|
||||||
|
SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */
|
||||||
|
const SKP_int32 N /* I: Number of input samples */
|
||||||
|
);
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* SCALAR FUNCTIONS */
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/* Approximation of 128 * log2() (very close inverse of approx 2^() below) */
|
||||||
|
/* Convert input to a log scale */
|
||||||
|
SKP_int32 SKP_Silk_lin2log(const SKP_int32 inLin); /* I: Input in linear scale */
|
||||||
|
|
||||||
|
/* Approximation of a sigmoid function */
|
||||||
|
SKP_int SKP_Silk_sigm_Q15(SKP_int in_Q5);
|
||||||
|
|
||||||
|
/* approximation of 2^() (exact inverse of approx log2() above) */
|
||||||
|
/* convert input to a linear scale */
|
||||||
|
SKP_int32 SKP_Silk_log2lin(const SKP_int32 inLog_Q7); /* I: input on log scale */
|
||||||
|
|
||||||
|
/* Function that returns the maximum absolut value of the input vector */
|
||||||
|
SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
|
||||||
|
const SKP_int16 *vec, /* I Input vector [len] */
|
||||||
|
const SKP_int32 len /* I Length of input vector */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Compute number of bits to right shift the sum of squares of a vector */
|
||||||
|
/* of int16s to make it fit in an int32 */
|
||||||
|
void SKP_Silk_sum_sqr_shift(
|
||||||
|
SKP_int32 *energy, /* O Energy of x, after shifting to the right */
|
||||||
|
SKP_int *shift, /* O Number of bits right shift applied to energy */
|
||||||
|
const SKP_int16 *x, /* I Input vector */
|
||||||
|
SKP_int len /* I Length of input vector */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Calculates the reflection coefficients from the correlation sequence */
|
||||||
|
/* Faster than schur64(), but much less accurate. */
|
||||||
|
/* Uses SMLAWB(), requiring armv5E and higher. */
|
||||||
|
SKP_int32 SKP_Silk_schur( /* O: Returns residual energy */
|
||||||
|
SKP_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */
|
||||||
|
const SKP_int32 *c, /* I: correlations [order+1] */
|
||||||
|
const SKP_int32 order /* I: prediction order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Calculates the reflection coefficients from the correlation sequence */
|
||||||
|
/* Slower than schur(), but more accurate. */
|
||||||
|
/* Uses SMULL(), available on armv4 */
|
||||||
|
SKP_int32 SKP_Silk_schur64( /* O: returns residual energy */
|
||||||
|
SKP_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */
|
||||||
|
const SKP_int32 c[], /* I: Correlations [order+1] */
|
||||||
|
SKP_int32 order /* I: Prediction order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Step up function, converts reflection coefficients to prediction coefficients */
|
||||||
|
void SKP_Silk_k2a(
|
||||||
|
SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
|
||||||
|
const SKP_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */
|
||||||
|
const SKP_int32 order /* I: Prediction order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Step up function, converts reflection coefficients to prediction coefficients */
|
||||||
|
void SKP_Silk_k2a_Q16(
|
||||||
|
SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
|
||||||
|
const SKP_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */
|
||||||
|
const SKP_int32 order /* I: Prediction order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Apply sine window to signal vector. */
|
||||||
|
/* Window types: */
|
||||||
|
/* 1 -> sine window from 0 to pi/2 */
|
||||||
|
/* 2 -> sine window from pi/2 to pi */
|
||||||
|
/* Every other sample is linearly interpolated, for speed. */
|
||||||
|
void SKP_Silk_apply_sine_window(
|
||||||
|
SKP_int16 px_win[], /* O Pointer to windowed signal */
|
||||||
|
const SKP_int16 px[], /* I Pointer to input signal */
|
||||||
|
const SKP_int win_type, /* I Selects a window type */
|
||||||
|
const SKP_int length /* I Window length, multiple of 4 */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Compute autocorrelation */
|
||||||
|
void SKP_Silk_autocorr(
|
||||||
|
SKP_int32 *results, /* O Result (length correlationCount) */
|
||||||
|
SKP_int *scale, /* O Scaling of the correlation vector */
|
||||||
|
const SKP_int16 *inputData, /* I Input data to correlate */
|
||||||
|
const SKP_int inputDataSize, /* I Length of input */
|
||||||
|
const SKP_int correlationCount /* I Number of correlation taps to compute */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Pitch estimator */
|
||||||
|
#define SKP_Silk_PITCH_EST_MIN_COMPLEX 0
|
||||||
|
#define SKP_Silk_PITCH_EST_MID_COMPLEX 1
|
||||||
|
#define SKP_Silk_PITCH_EST_MAX_COMPLEX 2
|
||||||
|
|
||||||
|
void SKP_Silk_decode_pitch(
|
||||||
|
SKP_int lagIndex, /* I */
|
||||||
|
SKP_int contourIndex, /* O */
|
||||||
|
SKP_int pitch_lags[], /* O 4 pitch values */
|
||||||
|
SKP_int Fs_kHz /* I sampling frequency (kHz) */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_int SKP_Silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
|
||||||
|
const SKP_int16 *signal, /* I Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */
|
||||||
|
SKP_int *pitch_out, /* O 4 pitch lag values */
|
||||||
|
SKP_int *lagIndex, /* O Lag Index */
|
||||||
|
SKP_int *contourIndex, /* O Pitch contour Index */
|
||||||
|
SKP_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
|
||||||
|
SKP_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
|
||||||
|
const SKP_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
|
||||||
|
const SKP_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */
|
||||||
|
const SKP_int Fs_kHz, /* I Sample frequency (kHz) */
|
||||||
|
const SKP_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
|
||||||
|
const SKP_int forLJC /* I 1 if this function is called from LJC code, 0 otherwise. */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* parameter defining the size and accuracy of the piecewise linear */
|
||||||
|
/* cosine approximatin table. */
|
||||||
|
|
||||||
|
#define LSF_COS_TAB_SZ_FIX 128
|
||||||
|
/* rom table with cosine values */
|
||||||
|
extern const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ];
|
||||||
|
|
||||||
|
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
|
||||||
|
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
|
||||||
|
void SKP_Silk_A2NLSF(
|
||||||
|
SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
|
||||||
|
SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
|
||||||
|
const SKP_int d /* I Filter order (must be even) */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
||||||
|
void SKP_Silk_NLSF2A(
|
||||||
|
SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
|
||||||
|
const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
|
||||||
|
const SKP_int d /* i filter order (should be even) */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_insertion_sort_increasing(
|
||||||
|
SKP_int32 *a, /* I/O Unsorted / Sorted vector */
|
||||||
|
SKP_int *index, /* O: Index vector for the sorted elements */
|
||||||
|
const SKP_int L, /* I: Vector length */
|
||||||
|
const SKP_int K /* I: Number of correctly sorted positions */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_insertion_sort_decreasing_int16(
|
||||||
|
SKP_int16 *a, /* I/O: Unsorted / Sorted vector */
|
||||||
|
SKP_int *index, /* O: Index vector for the sorted elements */
|
||||||
|
const SKP_int L, /* I: Vector length */
|
||||||
|
const SKP_int K /* I: Number of correctly sorted positions */
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_insertion_sort_increasing_all_values(
|
||||||
|
SKP_int *a, /* I/O: Unsorted / Sorted vector */
|
||||||
|
const SKP_int L /* I: Vector length */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* NLSF stabilizer, for a single input data vector */
|
||||||
|
void SKP_Silk_NLSF_stabilize(
|
||||||
|
SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */
|
||||||
|
const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
|
||||||
|
const SKP_int L /* I: Number of NLSF parameters in the input vector */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Laroia low complexity NLSF weights */
|
||||||
|
void SKP_Silk_NLSF_VQ_weights_laroia(
|
||||||
|
SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */
|
||||||
|
const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
|
||||||
|
const SKP_int D /* I: Input vector dimension (even) */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Compute reflection coefficients from input signal */
|
||||||
|
void SKP_Silk_burg_modified(
|
||||||
|
SKP_int32 *res_nrg, /* O residual energy */
|
||||||
|
SKP_int *res_nrgQ, /* O residual energy Q value */
|
||||||
|
SKP_int32 A_Q16[], /* O prediction coefficients (length order) */
|
||||||
|
const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||||
|
const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
|
||||||
|
const SKP_int nb_subfr, /* I number of subframes stacked in x */
|
||||||
|
const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
|
||||||
|
const SKP_int D /* I order */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Copy and multiply a vector by a constant */
|
||||||
|
void SKP_Silk_scale_copy_vector16(
|
||||||
|
SKP_int16 *data_out,
|
||||||
|
const SKP_int16 *data_in,
|
||||||
|
SKP_int32 gain_Q16, /* I: gain in Q16 */
|
||||||
|
const SKP_int dataSize /* I: length */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Some for the LTP related function requires Q26 to work.*/
|
||||||
|
void SKP_Silk_scale_vector32_Q26_lshift_18(
|
||||||
|
SKP_int32 *data1, /* I/O: Q0/Q18 */
|
||||||
|
SKP_int32 gain_Q26, /* I: Q26 */
|
||||||
|
SKP_int dataSize /* I: length */
|
||||||
|
);
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* INLINE ARM MATH */
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/* return sum(inVec1[i]*inVec2[i]) */
|
||||||
|
/* inVec1 and inVec2 should be increasing ordered, and starting address should be 4 byte aligned. (a factor of 4)*/
|
||||||
|
SKP_int32 SKP_Silk_inner_prod_aligned(
|
||||||
|
const SKP_int16* const inVec1, /* I input vector 1 */
|
||||||
|
const SKP_int16* const inVec2, /* I input vector 2 */
|
||||||
|
const SKP_int len /* I vector lengths */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_int64 SKP_Silk_inner_prod16_aligned_64(
|
||||||
|
const SKP_int16 *inVec1, /* I input vector 1 */
|
||||||
|
const SKP_int16 *inVec2, /* I input vector 2 */
|
||||||
|
const SKP_int len /* I vector lengths */
|
||||||
|
);
|
||||||
|
/********************************************************************/
|
||||||
|
/* MACROS */
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating
|
||||||
|
left. Output is 32bit int.
|
||||||
|
Note: contemporary compilers recognize the C expressions below and
|
||||||
|
compile them into 'ror' instructions if available. No need for inline ASM! */
|
||||||
|
#if defined(EMBEDDED_MIPS)
|
||||||
|
/* For MIPS (and most likely for ARM! and >=i486) we don't have to handle
|
||||||
|
negative rot's as only 5 bits of rot are encoded into ROR instructions. */
|
||||||
|
SKP_INLINE SKP_int32 SKP_ROR32(SKP_int32 a32, SKP_int rot)
|
||||||
|
{
|
||||||
|
SKP_uint32 _x = (SKP_uint32) a32;
|
||||||
|
SKP_uint32 _r = (SKP_uint32) rot;
|
||||||
|
return (SKP_int32) ((_x << (32 - _r)) | (_x >> _r));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* PPC must use this generic implementation. */
|
||||||
|
SKP_INLINE SKP_int32 SKP_ROR32( SKP_int32 a32, SKP_int rot )
|
||||||
|
{
|
||||||
|
SKP_uint32 x = (SKP_uint32) a32;
|
||||||
|
SKP_uint32 r = (SKP_uint32) rot;
|
||||||
|
SKP_uint32 m = (SKP_uint32) -rot;
|
||||||
|
if(rot <= 0)
|
||||||
|
return (SKP_int32) ((x << m) | (x >> (32 - m)));
|
||||||
|
else
|
||||||
|
return (SKP_int32) ((x << (32 - r)) | (x >> r));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allocate SKP_int16 alligned to 4-byte memory address */
|
||||||
|
#if EMBEDDED_ARM
|
||||||
|
#if defined(_WIN32) && defined(_M_ARM)
|
||||||
|
#define SKP_DWORD_ALIGN __declspec(align(4))
|
||||||
|
#else
|
||||||
|
#define SKP_DWORD_ALIGN __attribute__((aligned(4)))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define SKP_DWORD_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Useful Macros that can be adjusted to other platforms */
|
||||||
|
#define SKP_memcpy(a, b, c) memcpy((a), (b), (c)) /* Dest, Src, ByteCount */
|
||||||
|
#define SKP_memset(a, b, c) memset((a), (b), (c)) /* Dest, value, ByteCount */
|
||||||
|
#define SKP_memmove(a, b, c) memmove((a), (b), (c)) /* Dest, Src, ByteCount */
|
||||||
|
/* fixed point macros */
|
||||||
|
|
||||||
|
// (a32 * b32) output have to be 32bit int
|
||||||
|
#define SKP_MUL(a32, b32) ((a32) * (b32))
|
||||||
|
|
||||||
|
// (a32 * b32) output have to be 32bit uint
|
||||||
|
#define SKP_MUL_uint(a32, b32) SKP_MUL(a32, b32)
|
||||||
|
|
||||||
|
// a32 + (b32 * c32) output have to be 32bit int
|
||||||
|
#define SKP_MLA(a32, b32, c32) SKP_ADD32((a32),((b32) * (c32)))
|
||||||
|
|
||||||
|
/* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
|
||||||
|
#define SKP_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16))
|
||||||
|
|
||||||
|
/* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
|
||||||
|
#define SKP_SMLATT(a32, b32, c32) SKP_ADD32((a32),((b32) >> 16) * ((c32) >> 16))
|
||||||
|
|
||||||
|
#define SKP_SMLALBB(a64, b16, c16) SKP_ADD64((a64),(SKP_int64)((SKP_int32)(b16) * (SKP_int32)(c16)))
|
||||||
|
|
||||||
|
// (a32 * b32)
|
||||||
|
#define SKP_SMULL(a32, b32) ((SKP_int64)(a32) * /*(SKP_int64)*/(b32))
|
||||||
|
|
||||||
|
/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
|
||||||
|
(just standard two's complement implementation-specific behaviour) */
|
||||||
|
#define SKP_ADD32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) + (SKP_uint32)(b)))
|
||||||
|
/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
|
||||||
|
(just standard two's complement implementation-specific behaviour) */
|
||||||
|
#define SKP_SUB32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) - (SKP_uint32)(b)))
|
||||||
|
|
||||||
|
/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
|
||||||
|
#define SKP_MLA_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), (SKP_uint32)(b32) * (SKP_uint32)(c32))
|
||||||
|
#ifndef SKP_SMLABB_ovflw
|
||||||
|
#define SKP_SMLABB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULBB((b32),(c32)))
|
||||||
|
#endif
|
||||||
|
#define SKP_SMLATT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULTT((b32),(c32)))
|
||||||
|
#define SKP_SMLAWB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWB((b32),(c32)))
|
||||||
|
#define SKP_SMLAWT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWT((b32),(c32)))
|
||||||
|
#define SKP_DIV32_16(a32, b16) ((SKP_int32)((a32) / (b16)))
|
||||||
|
#define SKP_DIV32(a32, b32) ((SKP_int32)((a32) / (b32)))
|
||||||
|
|
||||||
|
#define SKP_ADD32(a, b) ((a) + (b))
|
||||||
|
#define SKP_ADD64(a, b) ((a) + (b))
|
||||||
|
|
||||||
|
#define SKP_SUB32(a, b) ((a) - (b))
|
||||||
|
|
||||||
|
#define SKP_SAT16(a) ((a) > SKP_int16_MAX ? SKP_int16_MAX : \
|
||||||
|
((a) < SKP_int16_MIN ? SKP_int16_MIN : (a)))
|
||||||
|
#define SKP_SAT32(a) ((a) > SKP_int32_MAX ? SKP_int32_MAX : \
|
||||||
|
((a) < SKP_int32_MIN ? SKP_int32_MIN : (a)))
|
||||||
|
|
||||||
|
#define SKP_CHECK_FIT16(a) (a)
|
||||||
|
#define SKP_CHECK_FIT32(a) (a)
|
||||||
|
|
||||||
|
#define SKP_ADD_SAT16(a, b) (SKP_int16)SKP_SAT16( SKP_ADD32( (SKP_int32)(a), (b) ) )
|
||||||
|
|
||||||
|
/* Add with saturation for positive input values */
|
||||||
|
#define SKP_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? SKP_int32_MAX : ((a)+(b)))
|
||||||
|
|
||||||
|
#define SKP_LSHIFT32(a, shift) ((a)<<(shift)) // shift >= 0, shift < 32
|
||||||
|
#define SKP_LSHIFT64(a, shift) ((a)<<(shift)) // shift >= 0, shift < 64
|
||||||
|
#define SKP_LSHIFT(a, shift) SKP_LSHIFT32(a, shift) // shift >= 0, shift < 32
|
||||||
|
|
||||||
|
#define SKP_RSHIFT32(a, shift) ((a)>>(shift)) // shift >= 0, shift < 32
|
||||||
|
#define SKP_RSHIFT64(a, shift) ((a)>>(shift)) // shift >= 0, shift < 64
|
||||||
|
#define SKP_RSHIFT(a, shift) SKP_RSHIFT32(a, shift) // shift >= 0, shift < 32
|
||||||
|
|
||||||
|
/* saturates before shifting */
|
||||||
|
#define SKP_LSHIFT_SAT32(a, shift) (SKP_LSHIFT32( SKP_LIMIT_32( (a), SKP_RSHIFT32( SKP_int32_MIN, (shift) ), \
|
||||||
|
SKP_RSHIFT32( SKP_int32_MAX, (shift) ) ), (shift) ))
|
||||||
|
|
||||||
|
#define SKP_LSHIFT_ovflw(a, shift) ((a)<<(shift)) // shift >= 0, allowed to overflow
|
||||||
|
#define SKP_LSHIFT_uint(a, shift) ((a)<<(shift)) // shift >= 0
|
||||||
|
#define SKP_RSHIFT_uint(a, shift) ((a)>>(shift)) // shift >= 0
|
||||||
|
|
||||||
|
#define SKP_ADD_LSHIFT(a, b, shift) ((a) + SKP_LSHIFT((b), (shift))) // shift >= 0
|
||||||
|
#define SKP_ADD_LSHIFT32(a, b, shift) SKP_ADD32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0
|
||||||
|
#define SKP_ADD_RSHIFT(a, b, shift) ((a) + SKP_RSHIFT((b), (shift))) // shift >= 0
|
||||||
|
#define SKP_ADD_RSHIFT32(a, b, shift) SKP_ADD32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0
|
||||||
|
#define SKP_ADD_RSHIFT_uint(a, b, shift) ((a) + SKP_RSHIFT_uint((b), (shift))) // shift >= 0
|
||||||
|
#define SKP_SUB_LSHIFT32(a, b, shift) SKP_SUB32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0
|
||||||
|
#define SKP_SUB_RSHIFT32(a, b, shift) SKP_SUB32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0
|
||||||
|
|
||||||
|
/* Requires that shift > 0 */
|
||||||
|
#define SKP_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
|
||||||
|
#define SKP_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
|
||||||
|
|
||||||
|
/* Number of rightshift required to fit the multiplication */
|
||||||
|
#define SKP_NSHIFT_MUL_32_32(a, b) ( -(31- (32-SKP_Silk_CLZ32(SKP_abs(a)) + (32-SKP_Silk_CLZ32(SKP_abs(b))))) )
|
||||||
|
|
||||||
|
#define SKP_min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define SKP_max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
/* Macro to convert floating-point constants to fixed-point */
|
||||||
|
#define SKP_FIX_CONST( C, Q ) ((SKP_int32)((C) * ((SKP_int64)1 << (Q)) + 0.5))
|
||||||
|
|
||||||
|
/* SKP_min() versions with typecast in the function call */
|
||||||
|
SKP_INLINE SKP_int SKP_min_int(SKP_int a, SKP_int b)
|
||||||
|
{
|
||||||
|
return (((a) < (b)) ? (a) : (b));
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int32 SKP_min_32(SKP_int32 a, SKP_int32 b)
|
||||||
|
{
|
||||||
|
return (((a) < (b)) ? (a) : (b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SKP_min() versions with typecast in the function call */
|
||||||
|
SKP_INLINE SKP_int SKP_max_int(SKP_int a, SKP_int b)
|
||||||
|
{
|
||||||
|
return (((a) > (b)) ? (a) : (b));
|
||||||
|
}
|
||||||
|
SKP_INLINE SKP_int16 SKP_max_16(SKP_int16 a, SKP_int16 b)
|
||||||
|
{
|
||||||
|
return (((a) > (b)) ? (a) : (b));
|
||||||
|
}
|
||||||
|
SKP_INLINE SKP_int32 SKP_max_32(SKP_int32 a, SKP_int32 b)
|
||||||
|
{
|
||||||
|
return (((a) > (b)) ? (a) : (b));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SKP_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
|
||||||
|
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))
|
||||||
|
|
||||||
|
#define SKP_LIMIT_int SKP_LIMIT
|
||||||
|
#define SKP_LIMIT_32 SKP_LIMIT
|
||||||
|
|
||||||
|
//#define SKP_non_neg(a) ((a) & ((-(a)) >> (8 * sizeof(a) - 1))) /* doesn't seem faster than SKP_max(0, a);
|
||||||
|
|
||||||
|
#define SKP_abs(a) (((a) > 0) ? (a) : -(a)) // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN
|
||||||
|
#define SKP_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31))
|
||||||
|
|
||||||
|
/* PSEUDO-RANDOM GENERATOR */
|
||||||
|
/* Make sure to store the result as the seed for the next call (also in between */
|
||||||
|
/* frames), otherwise result won't be random at all. When only using some of the */
|
||||||
|
/* bits, take the most significant bits by right-shifting. Do not just mask off */
|
||||||
|
/* the lowest bits. */
|
||||||
|
#define SKP_RAND(seed) (SKP_MLA_ovflw(907633515, (seed), 196314165))
|
||||||
|
|
||||||
|
// Add some multiplication functions that can be easily mapped to ARM.
|
||||||
|
|
||||||
|
// SKP_SMMUL: Signed top word multiply.
|
||||||
|
// ARMv6 2 instruction cycles.
|
||||||
|
// ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)
|
||||||
|
//#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT(SKP_SMLAL(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)), 16)
|
||||||
|
// the following seems faster on x86
|
||||||
|
//#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
|
||||||
|
|
||||||
|
#include "SKP_Silk_Inlines.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
320
app/src/main/cpp/src/SKP_Silk_VAD.c
Normal file
320
app/src/main/cpp/src/SKP_Silk_VAD.c
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File Name: SKP_Silk_VAD.c
|
||||||
|
* Description: Silk VAD.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/**********************************/
|
||||||
|
/* Initialization of the Silk VAD */
|
||||||
|
/**********************************/
|
||||||
|
SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */
|
||||||
|
SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int b, ret = 0;
|
||||||
|
|
||||||
|
/* reset state memory */
|
||||||
|
SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) );
|
||||||
|
|
||||||
|
/* init noise levels */
|
||||||
|
/* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
psSilk_VAD->NoiseLevelBias[ b ] = SKP_max_32( SKP_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize state */
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
psSilk_VAD->NL[ b ] = SKP_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
|
||||||
|
psSilk_VAD->inv_NL[ b ] = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->NL[ b ] );
|
||||||
|
}
|
||||||
|
psSilk_VAD->counter = 15;
|
||||||
|
|
||||||
|
/* init smoothed energy-to-noise ratio*/
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Weighting factors for tilt measure */
|
||||||
|
const static SKP_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
|
||||||
|
|
||||||
|
/***************************************/
|
||||||
|
/* Get the speech activity level in Q8 */
|
||||||
|
/***************************************/
|
||||||
|
SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */
|
||||||
|
SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */
|
||||||
|
SKP_int *pSA_Q8, /* O Speech activity level in Q8 */
|
||||||
|
SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */
|
||||||
|
SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */
|
||||||
|
SKP_int *pTilt_Q15, /* O current frame's frequency tilt */
|
||||||
|
const SKP_int16 pIn[], /* I PCM input [framelength] */
|
||||||
|
const SKP_int framelength /* I Input frame length */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int SA_Q15, input_tilt;
|
||||||
|
SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH / 2 ];
|
||||||
|
SKP_int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
|
||||||
|
SKP_int32 sumSquared, smooth_coef_Q16;
|
||||||
|
SKP_int16 HPstateTmp;
|
||||||
|
|
||||||
|
SKP_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ];
|
||||||
|
SKP_int32 Xnrg[ VAD_N_BANDS ];
|
||||||
|
SKP_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
|
||||||
|
SKP_int32 speech_nrg, x_tmp;
|
||||||
|
SKP_int ret = 0;
|
||||||
|
|
||||||
|
/* Safety checks */
|
||||||
|
SKP_assert( VAD_N_BANDS == 4 );
|
||||||
|
SKP_assert( MAX_FRAME_LENGTH >= framelength );
|
||||||
|
SKP_assert( framelength <= 512 );
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* Filter and Decimate */
|
||||||
|
/***********************/
|
||||||
|
/* 0-8 kHz to 0-4 kHz and 4-8 kHz */
|
||||||
|
SKP_Silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], &scratch[ 0 ], framelength );
|
||||||
|
|
||||||
|
/* 0-4 kHz to 0-2 kHz and 2-4 kHz */
|
||||||
|
SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 1 ) );
|
||||||
|
|
||||||
|
/* 0-2 kHz to 0-1 kHz and 1-2 kHz */
|
||||||
|
SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 2 ) );
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* HP filter on lowest band (differentiator) */
|
||||||
|
/*********************************************/
|
||||||
|
decimated_framelength = SKP_RSHIFT( framelength, 3 );
|
||||||
|
X[ 0 ][ decimated_framelength - 1 ] = SKP_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 );
|
||||||
|
HPstateTmp = X[ 0 ][ decimated_framelength - 1 ];
|
||||||
|
for( i = decimated_framelength - 1; i > 0; i-- ) {
|
||||||
|
X[ 0 ][ i - 1 ] = SKP_RSHIFT( X[ 0 ][ i - 1 ], 1 );
|
||||||
|
X[ 0 ][ i ] -= X[ 0 ][ i - 1 ];
|
||||||
|
}
|
||||||
|
X[ 0 ][ 0 ] -= psSilk_VAD->HPstate;
|
||||||
|
psSilk_VAD->HPstate = HPstateTmp;
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/* Calculate the energy in each band */
|
||||||
|
/*************************************/
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
/* Find the decimated framelength in the non-uniformly divided bands */
|
||||||
|
decimated_framelength = SKP_RSHIFT( framelength, SKP_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
|
||||||
|
|
||||||
|
/* Split length into subframe lengths */
|
||||||
|
dec_subframe_length = SKP_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
|
||||||
|
dec_subframe_offset = 0;
|
||||||
|
|
||||||
|
/* Compute energy per sub-frame */
|
||||||
|
/* initialize with summed energy of last subframe */
|
||||||
|
Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
|
||||||
|
for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
|
||||||
|
sumSquared = 0;
|
||||||
|
for( i = 0; i < dec_subframe_length; i++ ) {
|
||||||
|
/* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 ) ^ 2. */
|
||||||
|
/* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
|
||||||
|
x_tmp = SKP_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 );
|
||||||
|
sumSquared = SKP_SMLABB( sumSquared, x_tmp, x_tmp );
|
||||||
|
|
||||||
|
/* Safety check */
|
||||||
|
SKP_assert( sumSquared >= 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add/saturate summed energy of current subframe */
|
||||||
|
if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
|
||||||
|
Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
|
||||||
|
} else {
|
||||||
|
/* Look-ahead subframe */
|
||||||
|
Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], SKP_RSHIFT( sumSquared, 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
dec_subframe_offset += dec_subframe_length;
|
||||||
|
}
|
||||||
|
psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
/* Noise estimation */
|
||||||
|
/********************/
|
||||||
|
SKP_Silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/* Signal-plus-noise to noise ratio estimation */
|
||||||
|
/***********************************************/
|
||||||
|
sumSquared = 0;
|
||||||
|
input_tilt = 0;
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
|
||||||
|
if( speech_nrg > 0 ) {
|
||||||
|
/* Divide, with sufficient resolution */
|
||||||
|
if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
|
||||||
|
NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( SKP_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
|
||||||
|
} else {
|
||||||
|
NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( Xnrg[ b ], SKP_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert to log domain */
|
||||||
|
SNR_Q7 = SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
|
||||||
|
|
||||||
|
/* Sum-of-squares */
|
||||||
|
sumSquared = SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
|
||||||
|
|
||||||
|
/* Tilt measure */
|
||||||
|
if( speech_nrg < ( 1 << 20 ) ) {
|
||||||
|
/* Scale down SNR value for small subband speech energies */
|
||||||
|
SNR_Q7 = SKP_SMULWB( SKP_LSHIFT( SKP_Silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
|
||||||
|
}
|
||||||
|
input_tilt = SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
|
||||||
|
} else {
|
||||||
|
NrgToNoiseRatio_Q8[ b ] = 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mean-of-squares */
|
||||||
|
sumSquared = SKP_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
|
||||||
|
|
||||||
|
/* Root-mean-square approximation, scale to dBs, and write to output pointer */
|
||||||
|
*pSNR_dB_Q7 = ( SKP_int16 )( 3 * SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
|
||||||
|
|
||||||
|
/*********************************/
|
||||||
|
/* Speech Probability Estimation */
|
||||||
|
/*********************************/
|
||||||
|
SA_Q15 = SKP_Silk_sigm_Q15( SKP_SMULWB( VAD_SNR_FACTOR_Q16, *pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Frequency Tilt Measure */
|
||||||
|
/**************************/
|
||||||
|
*pTilt_Q15 = SKP_LSHIFT( SKP_Silk_sigm_Q15( input_tilt ) - 16384, 1 );
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/* Scale the sigmoid output based on power levels */
|
||||||
|
/**************************************************/
|
||||||
|
speech_nrg = 0;
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
/* Accumulate signal-without-noise energies, higher frequency bands have more weight */
|
||||||
|
speech_nrg += ( b + 1 ) * SKP_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Power scaling */
|
||||||
|
if( speech_nrg <= 0 ) {
|
||||||
|
SA_Q15 = SKP_RSHIFT( SA_Q15, 1 );
|
||||||
|
} else if( speech_nrg < 32768 ) {
|
||||||
|
/* square-root */
|
||||||
|
speech_nrg = SKP_Silk_SQRT_APPROX( SKP_LSHIFT( speech_nrg, 15 ) );
|
||||||
|
SA_Q15 = SKP_SMULWB( 32768 + speech_nrg, SA_Q15 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the resulting speech activity in Q8 to *pSA_Q8 */
|
||||||
|
*pSA_Q8 = SKP_min_int( SKP_RSHIFT( SA_Q15, 7 ), SKP_uint8_MAX );
|
||||||
|
|
||||||
|
/***********************************/
|
||||||
|
/* Energy Level and SNR estimation */
|
||||||
|
/***********************************/
|
||||||
|
/* Smoothing coefficient */
|
||||||
|
smooth_coef_Q16 = SKP_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, SKP_SMULWB( SA_Q15, SA_Q15 ) );
|
||||||
|
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||||
|
/* compute smoothed energy-to-noise ratio per band */
|
||||||
|
psSilk_VAD->NrgRatioSmth_Q8[ b ] = SKP_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
|
||||||
|
NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
|
||||||
|
|
||||||
|
/* signal to noise ratio in dB per band */
|
||||||
|
SNR_Q7 = 3 * ( SKP_Silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
|
||||||
|
/* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
|
||||||
|
pQuality_Q15[ b ] = SKP_Silk_sigm_Q15( SKP_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Noise level estimation */
|
||||||
|
/**************************/
|
||||||
|
void SKP_Silk_VAD_GetNoiseLevels(
|
||||||
|
const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */
|
||||||
|
SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 nl, nrg, inv_nrg;
|
||||||
|
SKP_int coef, min_coef;
|
||||||
|
|
||||||
|
/* Initially faster smoothing */
|
||||||
|
if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
|
||||||
|
min_coef = SKP_DIV32_16( SKP_int16_MAX, SKP_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
|
||||||
|
} else {
|
||||||
|
min_coef = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( k = 0; k < VAD_N_BANDS; k++ ) {
|
||||||
|
/* Get old noise level estimate for current band */
|
||||||
|
nl = psSilk_VAD->NL[ k ];
|
||||||
|
SKP_assert( nl >= 0 );
|
||||||
|
|
||||||
|
/* Add bias */
|
||||||
|
nrg = SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
|
||||||
|
SKP_assert( nrg > 0 );
|
||||||
|
|
||||||
|
/* Invert energies */
|
||||||
|
inv_nrg = SKP_DIV32( SKP_int32_MAX, nrg );
|
||||||
|
SKP_assert( inv_nrg >= 0 );
|
||||||
|
|
||||||
|
/* Less update when subband energy is high */
|
||||||
|
if( nrg > SKP_LSHIFT( nl, 3 ) ) {
|
||||||
|
coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
|
||||||
|
} else if( nrg < nl ) {
|
||||||
|
coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
|
||||||
|
} else {
|
||||||
|
coef = SKP_SMULWB( SKP_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initially faster smoothing */
|
||||||
|
coef = SKP_max_int( coef, min_coef );
|
||||||
|
|
||||||
|
/* Smooth inverse energies */
|
||||||
|
psSilk_VAD->inv_NL[ k ] = SKP_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
|
||||||
|
SKP_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
|
||||||
|
|
||||||
|
/* Compute noise level by inverting again */
|
||||||
|
nl = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->inv_NL[ k ] );
|
||||||
|
SKP_assert( nl >= 0 );
|
||||||
|
|
||||||
|
/* Limit noise levels (guarantee 7 bits of head room) */
|
||||||
|
nl = SKP_min( nl, 0x00FFFFFF );
|
||||||
|
|
||||||
|
/* Store as part of state */
|
||||||
|
psSilk_VAD->NL[ k ] = nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment frame counter */
|
||||||
|
psSilk_VAD->counter++;
|
||||||
|
}
|
159
app/src/main/cpp/src/SKP_Silk_VQ_nearest_neighbor_FIX.c
Normal file
159
app/src/main/cpp/src/SKP_Silk_VQ_nearest_neighbor_FIX.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
/* Entropy constrained MATRIX-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
|
||||||
|
void SKP_Silk_VQ_WMat_EC_FIX(
|
||||||
|
SKP_int *ind, /* O index of best codebook vector */
|
||||||
|
SKP_int32 *rate_dist_Q14, /* O best weighted quantization error + mu * rate*/
|
||||||
|
const SKP_int16 *in_Q14, /* I input vector to be quantized */
|
||||||
|
const SKP_int32 *W_Q18, /* I weighting matrix */
|
||||||
|
const SKP_int16 *cb_Q14, /* I codebook */
|
||||||
|
const SKP_int16 *cl_Q6, /* I code length for each codebook vector */
|
||||||
|
const SKP_int mu_Q8, /* I tradeoff between weighted error and rate */
|
||||||
|
SKP_int L /* I number of vectors in codebook */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
const SKP_int16 *cb_row_Q14;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 sum1_Q14, sum2_Q16, diff_Q14_01, diff_Q14_23, diff_Q14_4;
|
||||||
|
#else
|
||||||
|
SKP_int16 diff_Q14[ 5 ];
|
||||||
|
SKP_int32 sum1_Q14, sum2_Q16;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Loop over codebook */
|
||||||
|
*rate_dist_Q14 = SKP_int32_MAX;
|
||||||
|
cb_row_Q14 = cb_Q14;
|
||||||
|
for( k = 0; k < L; k++ ) {
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* Pack pairs of int16 values per int32 */
|
||||||
|
diff_Q14_01 = ( SKP_uint16 )( in_Q14[ 0 ] - cb_row_Q14[ 0 ] ) | SKP_LSHIFT( ( SKP_int32 )in_Q14[ 1 ] - cb_row_Q14[ 1 ], 16 );
|
||||||
|
diff_Q14_23 = ( SKP_uint16 )( in_Q14[ 2 ] - cb_row_Q14[ 2 ] ) | SKP_LSHIFT( ( SKP_int32 )in_Q14[ 3 ] - cb_row_Q14[ 3 ], 16 );
|
||||||
|
diff_Q14_4 = in_Q14[ 4 ] - cb_row_Q14[ 4 ];
|
||||||
|
#else
|
||||||
|
diff_Q14[ 0 ] = in_Q14[ 0 ] - cb_row_Q14[ 0 ];
|
||||||
|
diff_Q14[ 1 ] = in_Q14[ 1 ] - cb_row_Q14[ 1 ];
|
||||||
|
diff_Q14[ 2 ] = in_Q14[ 2 ] - cb_row_Q14[ 2 ];
|
||||||
|
diff_Q14[ 3 ] = in_Q14[ 3 ] - cb_row_Q14[ 3 ];
|
||||||
|
diff_Q14[ 4 ] = in_Q14[ 4 ] - cb_row_Q14[ 4 ];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Weighted rate */
|
||||||
|
sum1_Q14 = SKP_SMULBB( mu_Q8, cl_Q6[ k ] );
|
||||||
|
|
||||||
|
SKP_assert( sum1_Q14 >= 0 );
|
||||||
|
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
/* Add weighted quantization error, assuming W_Q18 is symmetric */
|
||||||
|
/* NOTE: the code below loads two int16 values as one int32, and multiplies each using the */
|
||||||
|
/* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
|
||||||
|
/* loaded in reverse order and the code will give the wrong result. In that case swapping */
|
||||||
|
/* the SMLAWB and SMLAWT instructions should solve the problem. */
|
||||||
|
/* first row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWT( W_Q18[ 1 ], diff_Q14_01 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14_23 );
|
||||||
|
sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 3 ], diff_Q14_23 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14_4 );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14_01 );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_01 );
|
||||||
|
|
||||||
|
/* second row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 7 ], diff_Q14_23 );
|
||||||
|
sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 8 ], diff_Q14_23 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14_4 );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 6 ], diff_Q14_01 );
|
||||||
|
sum1_Q14 = SKP_SMLAWT( sum1_Q14, sum2_Q16, diff_Q14_01 );
|
||||||
|
|
||||||
|
/* third row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWT( W_Q18[ 13 ], diff_Q14_23 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14_4 );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14_23 );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_23 );
|
||||||
|
|
||||||
|
/* fourth row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 19 ], diff_Q14_4 );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 18 ], diff_Q14_23 );
|
||||||
|
sum1_Q14 = SKP_SMLAWT( sum1_Q14, sum2_Q16, diff_Q14_23 );
|
||||||
|
|
||||||
|
/* last row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 24 ], diff_Q14_4 );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_4 );
|
||||||
|
#else
|
||||||
|
/* first row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] );
|
||||||
|
|
||||||
|
/* second row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] );
|
||||||
|
|
||||||
|
/* third row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] );
|
||||||
|
|
||||||
|
/* fourth row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] );
|
||||||
|
sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
|
||||||
|
sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] );
|
||||||
|
|
||||||
|
/* last row of W_Q18 */
|
||||||
|
sum2_Q16 = SKP_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] );
|
||||||
|
sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SKP_assert( sum1_Q14 >= 0 );
|
||||||
|
|
||||||
|
/* find best */
|
||||||
|
if( sum1_Q14 < *rate_dist_Q14 ) {
|
||||||
|
*rate_dist_Q14 = sum1_Q14;
|
||||||
|
*ind = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go to next cbk vector */
|
||||||
|
cb_row_Q14 += LTP_ORDER;
|
||||||
|
}
|
||||||
|
}
|
124
app/src/main/cpp/src/SKP_Silk_allpass_int_arm.S
Normal file
124
app/src/main/cpp/src/SKP_Silk_allpass_int_arm.S
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM >= 5
|
||||||
|
VARDEF A, r2
|
||||||
|
VARDEF len, r4
|
||||||
|
VARDEF S00, r5
|
||||||
|
VARDEF ink1, r6
|
||||||
|
VARDEF ink2, r8
|
||||||
|
VARDEF Y2, sb
|
||||||
|
VARDEF outk1, sl
|
||||||
|
VARDEF outk2, ip
|
||||||
|
|
||||||
|
.globl SYM(SKP_Silk_allpass_int)
|
||||||
|
SYM(SKP_Silk_allpass_int):
|
||||||
|
stmdb sp!, {r4-r10, fp, ip, lr}
|
||||||
|
add fp, sp, #36
|
||||||
|
.set len_offset, 40
|
||||||
|
ldr len, [sp, #len_offset]
|
||||||
|
ldr S00, [r1]
|
||||||
|
movs A, A, lsl #17
|
||||||
|
sub len, len, #1
|
||||||
|
ldmia r0!, {ink1,ink2}
|
||||||
|
bge LR(1, f)/*AgeZero*/
|
||||||
|
L(0)
|
||||||
|
sub Y2, ink1, S00
|
||||||
|
smlawt outk1, Y2, A, ink1
|
||||||
|
add S00, Y2, outk1
|
||||||
|
subs len, len, #2
|
||||||
|
sub Y2, ink2, S00
|
||||||
|
smlawt outk2, Y2, A, ink2
|
||||||
|
#ifdef _WINRT
|
||||||
|
ble LR(3, f)
|
||||||
|
ldmia r0!, {ink1,ink2}
|
||||||
|
L(3)
|
||||||
|
#else
|
||||||
|
ldmgtia r0!, {ink1,ink2}
|
||||||
|
#endif
|
||||||
|
add S00, Y2, outk2
|
||||||
|
stmia r3!, {outk1, outk2}
|
||||||
|
bgt LR(0, b)
|
||||||
|
#ifdef _WINRT
|
||||||
|
bne LR(2, f)
|
||||||
|
ldr ink1, [r0], #4
|
||||||
|
sub Y2, ink1, S00
|
||||||
|
smlawt outk1, Y2, A, ink1
|
||||||
|
add S00, Y2, outk1
|
||||||
|
str outk1, [r3]
|
||||||
|
L(2)
|
||||||
|
#else
|
||||||
|
ldreq ink1, [r0], #4
|
||||||
|
subeq Y2, ink1, S00
|
||||||
|
smlawteq outk1, Y2, A, ink1
|
||||||
|
addeq S00, Y2, outk1
|
||||||
|
streq outk1, [r3]
|
||||||
|
#endif
|
||||||
|
str S00, [r1]
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
|
||||||
|
L(1)/*AgeZero:*/
|
||||||
|
sub Y2, ink1, S00
|
||||||
|
smlawt outk1, Y2, A, S00
|
||||||
|
add S00, Y2, outk1
|
||||||
|
subs len, len, #2
|
||||||
|
sub Y2, ink2, S00
|
||||||
|
smlawt outk2, Y2, A, S00
|
||||||
|
#ifdef _WINRT
|
||||||
|
ble LR(3, f)
|
||||||
|
ldmia r0!, {ink1,ink2}
|
||||||
|
L(3)
|
||||||
|
#else
|
||||||
|
ldmgtia r0!, {ink1,ink2}
|
||||||
|
#endif
|
||||||
|
add S00, Y2, outk2
|
||||||
|
stmia r3!, {outk1, outk2}
|
||||||
|
bgt LR(1, b)
|
||||||
|
#ifdef _WINRT
|
||||||
|
bne LR(2, f)
|
||||||
|
ldr ink1, [r0], #4
|
||||||
|
sub Y2, ink1, S00
|
||||||
|
smlawt outk1, Y2, A, S00
|
||||||
|
add S00, Y2, outk1
|
||||||
|
str outk1, [r3]
|
||||||
|
L(2)
|
||||||
|
#else
|
||||||
|
ldreq ink1, [r0], #4
|
||||||
|
subeq Y2, ink1, S00
|
||||||
|
smlawteq outk1, Y2, A, S00
|
||||||
|
addeq S00, Y2, outk1
|
||||||
|
streq outk1, [r3]
|
||||||
|
#endif
|
||||||
|
str S00, [r1]
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
END
|
||||||
|
#endif
|
||||||
|
#endif
|
82
app/src/main/cpp/src/SKP_Silk_ana_filt_bank_1.c
Normal file
82
app/src/main/cpp/src/SKP_Silk_ana_filt_bank_1.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_ana_filt_bank_1.c *
|
||||||
|
* *
|
||||||
|
* Split signal into two decimated bands using first-order allpass filters *
|
||||||
|
* *
|
||||||
|
* Copyright 2006 (c), Skype Limited *
|
||||||
|
* Date: 060221 *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM<5
|
||||||
|
/* Coefficients for 2-band filter bank based on first-order allpass filters */
|
||||||
|
// old
|
||||||
|
static SKP_int16 A_fb1_20[ 1 ] = { 5394 << 1 };
|
||||||
|
static SKP_int16 A_fb1_21[ 1 ] = { (SKP_int16) (20623 << 1) }; /* wrap-around to negative number is intentional */
|
||||||
|
|
||||||
|
/* Split signal into two decimated bands using first-order allpass filters */
|
||||||
|
void SKP_Silk_ana_filt_bank_1(
|
||||||
|
const SKP_int16 *in, /* I: Input signal [N] */
|
||||||
|
SKP_int32 *S, /* I/O: State vector [2] */
|
||||||
|
SKP_int16 *outL, /* O: Low band [N/2] */
|
||||||
|
SKP_int16 *outH, /* O: High band [N/2] */
|
||||||
|
SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */ // todo: remove - no longer used
|
||||||
|
const SKP_int32 N /* I: Number of input samples */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, N2 = SKP_RSHIFT( N, 1 );
|
||||||
|
SKP_int32 in32, X, Y, out_1, out_2;
|
||||||
|
|
||||||
|
/* Internal variables and state are in Q10 format */
|
||||||
|
for( k = 0; k < N2; k++ ) {
|
||||||
|
/* Convert to Q10 */
|
||||||
|
in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 );
|
||||||
|
|
||||||
|
/* All-pass section for even input sample */
|
||||||
|
Y = SKP_SUB32( in32, S[ 0 ] );
|
||||||
|
X = SKP_SMLAWB( Y, Y, A_fb1_21[ 0 ] );
|
||||||
|
out_1 = SKP_ADD32( S[ 0 ], X );
|
||||||
|
S[ 0 ] = SKP_ADD32( in32, X );
|
||||||
|
|
||||||
|
/* Convert to Q10 */
|
||||||
|
in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 );
|
||||||
|
|
||||||
|
/* All-pass section for odd input sample */
|
||||||
|
Y = SKP_SUB32( in32, S[ 1 ] );
|
||||||
|
X = SKP_SMULWB( Y, A_fb1_20[ 0 ] );
|
||||||
|
out_2 = SKP_ADD32( S[ 1 ], X );
|
||||||
|
S[ 1 ] = SKP_ADD32( in32, X );
|
||||||
|
|
||||||
|
/* Add/subtract, convert back to int16 and store to output */
|
||||||
|
outL[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_ADD32( out_2, out_1 ), 11 ) );
|
||||||
|
outH[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( out_2, out_1 ), 11 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
186
app/src/main/cpp/src/SKP_Silk_ana_filt_bank_1_arm.S
Normal file
186
app/src/main/cpp/src/SKP_Silk_ana_filt_bank_1_arm.S
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM>=5
|
||||||
|
/*
|
||||||
|
* void SKP_Silk_ana_filt_bank_1(
|
||||||
|
* const SKP_int16 *in, I: Input signal [N]
|
||||||
|
* SKP_int32 *S, I/O: State vector [2]
|
||||||
|
* SKP_int16 *outL, O: Low band [N/2]
|
||||||
|
* SKP_int16 *outH, O: High band [N/2]
|
||||||
|
* SKP_int32 *scratch, I: Scratch memory [3*N/2]
|
||||||
|
* const SKP_int32 N I: Number of input samples
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
VARDEF ptr_in_lo, r0
|
||||||
|
VARDEF ptr_in_hi, r3
|
||||||
|
VARDEF val_in_lo, sb
|
||||||
|
VARDEF val_in_hi, sl
|
||||||
|
VARDEF ptr_scratch, r4
|
||||||
|
VARDEF ptr_scratch_N, r1
|
||||||
|
VARDEF ptr_scratch_halfN, r2
|
||||||
|
VARDEF idx_k, ip
|
||||||
|
VARDEF val_N, r8
|
||||||
|
VARDEF val_halfN, r8
|
||||||
|
VARDEF val_scratch1, r5
|
||||||
|
VARDEF val_scratch2, r6
|
||||||
|
VARDEF ptr_out_lo, r5
|
||||||
|
VARDEF ptr_out_hi, r6
|
||||||
|
VARDEF ptr_s, _r7
|
||||||
|
|
||||||
|
VARDEF val_const1, r2
|
||||||
|
VARDEF val_const2, ip // 0x03FF F800
|
||||||
|
VARDEF val_const3, sl // 0x0000 7FFF
|
||||||
|
VARDEF val_const4, lr // 0xFFFF 8000
|
||||||
|
VARDEF idx_k2, r8
|
||||||
|
VARDEF ptr_scratch_halfN_2, r3
|
||||||
|
VARDEF val_scratch3, r0
|
||||||
|
VARDEF val_scratch4, r1
|
||||||
|
VARDEF out_tmpla, sb
|
||||||
|
VARDEF out_tmplb, r2
|
||||||
|
VARDEF out_tmpha, r0
|
||||||
|
VARDEF out_tmphb, _r7
|
||||||
|
|
||||||
|
.set halfN, 0
|
||||||
|
.set sp_ptr_out_lo, 4
|
||||||
|
.set sp_ptr_out_hi, 8
|
||||||
|
|
||||||
|
EXTERN SYM(SKP_Silk_allpass_int)
|
||||||
|
|
||||||
|
.globl SYM(SKP_Silk_ana_filt_bank_1)
|
||||||
|
SYM(SKP_Silk_ana_filt_bank_1):
|
||||||
|
stmdb sp!, {r4-r10, fp, ip, lr}
|
||||||
|
add fp, sp, #36
|
||||||
|
sub sp, sp, #12
|
||||||
|
|
||||||
|
.set arg_scratch, 52
|
||||||
|
.set arg_N, 56
|
||||||
|
|
||||||
|
ldr ptr_scratch, [sp, #arg_scratch]
|
||||||
|
ldr val_N, [sp, #arg_N]
|
||||||
|
|
||||||
|
str r2, [sp, #sp_ptr_out_lo]
|
||||||
|
str r3, [sp, #sp_ptr_out_hi]
|
||||||
|
mov ptr_s, r1
|
||||||
|
mov val_halfN, val_N, asr #1
|
||||||
|
sub idx_k, val_halfN, #1
|
||||||
|
add ptr_in_hi, ptr_in_lo, #2
|
||||||
|
str val_halfN, [sp, #halfN]
|
||||||
|
ldrsh val_in_lo, [ptr_in_lo], #4
|
||||||
|
ldrsh val_in_hi, [ptr_in_hi], #4
|
||||||
|
add ptr_scratch_N, ptr_scratch, val_halfN, lsl #3
|
||||||
|
add ptr_scratch_halfN, ptr_scratch, val_halfN, lsl #2
|
||||||
|
|
||||||
|
L(0)
|
||||||
|
mov val_scratch1, val_in_lo, lsl #10
|
||||||
|
mov val_scratch2, val_in_hi, lsl #10
|
||||||
|
ldrsh val_in_lo, [ptr_in_lo], #4
|
||||||
|
ldrsh val_in_hi, [ptr_in_hi], #4
|
||||||
|
subs idx_k, idx_k, #1
|
||||||
|
str val_scratch1, [ptr_scratch_N], #4
|
||||||
|
str val_scratch2, [ptr_scratch_halfN], #4
|
||||||
|
bgt LR(0, b)
|
||||||
|
|
||||||
|
mov val_scratch1, val_in_lo, lsl #10
|
||||||
|
mov val_scratch2, val_in_hi, lsl #10
|
||||||
|
str val_scratch1, [ptr_scratch_N], #4
|
||||||
|
str val_scratch2, [ptr_scratch_halfN], #4
|
||||||
|
|
||||||
|
mov val_const1, #0x1500
|
||||||
|
add r0, ptr_scratch, val_halfN, lsl #2
|
||||||
|
add r1, ptr_s, #4
|
||||||
|
add val_const1, val_const1, #0x12
|
||||||
|
mov r3, ptr_scratch
|
||||||
|
bl SYM(SKP_Silk_allpass_int)
|
||||||
|
|
||||||
|
mov val_const1, #0x5000
|
||||||
|
add r0, ptr_scratch, val_halfN, lsl #3
|
||||||
|
mov r1, ptr_s
|
||||||
|
add val_const1, val_const1, #0x8F
|
||||||
|
add r3, ptr_scratch, val_halfN, lsl #2
|
||||||
|
bl SYM(SKP_Silk_allpass_int)
|
||||||
|
|
||||||
|
mvn val_const2, #0x80000000
|
||||||
|
add ptr_scratch_halfN_2, ptr_scratch, val_halfN, lsl #2
|
||||||
|
mov val_const3, val_const2, asr #16
|
||||||
|
rsb val_const4, val_const3, #0
|
||||||
|
mov idx_k2, val_halfN
|
||||||
|
mov val_const2, val_const3, lsl #11
|
||||||
|
ldr ptr_out_lo, [sp, #sp_ptr_out_lo]
|
||||||
|
ldr ptr_out_hi, [sp, #sp_ptr_out_hi]
|
||||||
|
|
||||||
|
L(1)
|
||||||
|
ldr val_scratch3, [ptr_scratch], #4
|
||||||
|
ldr val_scratch4, [ptr_scratch_halfN_2], #4
|
||||||
|
add out_tmpla, val_scratch3, val_scratch4
|
||||||
|
sub out_tmpha, val_scratch3, val_scratch4
|
||||||
|
add out_tmplb, out_tmpla, #1024
|
||||||
|
add out_tmphb, out_tmpha, #1024
|
||||||
|
mov out_tmplb, out_tmplb, asr #11
|
||||||
|
mov out_tmphb, out_tmphb, asr #11
|
||||||
|
strh out_tmplb, [ptr_out_lo], #2
|
||||||
|
strh out_tmphb, [ptr_out_hi], #2
|
||||||
|
#ifdef _WINRT
|
||||||
|
cmp out_tmpla, val_const2
|
||||||
|
ble LR(2, f)
|
||||||
|
strh val_const3, [ptr_out_lo, #-2]
|
||||||
|
L(2)
|
||||||
|
cmn out_tmpla, val_const2
|
||||||
|
bge LR(2, f)
|
||||||
|
strh val_const4, [ptr_out_lo, #-2]
|
||||||
|
L(2)
|
||||||
|
cmp out_tmpha, val_const2
|
||||||
|
ble LR(2, f)
|
||||||
|
strh val_const3, [ptr_out_hi, #-2]
|
||||||
|
L(2)
|
||||||
|
cmn out_tmpha, val_const2
|
||||||
|
bge LR(2, f)
|
||||||
|
strh val_const4, [ptr_out_hi, #-2]
|
||||||
|
L(2)
|
||||||
|
#else
|
||||||
|
cmp out_tmpla, val_const2
|
||||||
|
strgth val_const3, [ptr_out_lo, #-2]
|
||||||
|
cmn out_tmpla, val_const2
|
||||||
|
strlth val_const4, [ptr_out_lo, #-2]
|
||||||
|
cmp out_tmpha, val_const2
|
||||||
|
strgth val_const3, [ptr_out_hi, #-2]
|
||||||
|
cmn out_tmpha, val_const2
|
||||||
|
strlth val_const4, [ptr_out_hi, #-2]
|
||||||
|
#endif
|
||||||
|
subs idx_k2, idx_k2, #1
|
||||||
|
bgt LR(1, b)
|
||||||
|
|
||||||
|
add sp, sp, #12
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
120
app/src/main/cpp/src/SKP_Silk_apply_sine_window.c
Normal file
120
app/src/main/cpp/src/SKP_Silk_apply_sine_window.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Apply sine window to signal vector. */
|
||||||
|
/* Window types: */
|
||||||
|
/* 1 -> sine window from 0 to pi/2 */
|
||||||
|
/* 2 -> sine window from pi/2 to pi */
|
||||||
|
/* Every other sample is linearly interpolated, for speed. */
|
||||||
|
/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
|
||||||
|
|
||||||
|
/* Matlab code for table:
|
||||||
|
for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
|
||||||
|
*/
|
||||||
|
static SKP_int16 freq_table_Q16[ 27 ] = {
|
||||||
|
12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
|
||||||
|
3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
|
||||||
|
2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
|
||||||
|
};
|
||||||
|
|
||||||
|
//#if EMBEDDED_ARM<6
|
||||||
|
void SKP_Silk_apply_sine_window(
|
||||||
|
SKP_int16 px_win[], /* O Pointer to windowed signal */
|
||||||
|
const SKP_int16 px[], /* I Pointer to input signal */
|
||||||
|
const SKP_int win_type, /* I Selects a window type */
|
||||||
|
const SKP_int length /* I Window length, multiple of 4 */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, f_Q16, c_Q16;
|
||||||
|
SKP_int32 S0_Q16, S1_Q16;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 px32;
|
||||||
|
#endif
|
||||||
|
SKP_assert( win_type == 1 || win_type == 2 );
|
||||||
|
|
||||||
|
/* Length must be in a range from 16 to 120 and a multiple of 4 */
|
||||||
|
SKP_assert( length >= 16 && length <= 120 );
|
||||||
|
SKP_assert( ( length & 3 ) == 0 );
|
||||||
|
|
||||||
|
/* Input pointer must be 4-byte aligned */
|
||||||
|
SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )px - ( SKP_int8* )0 ) & 3 ) == 0 );
|
||||||
|
|
||||||
|
/* Frequency */
|
||||||
|
k = ( length >> 2 ) - 4;
|
||||||
|
SKP_assert( k >= 0 && k <= 26 );
|
||||||
|
f_Q16 = (SKP_int)freq_table_Q16[ k ];
|
||||||
|
|
||||||
|
/* Factor used for cosine approximation */
|
||||||
|
c_Q16 = SKP_SMULWB( f_Q16, -f_Q16 );
|
||||||
|
SKP_assert( c_Q16 >= -32768 );
|
||||||
|
|
||||||
|
/* initialize state */
|
||||||
|
if( win_type == 1 ) {
|
||||||
|
/* start from 0 */
|
||||||
|
S0_Q16 = 0;
|
||||||
|
/* approximation of sin(f) */
|
||||||
|
S1_Q16 = f_Q16 + SKP_RSHIFT( length, 3 );
|
||||||
|
} else {
|
||||||
|
/* start from 1 */
|
||||||
|
S0_Q16 = ( 1 << 16 );
|
||||||
|
/* approximation of cos(f) */
|
||||||
|
S1_Q16 = ( 1 << 16 ) + SKP_RSHIFT( c_Q16, 1 ) + SKP_RSHIFT( length, 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
|
||||||
|
/* 4 samples at a time */
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
for( k = 0; k < length; k += 4 ) {
|
||||||
|
px32 = *( (SKP_int32 *)&px[ k ] ); /* load two values at once */
|
||||||
|
px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px32 );
|
||||||
|
px_win[ k + 1 ] = (SKP_int16)SKP_SMULWT( S1_Q16, px32 );
|
||||||
|
S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
|
||||||
|
S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) );
|
||||||
|
|
||||||
|
px32 = *( (SKP_int32 *)&px[k + 2] ); /* load two values at once */
|
||||||
|
px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px32 );
|
||||||
|
px_win[ k + 3 ] = (SKP_int16)SKP_SMULWT( S0_Q16, px32 );
|
||||||
|
S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16;
|
||||||
|
S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for( k = 0; k < length; k += 4 ) {
|
||||||
|
px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
|
||||||
|
px_win[ k + 1 ] = (SKP_int16)SKP_SMULWB( S1_Q16, px[ k + 1] );
|
||||||
|
S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
|
||||||
|
S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) );
|
||||||
|
|
||||||
|
px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
|
||||||
|
px_win[ k + 3 ] = (SKP_int16)SKP_SMULWB( S0_Q16, px[ k + 3 ] );
|
||||||
|
S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16;
|
||||||
|
S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
//#endif
|
70
app/src/main/cpp/src/SKP_Silk_array_maxabs.c
Normal file
70
app/src/main/cpp/src/SKP_Silk_array_maxabs.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_int16_array_maxabs.c *
|
||||||
|
* *
|
||||||
|
* Function that returns the maximum absolut value of *
|
||||||
|
* the input vector *
|
||||||
|
* *
|
||||||
|
* Copyright 2006 (c), Skype Limited *
|
||||||
|
* Date: 060221 *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Function that returns the maximum absolut value of the input vector */
|
||||||
|
#if (EMBEDDED_ARM<4)
|
||||||
|
SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
|
||||||
|
const SKP_int16 *vec, /* I Input vector [len] */
|
||||||
|
const SKP_int32 len /* I Length of input vector */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int32 max = 0, i, lvl = 0, ind;
|
||||||
|
if( len == 0 ) return 0;
|
||||||
|
|
||||||
|
ind = len - 1;
|
||||||
|
max = SKP_SMULBB( vec[ ind ], vec[ ind ] );
|
||||||
|
for( i = len - 2; i >= 0; i-- ) {
|
||||||
|
lvl = SKP_SMULBB( vec[ i ], vec[ i ] );
|
||||||
|
if( lvl > max ) {
|
||||||
|
max = lvl;
|
||||||
|
ind = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */
|
||||||
|
if( max >= 1073676289 ) { // (2^15-1)^2 = 1073676289
|
||||||
|
return( SKP_int16_MAX );
|
||||||
|
} else {
|
||||||
|
if( vec[ ind ] < 0 ) {
|
||||||
|
return( -vec[ ind ] );
|
||||||
|
} else {
|
||||||
|
return( vec[ ind ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
288
app/src/main/cpp/src/SKP_Silk_array_maxabs_arm.S
Normal file
288
app/src/main/cpp/src/SKP_Silk_array_maxabs_arm.S
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM>=5
|
||||||
|
|
||||||
|
VARDEF ptr_vec, r0
|
||||||
|
VARDEF val_vec, r2
|
||||||
|
VARDEF val_return, r0
|
||||||
|
VARDEF len, r1
|
||||||
|
VARDEF val1_max, r3
|
||||||
|
VARDEF val2_max, r4
|
||||||
|
VARDEF val_lvl, r5
|
||||||
|
VARDEF val_ind, r6
|
||||||
|
|
||||||
|
VARDEF const_int16_MAX, r5
|
||||||
|
|
||||||
|
.globl SYM(SKP_Silk_int16_array_maxabs)
|
||||||
|
SYM(SKP_Silk_int16_array_maxabs):
|
||||||
|
stmdb sp!, {r4-r6, fp, ip, lr}
|
||||||
|
add fp, sp, #20
|
||||||
|
|
||||||
|
cmp r1, #6
|
||||||
|
mvn r5, #0 /*r5 = -1(max)*/
|
||||||
|
blt LR(7, f)
|
||||||
|
ands r2, r0, #3
|
||||||
|
bne LR(3, f)
|
||||||
|
ands r2, r1, #0x1
|
||||||
|
bne LR(1, f)
|
||||||
|
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
sub len, len, #2
|
||||||
|
L(0)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
cmp val1_max, r5
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
#ifdef _WINRT
|
||||||
|
subge val_ind, ptr_vec, #4 /*address*/
|
||||||
|
subge val_ind, val_ind, #4 /*address*/
|
||||||
|
#else
|
||||||
|
subge val_ind, ptr_vec, #8 /*address*/
|
||||||
|
#endif
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #6
|
||||||
|
subs len, len, #2
|
||||||
|
bgt LR(0, b)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #4 /*address*/
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #2
|
||||||
|
b LR(9, f)
|
||||||
|
/*Odd number of iterations*/
|
||||||
|
L(1)
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
sub len, len, #3
|
||||||
|
L(2)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
#ifdef _WINRT
|
||||||
|
subge val_ind, ptr_vec, #4 /*address*/
|
||||||
|
subge val_ind, val_ind, #4 /*address*/
|
||||||
|
#else
|
||||||
|
subge val_ind, ptr_vec, #8 /*address*/
|
||||||
|
#endif
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #6
|
||||||
|
subs len, len, #2
|
||||||
|
bgt LR(2, b)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
ldrsh val_vec, [ptr_vec], #2
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #6 /*address*/
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #4
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #2 /*address*/
|
||||||
|
b LR(9, f)
|
||||||
|
/*Oddly aligned*/
|
||||||
|
L(3)
|
||||||
|
ands r2, r1, #0x1
|
||||||
|
bne LR(5, f)
|
||||||
|
|
||||||
|
ldrsh val_vec, [ptr_vec], #2
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #2
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
sub len, len, #4
|
||||||
|
L(4)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
#ifdef _WINRT
|
||||||
|
subge val_ind, ptr_vec, #4 /*address*/
|
||||||
|
subge val_ind, val_ind, #4 /*address*/
|
||||||
|
#else
|
||||||
|
subge val_ind, ptr_vec, #8 /*address*/
|
||||||
|
#endif
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #6
|
||||||
|
subs len, len, #2
|
||||||
|
bgt LR(4, b)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
ldrsh val_vec, [ptr_vec], #2
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #6 /*address*/
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #4
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #2 /*address*/
|
||||||
|
b LR(9, f)
|
||||||
|
/*Odd number of iterations+Oddly aligned*/
|
||||||
|
L(5)
|
||||||
|
ldrsh val_vec, [ptr_vec], #2
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #2
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
sub len, len, #3
|
||||||
|
L(6)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
ldr val_vec, [ptr_vec], #4
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
#ifdef _WINRT
|
||||||
|
subge val_ind, ptr_vec, #4 /*address*/
|
||||||
|
subge val_ind, val_ind, #4 /*address*/
|
||||||
|
#else
|
||||||
|
subge val_ind, ptr_vec, #8 /*address*/
|
||||||
|
#endif
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #6
|
||||||
|
subs len, len, #2
|
||||||
|
bgt LR(6, b)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
smultt val2_max, val_vec, val_vec
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #4 /*address*/
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #2
|
||||||
|
b LR(9, f)
|
||||||
|
/*Less than 6 iterations*/
|
||||||
|
L(7)
|
||||||
|
ldrsh val_vec, [ptr_vec], #2
|
||||||
|
sub len, len, #1
|
||||||
|
L(8)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
ldrsh val_vec, [ptr_vec], #2
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #4
|
||||||
|
subs len, len, #1
|
||||||
|
bgt LR(8, b)
|
||||||
|
smulbb val1_max, val_vec, val_vec
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #2
|
||||||
|
L(9)
|
||||||
|
ldrsh val_return, [val_ind]
|
||||||
|
mvn const_int16_MAX, #0x80000000
|
||||||
|
mov const_int16_MAX, const_int16_MAX, asr #16
|
||||||
|
cmp val_return, #0
|
||||||
|
rsblt val_return, val_return, #0
|
||||||
|
cmp val_return, const_int16_MAX
|
||||||
|
movge val_return, const_int16_MAX
|
||||||
|
|
||||||
|
ldmia sp!, {r4-r6, fp, ip, pc}
|
||||||
|
|
||||||
|
#elif EMBEDDED_ARM>=4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VARDEF ptr_vec, r0
|
||||||
|
VARDEF val1_vec, r2
|
||||||
|
VARDEF val2_vec, r7
|
||||||
|
VARDEF len, r1
|
||||||
|
VARDEF val1_max, r3
|
||||||
|
VARDEF val2_max, r8
|
||||||
|
VARDEF val_lvl, r5
|
||||||
|
VARDEF val_ind, r6
|
||||||
|
|
||||||
|
VARDEF val_return, r0
|
||||||
|
VARDEF const_int16_MAX, r5
|
||||||
|
|
||||||
|
.globl SYM(SKP_Silk_int16_array_maxabs)
|
||||||
|
SYM(SKP_Silk_int16_array_maxabs):
|
||||||
|
stmdb sp!, {r4-r8, fp, ip, lr}
|
||||||
|
add fp, sp, #28
|
||||||
|
|
||||||
|
mvn val_lvl, #0 /*r5 = -1(max)*/
|
||||||
|
|
||||||
|
ldrsh val1_vec, [ptr_vec], #2
|
||||||
|
ldrsh val2_vec, [ptr_vec], #2
|
||||||
|
sub len, len, #2
|
||||||
|
L(0)
|
||||||
|
mul val1_max, val1_vec, val1_vec
|
||||||
|
mul val2_max, val2_vec, val2_vec
|
||||||
|
ldrsh val1_vec, [ptr_vec], #2
|
||||||
|
ldrsh val2_vec, [ptr_vec], #2
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #8
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #6
|
||||||
|
subs len, len, #2
|
||||||
|
bgt LR(0, b)
|
||||||
|
mul val1_max, val1_vec, val1_vec
|
||||||
|
mul val2_max, val2_vec, val2_vec
|
||||||
|
cmp val1_max, val_lvl
|
||||||
|
movge val_lvl, val1_max
|
||||||
|
subge val_ind, ptr_vec, #4
|
||||||
|
cmn len, #1 /*r1?=-1*/
|
||||||
|
beq LR(1, f)
|
||||||
|
cmp val2_max, val_lvl
|
||||||
|
movge val_lvl, val2_max
|
||||||
|
subge val_ind, ptr_vec, #2
|
||||||
|
L(1)
|
||||||
|
ldrsh val_return, [val_ind]
|
||||||
|
mvn const_int16_MAX, #0x80000000
|
||||||
|
mov const_int16_MAX, const_int16_MAX, asr #16
|
||||||
|
cmp val_return, #0
|
||||||
|
rsblt val_return, val_return, #0
|
||||||
|
cmp val_return, const_int16_MAX
|
||||||
|
movge val_return, const_int16_MAX
|
||||||
|
|
||||||
|
ldmia sp!, {r4-r8, fp, ip, pc}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
END
|
||||||
|
#endif
|
81
app/src/main/cpp/src/SKP_Silk_autocorr.c
Normal file
81
app/src/main/cpp/src/SKP_Silk_autocorr.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_autocorr.c *
|
||||||
|
* *
|
||||||
|
* Calculates the autocorrelation *
|
||||||
|
* The result has 29 non-zero bits for the first correlation, to leave *
|
||||||
|
* some room for adding white noise fractions etc. *
|
||||||
|
* *
|
||||||
|
* Copyright 2008 (c), Skype Limited *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Compute autocorrelation */
|
||||||
|
void SKP_Silk_autocorr(
|
||||||
|
SKP_int32 *results, /* O Result (length correlationCount) */
|
||||||
|
SKP_int *scale, /* O Scaling of the correlation vector */
|
||||||
|
const SKP_int16 *inputData, /* I Input data to correlate */
|
||||||
|
const SKP_int inputDataSize, /* I Length of input */
|
||||||
|
const SKP_int correlationCount /* I Number of correlation taps to compute */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, lz, nRightShifts, corrCount;
|
||||||
|
SKP_int64 corr64;
|
||||||
|
|
||||||
|
corrCount = SKP_min_int( inputDataSize, correlationCount );
|
||||||
|
|
||||||
|
/* compute energy (zero-lag correlation) */
|
||||||
|
corr64 = SKP_Silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );
|
||||||
|
|
||||||
|
/* deal with all-zero input data */
|
||||||
|
corr64 += 1;
|
||||||
|
|
||||||
|
/* number of leading zeros */
|
||||||
|
lz = SKP_Silk_CLZ64( corr64 );
|
||||||
|
|
||||||
|
/* scaling: number of right shifts applied to correlations */
|
||||||
|
nRightShifts = 35 - lz;
|
||||||
|
*scale = nRightShifts;
|
||||||
|
|
||||||
|
if( nRightShifts <= 0 ) {
|
||||||
|
results[ 0 ] = SKP_LSHIFT( (SKP_int32)SKP_CHECK_FIT32( corr64 ), -nRightShifts );
|
||||||
|
|
||||||
|
/* compute remaining correlations based on int32 inner product */
|
||||||
|
for( i = 1; i < corrCount; i++ ) {
|
||||||
|
results[ i ] = SKP_LSHIFT( SKP_Silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results[ 0 ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( corr64, nRightShifts ) );
|
||||||
|
|
||||||
|
/* compute remaining correlations based on int64 inner product */
|
||||||
|
for( i = 1; i < corrCount; i++ ) {
|
||||||
|
results[ i ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_Silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
app/src/main/cpp/src/SKP_Silk_biquad.c
Normal file
72
app/src/main/cpp/src/SKP_Silk_biquad.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_biquad.c *
|
||||||
|
* *
|
||||||
|
* Second order ARMA filter *
|
||||||
|
* Can handle slowly varying filter coefficients *
|
||||||
|
* *
|
||||||
|
* Copyright 2006 (c), Skype Limited *
|
||||||
|
* Date: 060221 *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Second order ARMA filter */
|
||||||
|
/* Can handle slowly varying filter coefficients */
|
||||||
|
void SKP_Silk_biquad(
|
||||||
|
const SKP_int16 *in, /* I: input signal */
|
||||||
|
const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */
|
||||||
|
const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */
|
||||||
|
SKP_int32 *S, /* I/O: state vector [2] */
|
||||||
|
SKP_int16 *out, /* O: output signal */
|
||||||
|
const SKP_int32 len /* I: signal length */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, in16;
|
||||||
|
SKP_int32 A0_neg, A1_neg, S0, S1, out32, tmp32;
|
||||||
|
|
||||||
|
S0 = S[ 0 ];
|
||||||
|
S1 = S[ 1 ];
|
||||||
|
A0_neg = -A[ 0 ];
|
||||||
|
A1_neg = -A[ 1 ];
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
/* S[ 0 ], S[ 1 ]: Q13 */
|
||||||
|
in16 = in[ k ];
|
||||||
|
out32 = SKP_SMLABB( S0, in16, B[ 0 ] );
|
||||||
|
|
||||||
|
S0 = SKP_SMLABB( S1, in16, B[ 1 ] );
|
||||||
|
S0 += SKP_LSHIFT( SKP_SMULWB( out32, A0_neg ), 3 );
|
||||||
|
|
||||||
|
S1 = SKP_LSHIFT( SKP_SMULWB( out32, A1_neg ), 3 );
|
||||||
|
S1 = SKP_SMLABB( S1, in16, B[ 2 ] );
|
||||||
|
tmp32 = SKP_RSHIFT_ROUND( out32, 13 ) + 1;
|
||||||
|
out[ k ] = (SKP_int16)SKP_SAT16( tmp32 );
|
||||||
|
}
|
||||||
|
S[ 0 ] = S0;
|
||||||
|
S[ 1 ] = S1;
|
||||||
|
}
|
73
app/src/main/cpp/src/SKP_Silk_biquad_alt.c
Normal file
73
app/src/main/cpp/src/SKP_Silk_biquad_alt.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_biquad_alt.c *
|
||||||
|
* *
|
||||||
|
* Second order ARMA filter *
|
||||||
|
* Can handle slowly varying filter coefficients *
|
||||||
|
* */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Second order ARMA filter, alternative implementation */
|
||||||
|
void SKP_Silk_biquad_alt(
|
||||||
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
const SKP_int32 *B_Q28, /* I: MA coefficients [3] */
|
||||||
|
const SKP_int32 *A_Q28, /* I: AR coefficients [2] */
|
||||||
|
SKP_int32 *S, /* I/O: State vector [2] */
|
||||||
|
SKP_int16 *out, /* O: Output signal */
|
||||||
|
const SKP_int32 len /* I: Signal length (must be even) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
|
||||||
|
|
||||||
|
/* Negate A_Q28 values and split in two parts */
|
||||||
|
A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
|
||||||
|
A0_U_Q28 = SKP_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
|
||||||
|
A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
|
||||||
|
A1_U_Q28 = SKP_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
|
||||||
|
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
/* S[ 0 ], S[ 1 ]: Q12 */
|
||||||
|
inval = in[ k ];
|
||||||
|
out32_Q14 = SKP_LSHIFT( SKP_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
|
||||||
|
|
||||||
|
S[ 0 ] = S[1] + SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
|
||||||
|
S[ 0 ] = SKP_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
|
||||||
|
S[ 0 ] = SKP_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
|
||||||
|
|
||||||
|
S[ 1 ] = SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
|
||||||
|
S[ 1 ] = SKP_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
|
||||||
|
S[ 1 ] = SKP_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
|
||||||
|
|
||||||
|
/* Scale back to Q0 and saturate */
|
||||||
|
out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
|
||||||
|
}
|
||||||
|
}
|
228
app/src/main/cpp/src/SKP_Silk_burg_modified.c
Normal file
228
app/src/main/cpp/src/SKP_Silk_burg_modified.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* SKP_Silk_burg_modified.c *
|
||||||
|
* *
|
||||||
|
* Calculates the reflection coefficients from the input vector *
|
||||||
|
* Input vector contains nb_subfr sub vectors of length L_sub + D *
|
||||||
|
* *
|
||||||
|
* Copyright 2009 (c), Skype Limited *
|
||||||
|
* Date: 100105 *
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
#define MAX_FRAME_SIZE 544 // subfr_length * nb_subfr = ( 0.005 * 24000 + 16 ) * 4 = 544
|
||||||
|
#define MAX_NB_SUBFR 4
|
||||||
|
|
||||||
|
#define QA 25
|
||||||
|
#define N_BITS_HEAD_ROOM 2
|
||||||
|
#define MIN_RSHIFTS -16
|
||||||
|
#define MAX_RSHIFTS (32 - QA)
|
||||||
|
|
||||||
|
/* Compute reflection coefficients from input signal */
|
||||||
|
void SKP_Silk_burg_modified(
|
||||||
|
SKP_int32 *res_nrg, /* O residual energy */
|
||||||
|
SKP_int *res_nrg_Q, /* O residual energy Q value */
|
||||||
|
SKP_int32 A_Q16[], /* O prediction coefficients (length order) */
|
||||||
|
const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||||
|
const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
|
||||||
|
const SKP_int nb_subfr, /* I number of subframes stacked in x */
|
||||||
|
const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
|
||||||
|
const SKP_int D /* I order */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, n, s, lz, rshifts, rshifts_extra;
|
||||||
|
SKP_int32 C0, num, nrg, rc_Q31, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
||||||
|
const SKP_int16 *x_ptr;
|
||||||
|
|
||||||
|
SKP_int32 C_first_row[ SKP_Silk_MAX_ORDER_LPC ];
|
||||||
|
SKP_int32 C_last_row[ SKP_Silk_MAX_ORDER_LPC ];
|
||||||
|
SKP_int32 Af_QA[ SKP_Silk_MAX_ORDER_LPC ];
|
||||||
|
|
||||||
|
SKP_int32 CAf[ SKP_Silk_MAX_ORDER_LPC + 1 ];
|
||||||
|
SKP_int32 CAb[ SKP_Silk_MAX_ORDER_LPC + 1 ];
|
||||||
|
|
||||||
|
SKP_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||||
|
SKP_assert( nb_subfr <= MAX_NB_SUBFR );
|
||||||
|
|
||||||
|
|
||||||
|
/* Compute autocorrelations, added over subframes */
|
||||||
|
SKP_Silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
|
||||||
|
if( rshifts > MAX_RSHIFTS ) {
|
||||||
|
C0 = SKP_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
|
||||||
|
SKP_assert( C0 > 0 );
|
||||||
|
rshifts = MAX_RSHIFTS;
|
||||||
|
} else {
|
||||||
|
lz = SKP_Silk_CLZ32( C0 ) - 1;
|
||||||
|
rshifts_extra = N_BITS_HEAD_ROOM - lz;
|
||||||
|
if( rshifts_extra > 0 ) {
|
||||||
|
rshifts_extra = SKP_min( rshifts_extra, MAX_RSHIFTS - rshifts );
|
||||||
|
C0 = SKP_RSHIFT32( C0, rshifts_extra );
|
||||||
|
} else {
|
||||||
|
rshifts_extra = SKP_max( rshifts_extra, MIN_RSHIFTS - rshifts );
|
||||||
|
C0 = SKP_LSHIFT32( C0, -rshifts_extra );
|
||||||
|
}
|
||||||
|
rshifts += rshifts_extra;
|
||||||
|
}
|
||||||
|
SKP_memset( C_first_row, 0, SKP_Silk_MAX_ORDER_LPC * sizeof( SKP_int32 ) );
|
||||||
|
if( rshifts > 0 ) {
|
||||||
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
x_ptr = x + s * subfr_length;
|
||||||
|
for( n = 1; n < D + 1; n++ ) {
|
||||||
|
C_first_row[ n - 1 ] += (SKP_int32)SKP_RSHIFT64(
|
||||||
|
SKP_Silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
x_ptr = x + s * subfr_length;
|
||||||
|
for( n = 1; n < D + 1; n++ ) {
|
||||||
|
C_first_row[ n - 1 ] += SKP_LSHIFT32(
|
||||||
|
SKP_Silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SKP_memcpy( C_last_row, C_first_row, SKP_Silk_MAX_ORDER_LPC * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
/* Initialize */
|
||||||
|
CAb[ 0 ] = CAf[ 0 ] = C0 + SKP_SMMUL( WhiteNoiseFrac_Q32, C0 ) + 1; // Q(-rshifts)
|
||||||
|
|
||||||
|
for( n = 0; n < D; n++ ) {
|
||||||
|
/* Update first row of correlation matrix (without first element) */
|
||||||
|
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
||||||
|
/* Update C * Af */
|
||||||
|
/* Update C * flipud(Af) (stored in reversed order) */
|
||||||
|
if( rshifts > -2 ) {
|
||||||
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
x_ptr = x + s * subfr_length;
|
||||||
|
x1 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], 16 - rshifts ); // Q(16-rshifts)
|
||||||
|
x2 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); // Q(16-rshifts)
|
||||||
|
tmp1 = SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], QA - 16 ); // Q(QA-16)
|
||||||
|
tmp2 = SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); // Q(QA-16)
|
||||||
|
for( k = 0; k < n; k++ ) {
|
||||||
|
C_first_row[ k ] = SKP_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); // Q( -rshifts )
|
||||||
|
C_last_row[ k ] = SKP_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); // Q( -rshifts )
|
||||||
|
Atmp_QA = Af_QA[ k ];
|
||||||
|
tmp1 = SKP_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); // Q(QA-16)
|
||||||
|
tmp2 = SKP_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); // Q(QA-16)
|
||||||
|
}
|
||||||
|
tmp1 = SKP_LSHIFT32( -tmp1, 32 - QA - rshifts ); // Q(16-rshifts)
|
||||||
|
tmp2 = SKP_LSHIFT32( -tmp2, 32 - QA - rshifts ); // Q(16-rshifts)
|
||||||
|
for( k = 0; k <= n; k++ ) {
|
||||||
|
CAf[ k ] = SKP_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); // Q( -rshift )
|
||||||
|
CAb[ k ] = SKP_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); // Q( -rshift )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
x_ptr = x + s * subfr_length;
|
||||||
|
x1 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], -rshifts ); // Q( -rshifts )
|
||||||
|
x2 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); // Q( -rshifts )
|
||||||
|
tmp1 = SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], 17 ); // Q17
|
||||||
|
tmp2 = SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], 17 ); // Q17
|
||||||
|
for( k = 0; k < n; k++ ) {
|
||||||
|
C_first_row[ k ] = SKP_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); // Q( -rshifts )
|
||||||
|
C_last_row[ k ] = SKP_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); // Q( -rshifts )
|
||||||
|
Atmp1 = SKP_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); // Q17
|
||||||
|
tmp1 = SKP_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); // Q17
|
||||||
|
tmp2 = SKP_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); // Q17
|
||||||
|
}
|
||||||
|
tmp1 = -tmp1; // Q17
|
||||||
|
tmp2 = -tmp2; // Q17
|
||||||
|
for( k = 0; k <= n; k++ ) {
|
||||||
|
CAf[ k ] = SKP_SMLAWW( CAf[ k ], tmp1,
|
||||||
|
SKP_LSHIFT32( (SKP_int32)x_ptr[ n - k ], -rshifts - 1 ) ); // Q( -rshift )
|
||||||
|
CAb[ k ] = SKP_SMLAWW( CAb[ k ], tmp2,
|
||||||
|
SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) );// Q( -rshift )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
|
||||||
|
tmp1 = C_first_row[ n ]; // Q( -rshifts )
|
||||||
|
tmp2 = C_last_row[ n ]; // Q( -rshifts )
|
||||||
|
num = 0; // Q( -rshifts )
|
||||||
|
nrg = SKP_ADD32( CAb[ 0 ], CAf[ 0 ] ); // Q( 1-rshifts )
|
||||||
|
for( k = 0; k < n; k++ ) {
|
||||||
|
Atmp_QA = Af_QA[ k ];
|
||||||
|
lz = SKP_Silk_CLZ32( SKP_abs( Atmp_QA ) ) - 1;
|
||||||
|
lz = SKP_min( 32 - QA, lz );
|
||||||
|
Atmp1 = SKP_LSHIFT32( Atmp_QA, lz ); // Q( QA + lz )
|
||||||
|
|
||||||
|
tmp1 = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts )
|
||||||
|
tmp2 = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts )
|
||||||
|
num = SKP_ADD_LSHIFT32( num, SKP_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts )
|
||||||
|
nrg = SKP_ADD_LSHIFT32( nrg, SKP_SMMUL( SKP_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
|
||||||
|
Atmp1 ), 32 - QA - lz ); // Q( 1-rshifts )
|
||||||
|
}
|
||||||
|
CAf[ n + 1 ] = tmp1; // Q( -rshifts )
|
||||||
|
CAb[ n + 1 ] = tmp2; // Q( -rshifts )
|
||||||
|
num = SKP_ADD32( num, tmp2 ); // Q( -rshifts )
|
||||||
|
num = SKP_LSHIFT32( -num, 1 ); // Q( 1-rshifts )
|
||||||
|
|
||||||
|
/* Calculate the next order reflection (parcor) coefficient */
|
||||||
|
if( SKP_abs( num ) < nrg ) {
|
||||||
|
rc_Q31 = SKP_DIV32_varQ( num, nrg, 31 );
|
||||||
|
} else {
|
||||||
|
/* Negative energy or ratio too high; set remaining coefficients to zero and exit loop */
|
||||||
|
SKP_memset( &Af_QA[ n ], 0, ( D - n ) * sizeof( SKP_int32 ) );
|
||||||
|
SKP_assert( 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the AR coefficients */
|
||||||
|
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
||||||
|
tmp1 = Af_QA[ k ]; // QA
|
||||||
|
tmp2 = Af_QA[ n - k - 1 ]; // QA
|
||||||
|
Af_QA[ k ] = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( tmp2, rc_Q31 ), 1 ); // QA
|
||||||
|
Af_QA[ n - k - 1 ] = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( tmp1, rc_Q31 ), 1 ); // QA
|
||||||
|
}
|
||||||
|
Af_QA[ n ] = SKP_RSHIFT32( rc_Q31, 31 - QA ); // QA
|
||||||
|
|
||||||
|
/* Update C * Af and C * Ab */
|
||||||
|
for( k = 0; k <= n + 1; k++ ) {
|
||||||
|
tmp1 = CAf[ k ]; // Q( -rshifts )
|
||||||
|
tmp2 = CAb[ n - k + 1 ]; // Q( -rshifts )
|
||||||
|
CAf[ k ] = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( tmp2, rc_Q31 ), 1 ); // Q( -rshifts )
|
||||||
|
CAb[ n - k + 1 ] = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( tmp1, rc_Q31 ), 1 ); // Q( -rshifts )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return residual energy */
|
||||||
|
nrg = CAf[ 0 ]; // Q( -rshifts )
|
||||||
|
tmp1 = 1 << 16; // Q16
|
||||||
|
for( k = 0; k < D; k++ ) {
|
||||||
|
Atmp1 = SKP_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); // Q16
|
||||||
|
nrg = SKP_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); // Q( -rshifts )
|
||||||
|
tmp1 = SKP_SMLAWW( tmp1, Atmp1, Atmp1 ); // Q16
|
||||||
|
A_Q16[ k ] = -Atmp1;
|
||||||
|
}
|
||||||
|
*res_nrg = SKP_SMLAWW( nrg, SKP_SMMUL( WhiteNoiseFrac_Q32, C0 ), -tmp1 ); // Q( -rshifts )
|
||||||
|
*res_nrg_Q = -rshifts;
|
||||||
|
}
|
49
app/src/main/cpp/src/SKP_Silk_bwexpander.c
Normal file
49
app/src/main/cpp/src/SKP_Silk_bwexpander.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Chirp (bandwidth expand) LP AR filter */
|
||||||
|
void SKP_Silk_bwexpander(
|
||||||
|
SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||||
|
const SKP_int d, /* I Length of ar */
|
||||||
|
SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int32 chirp_minus_one_Q16;
|
||||||
|
|
||||||
|
chirp_minus_one_Q16 = chirp_Q16 - 65536;
|
||||||
|
|
||||||
|
/* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL() , 16 ), below. */
|
||||||
|
/* Bias in SKP_SMULWB can lead to unstable filters */
|
||||||
|
for( i = 0; i < d - 1; i++ ) {
|
||||||
|
ar[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ i ] ), 16 );
|
||||||
|
chirp_Q16 += SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
|
||||||
|
}
|
||||||
|
ar[ d - 1 ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
|
||||||
|
}
|
46
app/src/main/cpp/src/SKP_Silk_bwexpander_32.c
Normal file
46
app/src/main/cpp/src/SKP_Silk_bwexpander_32.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/* Chirp (bandwidth expand) LP AR filter */
|
||||||
|
void SKP_Silk_bwexpander_32(
|
||||||
|
SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||||
|
const SKP_int d, /* I Length of ar */
|
||||||
|
SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int32 tmp_chirp_Q16;
|
||||||
|
|
||||||
|
tmp_chirp_Q16 = chirp_Q16;
|
||||||
|
for( i = 0; i < d - 1; i++ ) {
|
||||||
|
ar[ i ] = SKP_SMULWW( ar[ i ], tmp_chirp_Q16 );
|
||||||
|
tmp_chirp_Q16 = SKP_SMULWW( chirp_Q16, tmp_chirp_Q16 );
|
||||||
|
}
|
||||||
|
ar[ d - 1 ] = SKP_SMULWW( ar[ d - 1 ], tmp_chirp_Q16 );
|
||||||
|
}
|
122
app/src/main/cpp/src/SKP_Silk_clz_arm.S
Normal file
122
app/src/main/cpp/src/SKP_Silk_clz_arm.S
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
#if (EMBEDDED_ARM>0) && (EMBEDDED_ARM<5)
|
||||||
|
|
||||||
|
.globl SYM(SKP_Silk_CLZ16)
|
||||||
|
.globl SYM(SKP_Silk_CLZ32)
|
||||||
|
|
||||||
|
SYM(SKP_Silk_CLZ16):
|
||||||
|
str lr, [sp, #-4]!
|
||||||
|
|
||||||
|
mov r2, r0
|
||||||
|
mov r0, #0
|
||||||
|
ands r1, r2, #0xF000
|
||||||
|
movne r1, r2, asr #12
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF00
|
||||||
|
movne r1, r2, asr #8
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF0
|
||||||
|
movne r1, r2, asr #4
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
mov r1, r2
|
||||||
|
0:
|
||||||
|
ands r2, r1, #0x8
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
ands r2, r1, #0x4
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
ands r2, r1, #0x2
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
ands r2, r1, #0x1
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
1:
|
||||||
|
ldr pc, [sp], #4
|
||||||
|
|
||||||
|
SYM(SKP_Silk_CLZ32):
|
||||||
|
|
||||||
|
str lr, [sp, #-4]!
|
||||||
|
|
||||||
|
mov r2, r0
|
||||||
|
mov r0, #0
|
||||||
|
ands r1, r2, #0xF0000000
|
||||||
|
movne r1, r2, asr #28
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF000000
|
||||||
|
movne r1, r2, asr #24
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF00000
|
||||||
|
movne r1, r2, asr #20
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF0000
|
||||||
|
movne r1, r2, asr #16
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF000
|
||||||
|
movne r1, r2, asr #12
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF00
|
||||||
|
movne r1, r2, asr #8
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
ands r1, r2, #0xF0
|
||||||
|
movne r1, r2, asr #4
|
||||||
|
bne 0f
|
||||||
|
add r0, r0, #4
|
||||||
|
mov r1, r2
|
||||||
|
0:
|
||||||
|
ands r2, r1, #0x8
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
ands r2, r1, #0x4
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
ands r2, r1, #0x2
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
ands r2, r1, #0x1
|
||||||
|
bne 1f
|
||||||
|
add r0, r0, #1
|
||||||
|
1:
|
||||||
|
ldr pc, [sp], #4
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
91
app/src/main/cpp/src/SKP_Silk_code_signs.c
Normal file
91
app/src/main/cpp/src/SKP_Silk_code_signs.c
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
//#define SKP_enc_map(a) ((a) > 0 ? 1 : 0)
|
||||||
|
//#define SKP_dec_map(a) ((a) > 0 ? 1 : -1)
|
||||||
|
/* shifting avoids if-statement */
|
||||||
|
#define SKP_enc_map(a) ( SKP_RSHIFT( (a), 15 ) + 1 )
|
||||||
|
#define SKP_dec_map(a) ( SKP_LSHIFT( (a), 1 ) - 1 )
|
||||||
|
|
||||||
|
/* Encodes signs of excitation */
|
||||||
|
void SKP_Silk_encode_signs(
|
||||||
|
SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */
|
||||||
|
const SKP_int8 q[], /* I Pulse signal */
|
||||||
|
const SKP_int length, /* I Length of input */
|
||||||
|
const SKP_int sigtype, /* I Signal type */
|
||||||
|
const SKP_int QuantOffsetType, /* I Quantization offset type */
|
||||||
|
const SKP_int RateLevelIndex /* I Rate level index */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int inData;
|
||||||
|
SKP_uint16 cdf[ 3 ];
|
||||||
|
|
||||||
|
i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
|
||||||
|
cdf[ 0 ] = 0;
|
||||||
|
cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
|
||||||
|
cdf[ 2 ] = 65535;
|
||||||
|
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
if( q[ i ] != 0 ) {
|
||||||
|
inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */
|
||||||
|
SKP_Silk_range_encoder( sRC, inData, cdf );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decodes signs of excitation */
|
||||||
|
void SKP_Silk_decode_signs(
|
||||||
|
SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */
|
||||||
|
SKP_int q[], /* I/O pulse signal */
|
||||||
|
const SKP_int length, /* I length of output */
|
||||||
|
const SKP_int sigtype, /* I Signal type */
|
||||||
|
const SKP_int QuantOffsetType, /* I Quantization offset type */
|
||||||
|
const SKP_int RateLevelIndex /* I Rate Level Index */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int data;
|
||||||
|
SKP_uint16 cdf[ 3 ];
|
||||||
|
|
||||||
|
i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
|
||||||
|
cdf[ 0 ] = 0;
|
||||||
|
cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
|
||||||
|
cdf[ 2 ] = 65535;
|
||||||
|
|
||||||
|
for( i = 0; i < length; i++ ) {
|
||||||
|
if( q[ i ] > 0 ) {
|
||||||
|
SKP_Silk_range_decoder( &data, sRC, cdf, 1 );
|
||||||
|
/* attach sign */
|
||||||
|
/* implementation with shift, subtraction, multiplication */
|
||||||
|
q[ i ] *= SKP_dec_map( data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
76
app/src/main/cpp/src/SKP_Silk_common_pitch_est_defines.h
Normal file
76
app/src/main/cpp/src/SKP_Silk_common_pitch_est_defines.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SIGPROC_COMMON_PITCH_EST_DEFINES_H
|
||||||
|
#define SIGPROC_COMMON_PITCH_EST_DEFINES_H
|
||||||
|
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Definitions For Fix pitch estimator */
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
|
#define PITCH_EST_MAX_FS_KHZ 24 /* Maximum sampling frequency used */
|
||||||
|
|
||||||
|
#define PITCH_EST_FRAME_LENGTH_MS 40 /* 40 ms */
|
||||||
|
|
||||||
|
#define PITCH_EST_MAX_FRAME_LENGTH (PITCH_EST_FRAME_LENGTH_MS * PITCH_EST_MAX_FS_KHZ)
|
||||||
|
#define PITCH_EST_MAX_FRAME_LENGTH_ST_1 (PITCH_EST_MAX_FRAME_LENGTH >> 2)
|
||||||
|
#define PITCH_EST_MAX_FRAME_LENGTH_ST_2 (PITCH_EST_MAX_FRAME_LENGTH >> 1)
|
||||||
|
#define PITCH_EST_MAX_SF_FRAME_LENGTH (PITCH_EST_SUB_FRAME * PITCH_EST_MAX_FS_KHZ)
|
||||||
|
|
||||||
|
#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */
|
||||||
|
#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */
|
||||||
|
#define PITCH_EST_MAX_LAG (PITCH_EST_MAX_LAG_MS * PITCH_EST_MAX_FS_KHZ)
|
||||||
|
#define PITCH_EST_MIN_LAG (PITCH_EST_MIN_LAG_MS * PITCH_EST_MAX_FS_KHZ)
|
||||||
|
|
||||||
|
#define PITCH_EST_NB_SUBFR 4
|
||||||
|
|
||||||
|
#define PITCH_EST_D_SRCH_LENGTH 24
|
||||||
|
|
||||||
|
#define PITCH_EST_MAX_DECIMATE_STATE_LENGTH 7
|
||||||
|
|
||||||
|
#define PITCH_EST_NB_STAGE3_LAGS 5
|
||||||
|
|
||||||
|
#define PITCH_EST_NB_CBKS_STAGE2 3
|
||||||
|
#define PITCH_EST_NB_CBKS_STAGE2_EXT 11
|
||||||
|
|
||||||
|
#define PITCH_EST_CB_mn2 1
|
||||||
|
#define PITCH_EST_CB_mx2 2
|
||||||
|
|
||||||
|
#define PITCH_EST_NB_CBKS_STAGE3_MAX 34
|
||||||
|
#define PITCH_EST_NB_CBKS_STAGE3_MID 24
|
||||||
|
#define PITCH_EST_NB_CBKS_STAGE3_MIN 16
|
||||||
|
|
||||||
|
extern const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT];
|
||||||
|
extern const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX];
|
||||||
|
extern const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ];
|
||||||
|
extern const SKP_int16 SKP_Silk_cbk_sizes_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ];
|
||||||
|
extern const SKP_int16 SKP_Silk_cbk_offsets_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ];
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
137
app/src/main/cpp/src/SKP_Silk_control_audio_bandwidth.c
Normal file
137
app/src/main/cpp/src/SKP_Silk_control_audio_bandwidth.c
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* Control internal sampling rate */
|
||||||
|
SKP_int SKP_Silk_control_audio_bandwidth(
|
||||||
|
SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
|
||||||
|
const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int fs_kHz;
|
||||||
|
|
||||||
|
fs_kHz = psEncC->fs_kHz;
|
||||||
|
if( fs_kHz == 0 ) {
|
||||||
|
/* Encoder has just been initialized */
|
||||||
|
if( TargetRate_bps >= SWB2WB_BITRATE_BPS ) {
|
||||||
|
fs_kHz = 24;
|
||||||
|
} else if( TargetRate_bps >= WB2MB_BITRATE_BPS ) {
|
||||||
|
fs_kHz = 16;
|
||||||
|
} else if( TargetRate_bps >= MB2NB_BITRATE_BPS ) {
|
||||||
|
fs_kHz = 12;
|
||||||
|
} else {
|
||||||
|
fs_kHz = 8;
|
||||||
|
}
|
||||||
|
/* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
|
||||||
|
fs_kHz = SKP_min( fs_kHz, SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ) );
|
||||||
|
fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz );
|
||||||
|
} else if( SKP_SMULBB( fs_kHz, 1000 ) > psEncC->API_fs_Hz || fs_kHz > psEncC->maxInternal_fs_kHz ) {
|
||||||
|
/* Make sure internal rate is not higher than external rate or maximum allowed */
|
||||||
|
fs_kHz = SKP_DIV32_16( psEncC->API_fs_Hz, 1000 );
|
||||||
|
fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz );
|
||||||
|
} else {
|
||||||
|
/* State machine for the internal sampling rate switching */
|
||||||
|
if( psEncC->API_fs_Hz > 8000 ) {
|
||||||
|
/* Accumulate the difference between the target rate and limit for switching down */
|
||||||
|
psEncC->bitrateDiff += SKP_MUL( psEncC->PacketSize_ms, TargetRate_bps - psEncC->bitrate_threshold_down );
|
||||||
|
psEncC->bitrateDiff = SKP_min( psEncC->bitrateDiff, 0 );
|
||||||
|
|
||||||
|
if( psEncC->vadFlag == NO_VOICE_ACTIVITY ) { /* Low speech activity */
|
||||||
|
/* Check if we should switch down */
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
if( ( psEncC->sLP.transition_frame_no == 0 ) && /* Transition phase not active */
|
||||||
|
( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */
|
||||||
|
( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */
|
||||||
|
psEncC->sLP.transition_frame_no = 1; /* Begin transition phase */
|
||||||
|
psEncC->sLP.mode = 0; /* Switch down */
|
||||||
|
} else if(
|
||||||
|
( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */
|
||||||
|
( psEncC->sLP.mode == 0 ) ) { /* Ready to switch down */
|
||||||
|
psEncC->sLP.transition_frame_no = 0; /* Ready for new transition phase */
|
||||||
|
#else
|
||||||
|
if( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */
|
||||||
|
#endif
|
||||||
|
psEncC->bitrateDiff = 0;
|
||||||
|
|
||||||
|
/* Switch to a lower sample frequency */
|
||||||
|
if( psEncC->fs_kHz == 24 ) {
|
||||||
|
fs_kHz = 16;
|
||||||
|
} else if( psEncC->fs_kHz == 16 ) {
|
||||||
|
fs_kHz = 12;
|
||||||
|
} else {
|
||||||
|
SKP_assert( psEncC->fs_kHz == 12 );
|
||||||
|
fs_kHz = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we should switch up */
|
||||||
|
if( ( ( psEncC->fs_kHz * 1000 < psEncC->API_fs_Hz ) &&
|
||||||
|
( TargetRate_bps >= psEncC->bitrate_threshold_up ) &&
|
||||||
|
( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz < 16 ) ) &&
|
||||||
|
( ( ( psEncC->fs_kHz == 16 ) && ( psEncC->maxInternal_fs_kHz >= 24 ) ) ||
|
||||||
|
( ( psEncC->fs_kHz == 12 ) && ( psEncC->maxInternal_fs_kHz >= 16 ) ) ||
|
||||||
|
( ( psEncC->fs_kHz == 8 ) && ( psEncC->maxInternal_fs_kHz >= 12 ) ) )
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
&& ( psEncC->sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */
|
||||||
|
psEncC->sLP.mode = 1; /* Switch up */
|
||||||
|
#else
|
||||||
|
) {
|
||||||
|
#endif
|
||||||
|
psEncC->bitrateDiff = 0;
|
||||||
|
|
||||||
|
/* Switch to a higher sample frequency */
|
||||||
|
if( psEncC->fs_kHz == 8 ) {
|
||||||
|
fs_kHz = 12;
|
||||||
|
} else if( psEncC->fs_kHz == 12 ) {
|
||||||
|
fs_kHz = 16;
|
||||||
|
} else {
|
||||||
|
SKP_assert( psEncC->fs_kHz == 16 );
|
||||||
|
fs_kHz = 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
/* After switching up, stop transition filter during speech inactivity */
|
||||||
|
if( ( psEncC->sLP.mode == 1 ) &&
|
||||||
|
( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) &&
|
||||||
|
( psEncC->vadFlag == NO_VOICE_ACTIVITY ) ) {
|
||||||
|
|
||||||
|
psEncC->sLP.transition_frame_no = 0;
|
||||||
|
|
||||||
|
/* Reset transition filter state */
|
||||||
|
SKP_memset( psEncC->sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return fs_kHz;
|
||||||
|
}
|
402
app/src/main/cpp/src/SKP_Silk_control_codec_FIX.c
Normal file
402
app/src/main/cpp/src/SKP_Silk_control_codec_FIX.c
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_setup_complexity.h"
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_resamplers_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_packetsize_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int PacketSize_ms /* I Packet length (ms) */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_fs_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_rate_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int32 TargetRate_bps /* I Target max bitrate (if SNR_dB == 0) */
|
||||||
|
);
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_LBRR_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Control encoder */
|
||||||
|
SKP_int SKP_Silk_control_encoder_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */
|
||||||
|
const SKP_int PacketSize_ms, /* I Packet length (ms) */
|
||||||
|
const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
|
||||||
|
const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */
|
||||||
|
const SKP_int DTX_enabled, /* I Enable / disable DTX */
|
||||||
|
const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int fs_kHz, ret = 0;
|
||||||
|
|
||||||
|
if( psEnc->sCmn.controlled_since_last_payload != 0 ) {
|
||||||
|
if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
|
||||||
|
/* Change in API sampling rate in the middle of encoding a packet */
|
||||||
|
ret += SKP_Silk_setup_resamplers_FIX( psEnc, psEnc->sCmn.fs_kHz );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Beyond this point we know that there are no previously coded frames in the payload buffer */
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Determine internal sampling rate */
|
||||||
|
/********************************************/
|
||||||
|
fs_kHz = SKP_Silk_control_audio_bandwidth( &psEnc->sCmn, TargetRate_bps );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Prepare resampler and buffered data */
|
||||||
|
/********************************************/
|
||||||
|
ret += SKP_Silk_setup_resamplers_FIX( psEnc, fs_kHz );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set packet size */
|
||||||
|
/********************************************/
|
||||||
|
ret += SKP_Silk_setup_packetsize_FIX( psEnc, PacketSize_ms );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set internal sampling frequency */
|
||||||
|
/********************************************/
|
||||||
|
ret += SKP_Silk_setup_fs_FIX( psEnc, fs_kHz );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set encoding complexity */
|
||||||
|
/********************************************/
|
||||||
|
ret += SKP_Silk_setup_complexity( &psEnc->sCmn, Complexity );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set bitrate/coding quality */
|
||||||
|
/********************************************/
|
||||||
|
ret += SKP_Silk_setup_rate_FIX( psEnc, TargetRate_bps );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set packet loss rate measured by farend */
|
||||||
|
/********************************************/
|
||||||
|
if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) {
|
||||||
|
ret = SKP_SILK_ENC_INVALID_LOSS_RATE;
|
||||||
|
}
|
||||||
|
psEnc->sCmn.PacketLoss_perc = PacketLoss_perc;
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set LBRR usage */
|
||||||
|
/********************************************/
|
||||||
|
ret += SKP_Silk_setup_LBRR_FIX( psEnc );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Set DTX mode */
|
||||||
|
/********************************************/
|
||||||
|
if( DTX_enabled < 0 || DTX_enabled > 1 ) {
|
||||||
|
ret = SKP_SILK_ENC_INVALID_DTX_SETTING;
|
||||||
|
}
|
||||||
|
psEnc->sCmn.useDTX = DTX_enabled;
|
||||||
|
psEnc->sCmn.controlled_since_last_payload = 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Control low bitrate redundancy usage */
|
||||||
|
void SKP_Silk_LBRR_ctrl_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I Encoder state FIX */
|
||||||
|
SKP_Silk_encoder_control *psEncCtrlC /* I/O Encoder control */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int LBRR_usage;
|
||||||
|
|
||||||
|
if( psEnc->sCmn.LBRR_enabled ) {
|
||||||
|
/* Control LBRR */
|
||||||
|
|
||||||
|
/* Usage Control based on sensitivity and packet loss caracteristics */
|
||||||
|
/* For now only enable adding to next for active frames. Make more complex later */
|
||||||
|
LBRR_usage = SKP_SILK_NO_LBRR;
|
||||||
|
if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { // nb! maybe multiply loss prob and speech activity
|
||||||
|
LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS1;
|
||||||
|
}
|
||||||
|
psEncCtrlC->LBRR_usage = LBRR_usage;
|
||||||
|
} else {
|
||||||
|
psEncCtrlC->LBRR_usage = SKP_SILK_NO_LBRR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_resamplers_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int ret = SKP_SILK_NO_ERROR;
|
||||||
|
|
||||||
|
if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) {
|
||||||
|
|
||||||
|
if( psEnc->sCmn.fs_kHz == 0 ) {
|
||||||
|
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
||||||
|
ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000 );
|
||||||
|
} else {
|
||||||
|
/* Allocate space for worst case temporary upsampling, 8 to 48 kHz, so a factor 6 */
|
||||||
|
SKP_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * ( MAX_API_FS_KHZ / 8 ) ];
|
||||||
|
|
||||||
|
SKP_int32 nSamples_temp = SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + LA_SHAPE_MS * psEnc->sCmn.fs_kHz;
|
||||||
|
|
||||||
|
if( SKP_SMULBB( fs_kHz, 1000 ) < psEnc->sCmn.API_fs_Hz && psEnc->sCmn.fs_kHz != 0 ) {
|
||||||
|
/* Resample buffered data in x_buf to API_fs_Hz */
|
||||||
|
|
||||||
|
SKP_Silk_resampler_state_struct temp_resampler_state;
|
||||||
|
|
||||||
|
/* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
|
||||||
|
ret += SKP_Silk_resampler_init( &temp_resampler_state, SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz );
|
||||||
|
|
||||||
|
/* Temporary resampling of x_buf data to API_fs_Hz */
|
||||||
|
ret += SKP_Silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, psEnc->x_buf, nSamples_temp );
|
||||||
|
|
||||||
|
/* Calculate number of samples that has been temporarily upsampled */
|
||||||
|
nSamples_temp = SKP_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) );
|
||||||
|
|
||||||
|
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
||||||
|
ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, SKP_SMULBB( fs_kHz, 1000 ) );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Copy data */
|
||||||
|
SKP_memcpy( x_buf_API_fs_Hz, psEnc->x_buf, nSamples_temp * sizeof( SKP_int16 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( 1000 * fs_kHz != psEnc->sCmn.API_fs_Hz ) {
|
||||||
|
/* Correct resampler state (unless resampling by a factor 1) by resampling buffered data from API_fs_Hz to fs_kHz */
|
||||||
|
ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state, psEnc->x_buf, x_buf_API_fs_Hz, nSamples_temp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_packetsize_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int PacketSize_ms /* I Packet length (ms) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int ret = SKP_SILK_NO_ERROR;
|
||||||
|
|
||||||
|
/* Set packet size */
|
||||||
|
if( ( PacketSize_ms != 20 ) &&
|
||||||
|
( PacketSize_ms != 40 ) &&
|
||||||
|
( PacketSize_ms != 60 ) &&
|
||||||
|
( PacketSize_ms != 80 ) &&
|
||||||
|
( PacketSize_ms != 100 ) ) {
|
||||||
|
ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
|
||||||
|
} else {
|
||||||
|
if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
|
||||||
|
psEnc->sCmn.PacketSize_ms = PacketSize_ms;
|
||||||
|
|
||||||
|
/* Packet length changes. Reset LBRR buffer */
|
||||||
|
SKP_Silk_LBRR_reset( &psEnc->sCmn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_fs_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int fs_kHz /* I Internal sampling rate (kHz) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int ret = SKP_SILK_NO_ERROR;
|
||||||
|
|
||||||
|
/* Set internal sampling frequency */
|
||||||
|
if( psEnc->sCmn.fs_kHz != fs_kHz ) {
|
||||||
|
/* reset part of the state */
|
||||||
|
SKP_memset( &psEnc->sShape, 0, sizeof( SKP_Silk_shape_state_FIX ) );
|
||||||
|
SKP_memset( &psEnc->sPrefilt, 0, sizeof( SKP_Silk_prefilter_state_FIX ) );
|
||||||
|
SKP_memset( &psEnc->sPred, 0, sizeof( SKP_Silk_predict_state_FIX ) );
|
||||||
|
SKP_memset( &psEnc->sCmn.sNSQ, 0, sizeof( SKP_Silk_nsq_state ) );
|
||||||
|
SKP_memset( psEnc->sCmn.sNSQ_LBRR.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );
|
||||||
|
SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) );
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
|
||||||
|
if( psEnc->sCmn.sLP.mode == 1 ) {
|
||||||
|
/* Begin transition phase */
|
||||||
|
psEnc->sCmn.sLP.transition_frame_no = 1;
|
||||||
|
} else {
|
||||||
|
/* End transition phase */
|
||||||
|
psEnc->sCmn.sLP.transition_frame_no = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
psEnc->sCmn.inputBufIx = 0;
|
||||||
|
psEnc->sCmn.nFramesInPayloadBuf = 0;
|
||||||
|
psEnc->sCmn.nBytesInPayloadBuf = 0;
|
||||||
|
psEnc->sCmn.oldest_LBRR_idx = 0;
|
||||||
|
psEnc->sCmn.TargetRate_bps = 0; /* Ensures that psEnc->SNR_dB is recomputed */
|
||||||
|
|
||||||
|
SKP_memset( psEnc->sPred.prev_NLSFq_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
|
||||||
|
|
||||||
|
/* Initialize non-zero parameters */
|
||||||
|
psEnc->sCmn.prevLag = 100;
|
||||||
|
psEnc->sCmn.prev_sigtype = SIG_TYPE_UNVOICED;
|
||||||
|
psEnc->sCmn.first_frame_after_reset = 1;
|
||||||
|
psEnc->sPrefilt.lagPrev = 100;
|
||||||
|
psEnc->sShape.LastGainIndex = 1;
|
||||||
|
psEnc->sCmn.sNSQ.lagPrev = 100;
|
||||||
|
psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536;
|
||||||
|
psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536;
|
||||||
|
|
||||||
|
psEnc->sCmn.fs_kHz = fs_kHz;
|
||||||
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||||
|
psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
|
||||||
|
psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
|
||||||
|
psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
|
||||||
|
} else {
|
||||||
|
psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
|
||||||
|
psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
|
||||||
|
psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
|
||||||
|
}
|
||||||
|
psEnc->sCmn.frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );
|
||||||
|
psEnc->sCmn.subfr_length = SKP_DIV32_16( psEnc->sCmn.frame_length, NB_SUBFR );
|
||||||
|
psEnc->sCmn.la_pitch = SKP_SMULBB( LA_PITCH_MS, fs_kHz );
|
||||||
|
psEnc->sPred.min_pitch_lag = SKP_SMULBB( 3, fs_kHz );
|
||||||
|
psEnc->sPred.max_pitch_lag = SKP_SMULBB( 18, fs_kHz );
|
||||||
|
psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
|
||||||
|
if( psEnc->sCmn.fs_kHz == 24 ) {
|
||||||
|
psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_SWB, 8 );
|
||||||
|
psEnc->sCmn.bitrate_threshold_up = SKP_int32_MAX;
|
||||||
|
psEnc->sCmn.bitrate_threshold_down = SWB2WB_BITRATE_BPS;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
||||||
|
psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_WB, 8 );
|
||||||
|
psEnc->sCmn.bitrate_threshold_up = WB2SWB_BITRATE_BPS;
|
||||||
|
psEnc->sCmn.bitrate_threshold_down = WB2MB_BITRATE_BPS;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
||||||
|
psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_MB, 8 );
|
||||||
|
psEnc->sCmn.bitrate_threshold_up = MB2WB_BITRATE_BPS;
|
||||||
|
psEnc->sCmn.bitrate_threshold_down = MB2NB_BITRATE_BPS;
|
||||||
|
} else {
|
||||||
|
psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_NB, 8 );
|
||||||
|
psEnc->sCmn.bitrate_threshold_up = NB2MB_BITRATE_BPS;
|
||||||
|
psEnc->sCmn.bitrate_threshold_down = 0;
|
||||||
|
}
|
||||||
|
psEnc->sCmn.fs_kHz_changed = 1;
|
||||||
|
|
||||||
|
/* Check that settings are valid */
|
||||||
|
SKP_assert( ( psEnc->sCmn.subfr_length * NB_SUBFR ) == psEnc->sCmn.frame_length );
|
||||||
|
}
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_rate_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
SKP_int32 TargetRate_bps /* I Target max bitrate (if SNR_dB == 0) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, ret = SKP_SILK_NO_ERROR;
|
||||||
|
SKP_int32 frac_Q6;
|
||||||
|
const SKP_int32 *rateTable;
|
||||||
|
|
||||||
|
/* Set bitrate/coding quality */
|
||||||
|
if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) {
|
||||||
|
psEnc->sCmn.TargetRate_bps = TargetRate_bps;
|
||||||
|
|
||||||
|
/* If new TargetRate_bps, translate to SNR_dB value */
|
||||||
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||||
|
rateTable = TargetRate_table_NB;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
||||||
|
rateTable = TargetRate_table_MB;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
||||||
|
rateTable = TargetRate_table_WB;
|
||||||
|
} else {
|
||||||
|
rateTable = TargetRate_table_SWB;
|
||||||
|
}
|
||||||
|
for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
|
||||||
|
/* Find bitrate interval in table and interpolate */
|
||||||
|
if( TargetRate_bps <= rateTable[ k ] ) {
|
||||||
|
frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ),
|
||||||
|
rateTable[ k ] - rateTable[ k - 1 ] );
|
||||||
|
psEnc->SNR_dB_Q7 = SKP_LSHIFT( SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int SKP_Silk_setup_LBRR_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk encoder state FIX */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int ret = SKP_SILK_NO_ERROR;
|
||||||
|
#if USE_LBRR
|
||||||
|
SKP_int32 LBRRRate_thres_bps;
|
||||||
|
|
||||||
|
if( psEnc->sCmn.useInBandFEC < 0 || psEnc->sCmn.useInBandFEC > 1 ) {
|
||||||
|
ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
psEnc->sCmn.LBRR_enabled = psEnc->sCmn.useInBandFEC;
|
||||||
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||||
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
||||||
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
||||||
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000;
|
||||||
|
} else {
|
||||||
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) {
|
||||||
|
/* Set gain increase / rate reduction for LBRR usage */
|
||||||
|
/* Coarsely tuned with PESQ for now. */
|
||||||
|
/* Linear regression coefs G = 8 - 0.5 * loss */
|
||||||
|
/* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */
|
||||||
|
psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 );
|
||||||
|
|
||||||
|
/* Set main stream rate compensation */
|
||||||
|
if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {
|
||||||
|
/* Tuned to give approx same mean / weighted bitrate as no inband FEC */
|
||||||
|
psEnc->inBandFEC_SNR_comp_Q8 = SKP_FIX_CONST( 6.0f, 8 ) - SKP_LSHIFT( psEnc->sCmn.LBRR_GainIncreases, 7 );
|
||||||
|
} else {
|
||||||
|
psEnc->inBandFEC_SNR_comp_Q8 = 0;
|
||||||
|
psEnc->sCmn.LBRR_enabled = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
psEnc->inBandFEC_SNR_comp_Q8 = 0;
|
||||||
|
psEnc->sCmn.LBRR_enabled = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if( INBandFEC_enabled != 0 ) {
|
||||||
|
ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;
|
||||||
|
}
|
||||||
|
psEnc->sCmn.LBRR_enabled = 0;
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
153
app/src/main/cpp/src/SKP_Silk_corrMatrix_FIX.c
Normal file
153
app/src/main/cpp/src/SKP_Silk_corrMatrix_FIX.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Correlation Matrix Computations for LS estimate.
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
|
||||||
|
/* Calculates correlation vector X'*t */
|
||||||
|
void SKP_Silk_corrVector_FIX(
|
||||||
|
const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||||
|
const SKP_int16 *t, /* I target vector [L] */
|
||||||
|
const SKP_int L, /* I Length of vectors */
|
||||||
|
const SKP_int order, /* I Max lag for correlation */
|
||||||
|
SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
|
||||||
|
const SKP_int rshifts /* I Right shifts of correlations */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int lag, i;
|
||||||
|
const SKP_int16 *ptr1, *ptr2;
|
||||||
|
SKP_int32 inner_prod;
|
||||||
|
|
||||||
|
ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
|
||||||
|
ptr2 = t;
|
||||||
|
/* Calculate X'*t */
|
||||||
|
if( rshifts > 0 ) {
|
||||||
|
/* Right shifting used */
|
||||||
|
for( lag = 0; lag < order; lag++ ) {
|
||||||
|
inner_prod = 0;
|
||||||
|
for( i = 0; i < L; i++ ) {
|
||||||
|
inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
|
||||||
|
}
|
||||||
|
Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
|
||||||
|
ptr1--; /* Go to next column of X */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_assert( rshifts == 0 );
|
||||||
|
for( lag = 0; lag < order; lag++ ) {
|
||||||
|
Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */
|
||||||
|
ptr1--; /* Go to next column of X */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculates correlation matrix X'*X */
|
||||||
|
void SKP_Silk_corrMatrix_FIX(
|
||||||
|
const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||||
|
const SKP_int L, /* I Length of vectors */
|
||||||
|
const SKP_int order, /* I Max lag for correlation */
|
||||||
|
const SKP_int head_room, /* I Desired headroom */
|
||||||
|
SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/
|
||||||
|
SKP_int *rshifts /* I/O Right shifts of correlations */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, j, lag, rshifts_local, head_room_rshifts;
|
||||||
|
SKP_int32 energy;
|
||||||
|
const SKP_int16 *ptr1, *ptr2;
|
||||||
|
|
||||||
|
/* Calculate energy to find shift used to fit in 32 bits */
|
||||||
|
SKP_Silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );
|
||||||
|
|
||||||
|
/* Add shifts to get the desired head room */
|
||||||
|
head_room_rshifts = SKP_max( head_room - SKP_Silk_CLZ32( energy ), 0 );
|
||||||
|
|
||||||
|
energy = SKP_RSHIFT32( energy, head_room_rshifts );
|
||||||
|
rshifts_local += head_room_rshifts;
|
||||||
|
|
||||||
|
/* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
|
||||||
|
/* Remove contribution of first order - 1 samples */
|
||||||
|
for( i = 0; i < order - 1; i++ ) {
|
||||||
|
energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local );
|
||||||
|
}
|
||||||
|
if( rshifts_local < *rshifts ) {
|
||||||
|
/* Adjust energy */
|
||||||
|
energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local );
|
||||||
|
rshifts_local = *rshifts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
|
||||||
|
/* Fill out the diagonal of the correlation matrix */
|
||||||
|
matrix_ptr( XX, 0, 0, order ) = energy;
|
||||||
|
ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
|
||||||
|
for( j = 1; j < order; j++ ) {
|
||||||
|
energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );
|
||||||
|
energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );
|
||||||
|
matrix_ptr( XX, j, j, order ) = energy;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
|
||||||
|
/* Calculate the remaining elements of the correlation matrix */
|
||||||
|
if( rshifts_local > 0 ) {
|
||||||
|
/* Right shifting used */
|
||||||
|
for( lag = 1; lag < order; lag++ ) {
|
||||||
|
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
|
||||||
|
energy = 0;
|
||||||
|
for( i = 0; i < L; i++ ) {
|
||||||
|
energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );
|
||||||
|
}
|
||||||
|
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
|
||||||
|
matrix_ptr( XX, lag, 0, order ) = energy;
|
||||||
|
matrix_ptr( XX, 0, lag, order ) = energy;
|
||||||
|
for( j = 1; j < ( order - lag ); j++ ) {
|
||||||
|
energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );
|
||||||
|
energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );
|
||||||
|
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||||
|
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||||
|
}
|
||||||
|
ptr2--; /* Update pointer to first sample of next column (lag) in X */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for( lag = 1; lag < order; lag++ ) {
|
||||||
|
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
|
||||||
|
energy = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L );
|
||||||
|
matrix_ptr( XX, lag, 0, order ) = energy;
|
||||||
|
matrix_ptr( XX, 0, lag, order ) = energy;
|
||||||
|
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
|
||||||
|
for( j = 1; j < ( order - lag ); j++ ) {
|
||||||
|
energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
|
||||||
|
energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
|
||||||
|
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||||
|
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||||
|
}
|
||||||
|
ptr2--;/* Update pointer to first sample of next column (lag) in X */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*rshifts = rshifts_local;
|
||||||
|
}
|
||||||
|
|
53
app/src/main/cpp/src/SKP_Silk_create_init_destroy.c
Normal file
53
app/src/main/cpp/src/SKP_Silk_create_init_destroy.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* Init Decoder State */
|
||||||
|
/************************/
|
||||||
|
SKP_int SKP_Silk_init_decoder(
|
||||||
|
SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_memset( psDec, 0, sizeof( SKP_Silk_decoder_state ) );
|
||||||
|
/* Set sampling rate to 24 kHz, and init non-zero values */
|
||||||
|
SKP_Silk_decoder_set_fs( psDec, 24 );
|
||||||
|
|
||||||
|
/* Used to deactivate e.g. LSF interpolation and fluctuation reduction */
|
||||||
|
psDec->first_frame_after_reset = 1;
|
||||||
|
psDec->prev_inv_gain_Q16 = 65536;
|
||||||
|
|
||||||
|
/* Reset CNG state */
|
||||||
|
SKP_Silk_CNG_Reset( psDec );
|
||||||
|
|
||||||
|
SKP_Silk_PLC_Reset( psDec );
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
279
app/src/main/cpp/src/SKP_Silk_dec_API.c
Normal file
279
app/src/main/cpp/src/SKP_Silk_dec_API.c
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_SDK_API.h"
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
/* Decoder functions */
|
||||||
|
/*********************/
|
||||||
|
|
||||||
|
SKP_int SKP_Silk_SDK_Get_Decoder_Size( SKP_int32 *decSizeBytes )
|
||||||
|
{
|
||||||
|
SKP_int ret = 0;
|
||||||
|
|
||||||
|
*decSizeBytes = sizeof( SKP_Silk_decoder_state );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset decoder state */
|
||||||
|
SKP_int SKP_Silk_SDK_InitDecoder(
|
||||||
|
void* decState /* I/O: State */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int ret = 0;
|
||||||
|
SKP_Silk_decoder_state *struc;
|
||||||
|
|
||||||
|
struc = (SKP_Silk_decoder_state *)decState;
|
||||||
|
|
||||||
|
ret = SKP_Silk_init_decoder( struc );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode a frame */
|
||||||
|
SKP_int SKP_Silk_SDK_Decode(
|
||||||
|
void* decState, /* I/O: State */
|
||||||
|
SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control structure */
|
||||||
|
SKP_int lostFlag, /* I: 0: no loss, 1 loss */
|
||||||
|
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||||
|
const SKP_int nBytesIn, /* I: Number of input Bytes */
|
||||||
|
SKP_int16 *samplesOut, /* O: Decoded output speech vector */
|
||||||
|
SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int ret = 0, used_bytes, prev_fs_kHz;
|
||||||
|
SKP_Silk_decoder_state *psDec;
|
||||||
|
SKP_int16 samplesOutInternal[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ];
|
||||||
|
SKP_int16 *pSamplesOutInternal;
|
||||||
|
|
||||||
|
psDec = (SKP_Silk_decoder_state *)decState;
|
||||||
|
|
||||||
|
/* We need this buffer to have room for an internal frame */
|
||||||
|
pSamplesOutInternal = samplesOut;
|
||||||
|
if( psDec->fs_kHz * 1000 > decControl->API_sampleRate ) {
|
||||||
|
pSamplesOutInternal = samplesOutInternal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************/
|
||||||
|
/* Test if first frame in payload */
|
||||||
|
/**********************************/
|
||||||
|
if( psDec->moreInternalDecoderFrames == 0 ) {
|
||||||
|
/* First Frame in Payload */
|
||||||
|
psDec->nFramesDecoded = 0; /* Used to count frames in packet */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( psDec->moreInternalDecoderFrames == 0 && /* First frame in packet */
|
||||||
|
lostFlag == 0 && /* Not packet loss */
|
||||||
|
nBytesIn > MAX_ARITHM_BYTES ) { /* Too long payload */
|
||||||
|
/* Avoid trying to decode a too large packet */
|
||||||
|
lostFlag = 1;
|
||||||
|
ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save previous sample frequency */
|
||||||
|
prev_fs_kHz = psDec->fs_kHz;
|
||||||
|
|
||||||
|
/* Call decoder for one frame */
|
||||||
|
ret += SKP_Silk_decode_frame( psDec, pSamplesOutInternal, nSamplesOut, inData, nBytesIn,
|
||||||
|
lostFlag, &used_bytes );
|
||||||
|
|
||||||
|
if( used_bytes ) { /* Only Call if not a packet loss */
|
||||||
|
if( psDec->nBytesLeft > 0 && psDec->FrameTermination == SKP_SILK_MORE_FRAMES && psDec->nFramesDecoded < 5 ) {
|
||||||
|
/* We have more frames in the Payload */
|
||||||
|
psDec->moreInternalDecoderFrames = 1;
|
||||||
|
} else {
|
||||||
|
/* Last frame in Payload */
|
||||||
|
psDec->moreInternalDecoderFrames = 0;
|
||||||
|
psDec->nFramesInPacket = psDec->nFramesDecoded;
|
||||||
|
|
||||||
|
/* Track inband FEC usage */
|
||||||
|
if( psDec->vadFlag == VOICE_ACTIVITY ) {
|
||||||
|
if( psDec->FrameTermination == SKP_SILK_LAST_FRAME ) {
|
||||||
|
psDec->no_FEC_counter++;
|
||||||
|
if( psDec->no_FEC_counter > NO_LBRR_THRES ) {
|
||||||
|
psDec->inband_FEC_offset = 0;
|
||||||
|
}
|
||||||
|
} else if( psDec->FrameTermination == SKP_SILK_LBRR_VER1 ) {
|
||||||
|
psDec->inband_FEC_offset = 1; /* FEC info with 1 packet delay */
|
||||||
|
psDec->no_FEC_counter = 0;
|
||||||
|
} else if( psDec->FrameTermination == SKP_SILK_LBRR_VER2 ) {
|
||||||
|
psDec->inband_FEC_offset = 2; /* FEC info with 2 packets delay */
|
||||||
|
psDec->no_FEC_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( MAX_API_FS_KHZ * 1000 < decControl->API_sampleRate ||
|
||||||
|
8000 > decControl->API_sampleRate ) {
|
||||||
|
ret = SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY;
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resample if needed */
|
||||||
|
if( psDec->fs_kHz * 1000 != decControl->API_sampleRate ) {
|
||||||
|
SKP_int16 samplesOut_tmp[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ];
|
||||||
|
SKP_assert( psDec->fs_kHz <= MAX_API_FS_KHZ );
|
||||||
|
|
||||||
|
/* Copy to a tmp buffer as the resampling writes to samplesOut */
|
||||||
|
SKP_memcpy( samplesOut_tmp, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
/* (Re-)initialize resampler state when switching internal sampling frequency */
|
||||||
|
if( prev_fs_kHz != psDec->fs_kHz || psDec->prev_API_sampleRate != decControl->API_sampleRate ) {
|
||||||
|
ret = SKP_Silk_resampler_init( &psDec->resampler_state, SKP_SMULBB( psDec->fs_kHz, 1000 ), decControl->API_sampleRate );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resample the output to API_sampleRate */
|
||||||
|
ret += SKP_Silk_resampler( &psDec->resampler_state, samplesOut, samplesOut_tmp, *nSamplesOut );
|
||||||
|
|
||||||
|
/* Update the number of output samples */
|
||||||
|
*nSamplesOut = SKP_DIV32( ( SKP_int32 )*nSamplesOut * decControl->API_sampleRate, psDec->fs_kHz * 1000 );
|
||||||
|
} else if( prev_fs_kHz * 1000 > decControl->API_sampleRate ) {
|
||||||
|
SKP_memcpy( samplesOut, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
psDec->prev_API_sampleRate = decControl->API_sampleRate;
|
||||||
|
|
||||||
|
/* Copy all parameters that are needed out of internal structure to the control stucture */
|
||||||
|
decControl->frameSize = (SKP_uint16)( decControl->API_sampleRate / 50 ) ;
|
||||||
|
decControl->framesPerPacket = ( SKP_int )psDec->nFramesInPacket;
|
||||||
|
decControl->inBandFECOffset = ( SKP_int )psDec->inband_FEC_offset;
|
||||||
|
decControl->moreInternalDecoderFrames = ( SKP_int )psDec->moreInternalDecoderFrames;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to find LBRR information in a packet */
|
||||||
|
void SKP_Silk_SDK_search_for_LBRR(
|
||||||
|
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||||
|
const SKP_int nBytesIn, /* I: Number of input Bytes */
|
||||||
|
SKP_int lost_offset, /* I: Offset from lost packet */
|
||||||
|
SKP_uint8 *LBRRData, /* O: LBRR payload */
|
||||||
|
SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_decoder_state sDec; // Local decoder state to avoid interfering with running decoder */
|
||||||
|
SKP_Silk_decoder_control sDecCtrl;
|
||||||
|
SKP_int TempQ[ MAX_FRAME_LENGTH ];
|
||||||
|
|
||||||
|
if( lost_offset < 1 || lost_offset > MAX_LBRR_DELAY ) {
|
||||||
|
/* No useful FEC in this packet */
|
||||||
|
*nLBRRBytes = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sDec.nFramesDecoded = 0;
|
||||||
|
sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */
|
||||||
|
sDec.lossCnt = 0; /* Avoid running bw expansion of the LPC parameters when searching for LBRR data */
|
||||||
|
SKP_memset( sDec.prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
|
||||||
|
SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn );
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 );
|
||||||
|
|
||||||
|
if( sDec.sRC.error ) {
|
||||||
|
/* Corrupt stream */
|
||||||
|
*nLBRRBytes = 0;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if( ( sDec.FrameTermination - 1 ) & lost_offset && sDec.FrameTermination > 0 && sDec.nBytesLeft >= 0 ) {
|
||||||
|
/* The wanted FEC is present in the packet */
|
||||||
|
*nLBRRBytes = sDec.nBytesLeft;
|
||||||
|
SKP_memcpy( LBRRData, &inData[ nBytesIn - sDec.nBytesLeft ], sDec.nBytesLeft * sizeof( SKP_uint8 ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) {
|
||||||
|
sDec.nFramesDecoded++;
|
||||||
|
} else {
|
||||||
|
LBRRData = NULL;
|
||||||
|
*nLBRRBytes = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Getting type of content for a packet */
|
||||||
|
void SKP_Silk_SDK_get_TOC(
|
||||||
|
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||||
|
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||||
|
SKP_Silk_TOC_struct *Silk_TOC /* O: Type of content */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_decoder_state sDec; // Local Decoder state to avoid interfering with running decoder */
|
||||||
|
SKP_Silk_decoder_control sDecCtrl;
|
||||||
|
SKP_int TempQ[ MAX_FRAME_LENGTH ];
|
||||||
|
|
||||||
|
sDec.nFramesDecoded = 0;
|
||||||
|
sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */
|
||||||
|
SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn );
|
||||||
|
|
||||||
|
Silk_TOC->corrupt = 0;
|
||||||
|
while( 1 ) {
|
||||||
|
SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 );
|
||||||
|
|
||||||
|
Silk_TOC->vadFlags[ sDec.nFramesDecoded ] = sDec.vadFlag;
|
||||||
|
Silk_TOC->sigtypeFlags[ sDec.nFramesDecoded ] = sDecCtrl.sigtype;
|
||||||
|
|
||||||
|
if( sDec.sRC.error ) {
|
||||||
|
/* Corrupt stream */
|
||||||
|
Silk_TOC->corrupt = 1;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) {
|
||||||
|
sDec.nFramesDecoded++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( Silk_TOC->corrupt || sDec.FrameTermination == SKP_SILK_MORE_FRAMES ||
|
||||||
|
sDec.nFramesInPacket > SILK_MAX_FRAMES_PER_PACKET ) {
|
||||||
|
/* Corrupt packet */
|
||||||
|
SKP_memset( Silk_TOC, 0, sizeof( SKP_Silk_TOC_struct ) );
|
||||||
|
Silk_TOC->corrupt = 1;
|
||||||
|
} else {
|
||||||
|
Silk_TOC->framesInPacket = sDec.nFramesDecoded + 1;
|
||||||
|
Silk_TOC->fs_kHz = sDec.fs_kHz;
|
||||||
|
if( sDec.FrameTermination == SKP_SILK_LAST_FRAME ) {
|
||||||
|
Silk_TOC->inbandLBRR = sDec.FrameTermination;
|
||||||
|
} else {
|
||||||
|
Silk_TOC->inbandLBRR = sDec.FrameTermination - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Get the version number */
|
||||||
|
/**************************/
|
||||||
|
/* Return a pointer to string specifying the version */
|
||||||
|
const char *SKP_Silk_SDK_get_version()
|
||||||
|
{
|
||||||
|
static const char version[] = "1.0.9.6";
|
||||||
|
return version;
|
||||||
|
}
|
314
app/src/main/cpp/src/SKP_Silk_decode_core.c
Normal file
314
app/src/main/cpp/src/SKP_Silk_decode_core.c
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
|
||||||
|
void SKP_Silk_decode_short_term_prediction(
|
||||||
|
SKP_int32 *vec_Q10,
|
||||||
|
SKP_int32 *pres_Q10,
|
||||||
|
SKP_int32 *sLPC_Q14,
|
||||||
|
SKP_int16 *A_Q12_tmp,
|
||||||
|
SKP_int LPC_order,
|
||||||
|
SKP_int subfr_length
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Core decoder. Performs inverse NSQ operation LTP + LPC */
|
||||||
|
/**********************************************************/
|
||||||
|
void SKP_Silk_decode_core(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
|
||||||
|
SKP_int16 xq[], /* O Decoded speech */
|
||||||
|
const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, sigtype;
|
||||||
|
SKP_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int16 sLTP[ MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int32 LTP_pred_Q14, Gain_Q16, inv_gain_Q16, inv_gain_Q32, gain_adj_Q16, rand_seed, offset_Q10, dither;
|
||||||
|
SKP_int32 *pred_lag_ptr, *pexc_Q10, *pres_Q10;
|
||||||
|
SKP_int32 vec_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
|
||||||
|
SKP_int32 FiltState[ MAX_LPC_ORDER ];
|
||||||
|
|
||||||
|
SKP_assert( psDec->prev_inv_gain_Q16 != 0 );
|
||||||
|
|
||||||
|
offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psDecCtrl->sigtype ][ psDecCtrl->QuantOffsetType ];
|
||||||
|
|
||||||
|
if( psDecCtrl->NLSFInterpCoef_Q2 < ( 1 << 2 ) ) {
|
||||||
|
NLSF_interpolation_flag = 1;
|
||||||
|
} else {
|
||||||
|
NLSF_interpolation_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Decode excitation */
|
||||||
|
rand_seed = psDecCtrl->Seed;
|
||||||
|
for( i = 0; i < psDec->frame_length; i++ ) {
|
||||||
|
rand_seed = SKP_RAND( rand_seed );
|
||||||
|
/* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
|
||||||
|
dither = SKP_RSHIFT( rand_seed, 31 );
|
||||||
|
|
||||||
|
psDec->exc_Q10[ i ] = SKP_LSHIFT( ( SKP_int32 )q[ i ], 10 ) + offset_Q10;
|
||||||
|
psDec->exc_Q10[ i ] = ( psDec->exc_Q10[ i ] ^ dither ) - dither;
|
||||||
|
|
||||||
|
rand_seed += q[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pexc_Q10 = psDec->exc_Q10;
|
||||||
|
pres_Q10 = psDec->res_Q10;
|
||||||
|
pxq = &psDec->outBuf[ psDec->frame_length ];
|
||||||
|
sLTP_buf_idx = psDec->frame_length;
|
||||||
|
/* Loop over subframes */
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];
|
||||||
|
|
||||||
|
/* Preload LPC coeficients to array on stack. Gives small performance gain */
|
||||||
|
SKP_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
|
||||||
|
B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ];
|
||||||
|
Gain_Q16 = psDecCtrl->Gains_Q16[ k ];
|
||||||
|
sigtype = psDecCtrl->sigtype;
|
||||||
|
|
||||||
|
inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gain_Q16, 1 ), 32 );
|
||||||
|
inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
|
||||||
|
|
||||||
|
/* Calculate Gain adjustment factor */
|
||||||
|
gain_adj_Q16 = ( SKP_int32 )1 << 16;
|
||||||
|
if( inv_gain_Q16 != psDec->prev_inv_gain_Q16 ) {
|
||||||
|
gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, psDec->prev_inv_gain_Q16, 16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */
|
||||||
|
if( psDec->lossCnt && psDec->prev_sigtype == SIG_TYPE_VOICED &&
|
||||||
|
psDecCtrl->sigtype == SIG_TYPE_UNVOICED && k < ( NB_SUBFR >> 1 ) ) {
|
||||||
|
|
||||||
|
SKP_memset( B_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );
|
||||||
|
B_Q14[ LTP_ORDER/2 ] = ( SKP_int16 )1 << 12; /* 0.25 */
|
||||||
|
|
||||||
|
sigtype = SIG_TYPE_VOICED;
|
||||||
|
psDecCtrl->pitchL[ k ] = psDec->lagPrev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Voiced */
|
||||||
|
|
||||||
|
lag = psDecCtrl->pitchL[ k ];
|
||||||
|
/* Re-whitening */
|
||||||
|
if( ( k & ( 3 - SKP_LSHIFT( NLSF_interpolation_flag, 1 ) ) ) == 0 ) {
|
||||||
|
/* Rewhiten with new A coefs */
|
||||||
|
start_idx = psDec->frame_length - lag - psDec->LPC_order - LTP_ORDER / 2;
|
||||||
|
SKP_assert( start_idx >= 0 );
|
||||||
|
SKP_assert( start_idx <= psDec->frame_length - psDec->LPC_order );
|
||||||
|
|
||||||
|
SKP_memset( FiltState, 0, psDec->LPC_order * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind and Coverity will complain otherwise */
|
||||||
|
SKP_Silk_MA_Prediction( &psDec->outBuf[ start_idx + k * ( psDec->frame_length >> 2 ) ],
|
||||||
|
A_Q12, FiltState, sLTP + start_idx, psDec->frame_length - start_idx, psDec->LPC_order );
|
||||||
|
|
||||||
|
/* After rewhitening the LTP state is unscaled */
|
||||||
|
inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
|
||||||
|
if( k == 0 ) {
|
||||||
|
/* Do LTP downscaling */
|
||||||
|
inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, psDecCtrl->LTP_scale_Q14 ), 2 );
|
||||||
|
}
|
||||||
|
for( i = 0; i < (lag + LTP_ORDER/2); i++ ) {
|
||||||
|
psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWB( inv_gain_Q32, sLTP[ psDec->frame_length - i - 1 ] );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Update LTP state when Gain changes */
|
||||||
|
if( gain_adj_Q16 != ( SKP_int32 )1 << 16 ) {
|
||||||
|
for( i = 0; i < ( lag + LTP_ORDER / 2 ); i++ ) {
|
||||||
|
psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWW( gain_adj_Q16, psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale short term state */
|
||||||
|
for( i = 0; i < MAX_LPC_ORDER; i++ ) {
|
||||||
|
psDec->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDec->sLPC_Q14[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save inv_gain */
|
||||||
|
SKP_assert( inv_gain_Q16 != 0 );
|
||||||
|
psDec->prev_inv_gain_Q16 = inv_gain_Q16;
|
||||||
|
|
||||||
|
/* Long-term prediction */
|
||||||
|
if( sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/* Setup pointer */
|
||||||
|
pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
|
/* Unrolled loop */
|
||||||
|
LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
|
||||||
|
LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
|
||||||
|
pred_lag_ptr++;
|
||||||
|
|
||||||
|
/* Generate LPC residual */
|
||||||
|
pres_Q10[ i ] = SKP_ADD32( pexc_Q10[ i ], SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( pres_Q10[ i ], 6 );
|
||||||
|
sLTP_buf_idx++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_memcpy( pres_Q10, pexc_Q10, psDec->subfr_length * sizeof( SKP_int32 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_Silk_decode_short_term_prediction(vec_Q10, pres_Q10, psDec->sLPC_Q14,A_Q12_tmp,psDec->LPC_order,psDec->subfr_length);
|
||||||
|
|
||||||
|
/* Scale with Gain */
|
||||||
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
|
pxq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( vec_Q10[ i ], Gain_Q16 ), 10 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update LPC filter state */
|
||||||
|
SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
|
||||||
|
pexc_Q10 += psDec->subfr_length;
|
||||||
|
pres_Q10 += psDec->subfr_length;
|
||||||
|
pxq += psDec->subfr_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy to output */
|
||||||
|
SKP_memcpy( xq, &psDec->outBuf[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM<5
|
||||||
|
void SKP_Silk_decode_short_term_prediction(
|
||||||
|
SKP_int32 *vec_Q10,
|
||||||
|
SKP_int32 *pres_Q10,
|
||||||
|
SKP_int32 *sLPC_Q14,
|
||||||
|
SKP_int16 *A_Q12_tmp,
|
||||||
|
SKP_int LPC_order,
|
||||||
|
SKP_int subfr_length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
SKP_int32 LPC_pred_Q10;
|
||||||
|
#if !defined(_SYSTEM_IS_BIG_ENDIAN)
|
||||||
|
SKP_int32 Atmp;
|
||||||
|
/* Short term prediction */
|
||||||
|
/* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
|
||||||
|
/* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
|
||||||
|
/* loaded in reverse order and the code will give the wrong result. In that case swapping */
|
||||||
|
/* the SMLAWB and SMLAWT instructions should solve the problem. */
|
||||||
|
if( LPC_order == 16 ) {
|
||||||
|
for( i = 0; i < subfr_length; i++ ) {
|
||||||
|
/* unrolled */
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] ); /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 10 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 12 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 14 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], Atmp );
|
||||||
|
|
||||||
|
/* Add prediction to LPC residual */
|
||||||
|
vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_assert( LPC_order == 10 );
|
||||||
|
for( i = 0; i < subfr_length; i++ ) {
|
||||||
|
/* unrolled */
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] ); /* read two coefficients at once */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp );
|
||||||
|
Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
|
||||||
|
|
||||||
|
/* Add prediction to LPC residual */
|
||||||
|
vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SKP_int j;
|
||||||
|
for( i = 0; i < subfr_length; i++ ) {
|
||||||
|
/* Partially unrolled */
|
||||||
|
LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] );
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
|
||||||
|
|
||||||
|
for( j = 10; j < LPC_order; j ++ ) {
|
||||||
|
LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add prediction to LPC residual */
|
||||||
|
vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
248
app/src/main/cpp/src/SKP_Silk_decode_core_arm.S
Normal file
248
app/src/main/cpp/src/SKP_Silk_decode_core_arm.S
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_AsmPreproc.h"
|
||||||
|
|
||||||
|
#define MAX_LPC_ORDER 16
|
||||||
|
#define MAX_LPC_ORDER_INT32_OFFSET 64
|
||||||
|
|
||||||
|
|
||||||
|
#if EMBEDDED_ARM >= 5
|
||||||
|
|
||||||
|
VARDEF ptr_vec_Q10, r0
|
||||||
|
VARDEF ptr_pres_Q10, r1
|
||||||
|
VARDEF ptr_sLPC_Q14, r2
|
||||||
|
VARDEF ptr_A_Q12_tmp, r3
|
||||||
|
VARDEF ptr_LPC_Q14, r4
|
||||||
|
VARDEF val1_LPC_Q14, r5
|
||||||
|
VARDEF val_pres_Q10, r5
|
||||||
|
VARDEF val2_LPC_Q14, r6
|
||||||
|
VARDEF val_vec_Q10, r6
|
||||||
|
VARDEF val3_LPC_Q14, r8
|
||||||
|
VARDEF val4_LPC_Q14, sb
|
||||||
|
VARDEF val1_Atmp, sl
|
||||||
|
VARDEF val_LPC_Q14, sl
|
||||||
|
VARDEF val2_Atmp, ip
|
||||||
|
|
||||||
|
VARDEF val_subfr_length, _r7
|
||||||
|
VARDEF val_LPC_order, lr
|
||||||
|
VARDEF val_LPC_pred_Q10, lr
|
||||||
|
|
||||||
|
.globl SYM(SKP_Silk_decode_short_term_prediction)
|
||||||
|
SYM(SKP_Silk_decode_short_term_prediction):
|
||||||
|
stmdb sp!, {r4-r10, fp, ip, lr}
|
||||||
|
add fp, sp, #36
|
||||||
|
.set ptr_LPC_order, 40
|
||||||
|
.set ptr_subfr_length, 44
|
||||||
|
|
||||||
|
|
||||||
|
ldr val_LPC_order, [sp, #ptr_LPC_order]
|
||||||
|
ldr val_subfr_length, [sp, #ptr_subfr_length]
|
||||||
|
ands val1_Atmp, ptr_A_Q12_tmp, #3
|
||||||
|
add ptr_sLPC_Q14, ptr_sLPC_Q14, #MAX_LPC_ORDER_INT32_OFFSET
|
||||||
|
bne LR(2, f)
|
||||||
|
cmp val_LPC_order, #16
|
||||||
|
bne LR(1, f)
|
||||||
|
/*LPC_order == 16*/
|
||||||
|
L(0)
|
||||||
|
mov ptr_LPC_Q14, ptr_sLPC_Q14
|
||||||
|
ldmia ptr_A_Q12_tmp!, {val1_Atmp, val2_Atmp}
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
smulwb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp
|
||||||
|
smlawt val_LPC_pred_Q10, val1_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
|
||||||
|
smlawb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val1_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
|
||||||
|
smlawb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val1_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #-28
|
||||||
|
|
||||||
|
smlawb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val1_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val_pres_Q10, [ptr_pres_Q10], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
subs val_subfr_length, val_subfr_length, #1
|
||||||
|
add val_vec_Q10, val_LPC_pred_Q10, val_pres_Q10
|
||||||
|
mov val_LPC_Q14, val_vec_Q10, lsl #4
|
||||||
|
str val_vec_Q10, [ptr_vec_Q10], #4
|
||||||
|
str val_LPC_Q14, [ptr_sLPC_Q14], #4
|
||||||
|
bgt LR(0, b)
|
||||||
|
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
|
||||||
|
/*LPC_order == 10*/
|
||||||
|
L(1)
|
||||||
|
mov ptr_LPC_Q14, ptr_sLPC_Q14
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
|
||||||
|
smulwb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
|
||||||
|
smlawb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val1_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #-16
|
||||||
|
|
||||||
|
smlawb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val1_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val_pres_Q10, [ptr_pres_Q10], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawt val_LPC_pred_Q10, val3_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
subs val_subfr_length, val_subfr_length, #1
|
||||||
|
add val_vec_Q10, val_LPC_pred_Q10, val_pres_Q10
|
||||||
|
mov val_LPC_Q14, val_vec_Q10, lsl #4
|
||||||
|
str val_vec_Q10, [ptr_vec_Q10], #4
|
||||||
|
str val_LPC_Q14, [ptr_sLPC_Q14], #4
|
||||||
|
bgt LR(1, b)
|
||||||
|
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
|
||||||
|
L(2)
|
||||||
|
cmp val_LPC_order, #16
|
||||||
|
bne LR(4, f)
|
||||||
|
/*LPC_order == 16*/
|
||||||
|
L(3)
|
||||||
|
mov ptr_LPC_Q14, ptr_sLPC_Q14
|
||||||
|
ldrh val1_Atmp, [ptr_A_Q12_tmp], #2
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
smulwb val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val1_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val1_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val1_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldrh val1_Atmp, [ptr_A_Q12_tmp], #-30
|
||||||
|
smlawb val_LPC_pred_Q10, val1_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val_pres_Q10, [ptr_pres_Q10], #4
|
||||||
|
smlawt val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
subs val_subfr_length, val_subfr_length, #1
|
||||||
|
add val_vec_Q10, val_LPC_pred_Q10, val_pres_Q10
|
||||||
|
mov val_LPC_Q14, val_vec_Q10, lsl #4
|
||||||
|
str val_vec_Q10, [ptr_vec_Q10], #4
|
||||||
|
str val_LPC_Q14, [ptr_sLPC_Q14], #4
|
||||||
|
bgt LR(3, b)
|
||||||
|
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
|
||||||
|
/*LPC_order == 10*/
|
||||||
|
L(4)
|
||||||
|
mov ptr_LPC_Q14, ptr_sLPC_Q14
|
||||||
|
ldrh val2_Atmp, [ptr_A_Q12_tmp], #2
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
|
||||||
|
smulwb val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val1_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val1_LPC_Q14, val2_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val2_Atmp, [ptr_A_Q12_tmp], #4
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldmdb ptr_LPC_Q14!, {val3_LPC_Q14, val4_LPC_Q14}
|
||||||
|
|
||||||
|
smlawt val_LPC_pred_Q10, val2_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val1_Atmp, [ptr_A_Q12_tmp], #-18
|
||||||
|
smlawb val_LPC_pred_Q10, val1_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
ldr val_pres_Q10, [ptr_pres_Q10], #4
|
||||||
|
smlawt val_LPC_pred_Q10, val4_LPC_Q14, val2_Atmp, val_LPC_pred_Q10
|
||||||
|
smlawb val_LPC_pred_Q10, val3_LPC_Q14, val1_Atmp, val_LPC_pred_Q10
|
||||||
|
subs val_subfr_length, val_subfr_length, #1
|
||||||
|
add val_vec_Q10, val_LPC_pred_Q10, val_pres_Q10
|
||||||
|
mov val_LPC_Q14, val_vec_Q10, lsl #4
|
||||||
|
str val_vec_Q10, [ptr_vec_Q10], #4
|
||||||
|
str val_LPC_Q14, [ptr_sLPC_Q14], #4
|
||||||
|
bgt LR(4, b)
|
||||||
|
|
||||||
|
ldmia sp!, {r4-r10, fp, ip, pc}
|
||||||
|
END
|
||||||
|
#endif
|
155
app/src/main/cpp/src/SKP_Silk_decode_frame.c
Normal file
155
app/src/main/cpp/src/SKP_Silk_decode_frame.c
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
#include "SKP_Silk_PLC.h"
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Decode frame */
|
||||||
|
/****************/
|
||||||
|
SKP_int SKP_Silk_decode_frame(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */
|
||||||
|
SKP_int16 pOut[], /* O Pointer to output speech frame */
|
||||||
|
SKP_int16 *pN, /* O Pointer to size of output frame */
|
||||||
|
const SKP_uint8 pCode[], /* I Pointer to payload */
|
||||||
|
const SKP_int nBytes, /* I Payload length */
|
||||||
|
SKP_int action, /* I Action from Jitter Buffer */
|
||||||
|
SKP_int *decBytes /* O Used bytes to decode this frame */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_decoder_control sDecCtrl;
|
||||||
|
SKP_int L, fs_Khz_old, ret = 0;
|
||||||
|
SKP_int Pulses[ MAX_FRAME_LENGTH ];
|
||||||
|
|
||||||
|
|
||||||
|
L = psDec->frame_length;
|
||||||
|
sDecCtrl.LTP_scale_Q14 = 0;
|
||||||
|
|
||||||
|
/* Safety checks */
|
||||||
|
SKP_assert( L > 0 && L <= MAX_FRAME_LENGTH );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Decode Frame if packet is not lost */
|
||||||
|
/********************************************/
|
||||||
|
*decBytes = 0;
|
||||||
|
if( action == 0 ) {
|
||||||
|
/********************************************/
|
||||||
|
/* Initialize arithmetic coder */
|
||||||
|
/********************************************/
|
||||||
|
fs_Khz_old = psDec->fs_kHz;
|
||||||
|
if( psDec->nFramesDecoded == 0 ) {
|
||||||
|
/* Initialize range decoder state */
|
||||||
|
SKP_Silk_range_dec_init( &psDec->sRC, pCode, nBytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Decode parameters and pulse signal */
|
||||||
|
/********************************************/
|
||||||
|
SKP_Silk_decode_parameters( psDec, &sDecCtrl, Pulses, 1 );
|
||||||
|
|
||||||
|
|
||||||
|
if( psDec->sRC.error ) {
|
||||||
|
psDec->nBytesLeft = 0;
|
||||||
|
|
||||||
|
action = 1; /* PLC operation */
|
||||||
|
/* revert fs if changed in decode_parameters */
|
||||||
|
SKP_Silk_decoder_set_fs( psDec, fs_Khz_old );
|
||||||
|
|
||||||
|
/* Avoid crashing */
|
||||||
|
*decBytes = psDec->sRC.bufferLength;
|
||||||
|
|
||||||
|
if( psDec->sRC.error == RANGE_CODER_DEC_PAYLOAD_TOO_LONG ) {
|
||||||
|
ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
|
||||||
|
} else {
|
||||||
|
ret = SKP_SILK_DEC_PAYLOAD_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*decBytes = psDec->sRC.bufferLength - psDec->nBytesLeft;
|
||||||
|
psDec->nFramesDecoded++;
|
||||||
|
|
||||||
|
/* Update lengths. Sampling frequency could have changed */
|
||||||
|
L = psDec->frame_length;
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/* Run inverse NSQ */
|
||||||
|
/********************************************************/
|
||||||
|
SKP_Silk_decode_core( psDec, &sDecCtrl, pOut, Pulses );
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
/* Update PLC state */
|
||||||
|
/********************************************************/
|
||||||
|
SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
|
||||||
|
|
||||||
|
psDec->lossCnt = 0;
|
||||||
|
psDec->prev_sigtype = sDecCtrl.sigtype;
|
||||||
|
|
||||||
|
/* A frame has been decoded without errors */
|
||||||
|
psDec->first_frame_after_reset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*************************************************************/
|
||||||
|
/* Generate Concealment frame if packet is lost, or corrupt */
|
||||||
|
/*************************************************************/
|
||||||
|
if( action == 1 ) {
|
||||||
|
/* Handle packet loss by extrapolation */
|
||||||
|
SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************/
|
||||||
|
/* Update output buffer. */
|
||||||
|
/*************************/
|
||||||
|
SKP_memcpy( psDec->outBuf, pOut, L * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* Ensure smooth connection of extrapolated and good frames */
|
||||||
|
/****************************************************************/
|
||||||
|
SKP_Silk_PLC_glue_frames( psDec, &sDecCtrl, pOut, L );
|
||||||
|
|
||||||
|
/************************************************/
|
||||||
|
/* Comfort noise generation / estimation */
|
||||||
|
/************************************************/
|
||||||
|
SKP_Silk_CNG( psDec, &sDecCtrl, pOut , L );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* HP filter output */
|
||||||
|
/********************************************/
|
||||||
|
SKP_assert( ( ( psDec->fs_kHz == 12 ) && ( L % 3 ) == 0 ) ||
|
||||||
|
( ( psDec->fs_kHz != 12 ) && ( L % 2 ) == 0 ) );
|
||||||
|
SKP_Silk_biquad( pOut, psDec->HP_B, psDec->HP_A, psDec->HPState, pOut, L );
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* set output frame length */
|
||||||
|
/********************************************/
|
||||||
|
*pN = ( SKP_int16 )L;
|
||||||
|
|
||||||
|
/* Update some decoder state variables */
|
||||||
|
psDec->lagPrev = sDecCtrl.pitchL[ NB_SUBFR - 1 ];
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
244
app/src/main/cpp/src/SKP_Silk_decode_parameters.c
Normal file
244
app/src/main/cpp/src/SKP_Silk_decode_parameters.c
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* Decode parameters from payload */
|
||||||
|
void SKP_Silk_decode_parameters(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O State */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int q[], /* O Excitation signal */
|
||||||
|
const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, Ix, fs_kHz_dec, nBytesUsed;
|
||||||
|
SKP_int Ixs[ NB_SUBFR ];
|
||||||
|
SKP_int GainsIndices[ NB_SUBFR ];
|
||||||
|
SKP_int NLSFIndices[ NLSF_MSVQ_MAX_CB_STAGES ];
|
||||||
|
SKP_int pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ];
|
||||||
|
const SKP_int16 *cbk_ptr_Q14;
|
||||||
|
const SKP_Silk_NLSF_CB_struct *psNLSF_CB = NULL;
|
||||||
|
SKP_Silk_range_coder_state *psRC = &psDec->sRC;
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* Decode sampling rate */
|
||||||
|
/************************/
|
||||||
|
/* only done for first frame of packet */
|
||||||
|
if( psDec->nFramesDecoded == 0 ) {
|
||||||
|
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_SamplingRates_CDF, SKP_Silk_SamplingRates_offset );
|
||||||
|
|
||||||
|
/* check that sampling rate is supported */
|
||||||
|
if( Ix < 0 || Ix > 3 ) {
|
||||||
|
psRC->error = RANGE_CODER_ILLEGAL_SAMPLING_RATE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fs_kHz_dec = SKP_Silk_SamplingRates_table[ Ix ];
|
||||||
|
SKP_Silk_decoder_set_fs( psDec, fs_kHz_dec );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
/* Decode signal type and quantizer offset */
|
||||||
|
/*******************************************/
|
||||||
|
if( psDec->nFramesDecoded == 0 ) {
|
||||||
|
/* first frame in packet: independent coding */
|
||||||
|
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_CDF, SKP_Silk_type_offset_CDF_offset );
|
||||||
|
} else {
|
||||||
|
/* condidtional coding */
|
||||||
|
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_joint_CDF[ psDec->typeOffsetPrev ],
|
||||||
|
SKP_Silk_type_offset_CDF_offset );
|
||||||
|
}
|
||||||
|
psDecCtrl->sigtype = SKP_RSHIFT( Ix, 1 );
|
||||||
|
psDecCtrl->QuantOffsetType = Ix & 1;
|
||||||
|
psDec->typeOffsetPrev = Ix;
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Decode gains */
|
||||||
|
/****************/
|
||||||
|
/* first subframe */
|
||||||
|
if( psDec->nFramesDecoded == 0 ) {
|
||||||
|
/* first frame in packet: independent coding */
|
||||||
|
SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_gain_CDF[ psDecCtrl->sigtype ], SKP_Silk_gain_CDF_offset );
|
||||||
|
} else {
|
||||||
|
/* condidtional coding */
|
||||||
|
SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remaining subframes */
|
||||||
|
for( i = 1; i < NB_SUBFR; i++ ) {
|
||||||
|
SKP_Silk_range_decoder( &GainsIndices[ i ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dequant Gains */
|
||||||
|
SKP_Silk_gains_dequant( psDecCtrl->Gains_Q16, GainsIndices, &psDec->LastGainIndex, psDec->nFramesDecoded );
|
||||||
|
/****************/
|
||||||
|
/* Decode NLSFs */
|
||||||
|
/****************/
|
||||||
|
/* Set pointer to NLSF VQ CB for the current signal type */
|
||||||
|
psNLSF_CB = psDec->psNLSF_CB[ psDecCtrl->sigtype ];
|
||||||
|
|
||||||
|
/* Range decode NLSF path */
|
||||||
|
SKP_Silk_range_decoder_multi( NLSFIndices, psRC, psNLSF_CB->StartPtr, psNLSF_CB->MiddleIx, psNLSF_CB->nStages );
|
||||||
|
|
||||||
|
/* From the NLSF path, decode an NLSF vector */
|
||||||
|
SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, psDec->LPC_order );
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/* Decode NLSF interpolation factor */
|
||||||
|
/************************************/
|
||||||
|
SKP_Silk_range_decoder( &psDecCtrl->NLSFInterpCoef_Q2, psRC, SKP_Silk_NLSF_interpolation_factor_CDF,
|
||||||
|
SKP_Silk_NLSF_interpolation_factor_offset );
|
||||||
|
|
||||||
|
/* If just reset, e.g., because internal Fs changed, do not allow interpolation */
|
||||||
|
/* improves the case of packet loss in the first frame after a switch */
|
||||||
|
if( psDec->first_frame_after_reset == 1 ) {
|
||||||
|
psDecCtrl->NLSFInterpCoef_Q2 = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fullDecoding ) {
|
||||||
|
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||||
|
SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
|
||||||
|
|
||||||
|
if( psDecCtrl->NLSFInterpCoef_Q2 < 4 ) {
|
||||||
|
/* Calculation of the interpolated NLSF0 vector from the interpolation factor, */
|
||||||
|
/* the previous NLSF1, and the current NLSF1 */
|
||||||
|
for( i = 0; i < psDec->LPC_order; i++ ) {
|
||||||
|
pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + SKP_RSHIFT( SKP_MUL( psDecCtrl->NLSFInterpCoef_Q2,
|
||||||
|
( pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ) ), 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||||
|
SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
|
||||||
|
} else {
|
||||||
|
/* Copy LPC coefficients for first half from second half */
|
||||||
|
SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ],
|
||||||
|
psDec->LPC_order * sizeof( SKP_int16 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( SKP_int ) );
|
||||||
|
|
||||||
|
/* After a packet loss do BWE of LPC coefs */
|
||||||
|
if( psDec->lossCnt ) {
|
||||||
|
SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
|
||||||
|
SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/*********************/
|
||||||
|
/* Decode pitch lags */
|
||||||
|
/*********************/
|
||||||
|
/* Get lag index */
|
||||||
|
if( psDec->fs_kHz == 8 ) {
|
||||||
|
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_NB_CDF, SKP_Silk_pitch_lag_NB_CDF_offset );
|
||||||
|
} else if( psDec->fs_kHz == 12 ) {
|
||||||
|
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_MB_CDF, SKP_Silk_pitch_lag_MB_CDF_offset );
|
||||||
|
} else if( psDec->fs_kHz == 16 ) {
|
||||||
|
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_WB_CDF, SKP_Silk_pitch_lag_WB_CDF_offset );
|
||||||
|
} else {
|
||||||
|
SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_SWB_CDF, SKP_Silk_pitch_lag_SWB_CDF_offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get countour index */
|
||||||
|
if( psDec->fs_kHz == 8 ) {
|
||||||
|
/* Less codevectors used in 8 khz mode */
|
||||||
|
SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_NB_CDF, SKP_Silk_pitch_contour_NB_CDF_offset );
|
||||||
|
} else {
|
||||||
|
/* Joint for 12, 16, and 24 khz */
|
||||||
|
SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_CDF, SKP_Silk_pitch_contour_CDF_offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode pitch values */
|
||||||
|
SKP_Silk_decode_pitch( Ixs[ 0 ], Ixs[ 1 ], psDecCtrl->pitchL, psDec->fs_kHz );
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
/* Decode LTP gains */
|
||||||
|
/********************/
|
||||||
|
/* Decode PERIndex value */
|
||||||
|
SKP_Silk_range_decoder( &psDecCtrl->PERIndex, psRC, SKP_Silk_LTP_per_index_CDF,
|
||||||
|
SKP_Silk_LTP_per_index_CDF_offset );
|
||||||
|
|
||||||
|
/* Decode Codebook Index */
|
||||||
|
cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ psDecCtrl->PERIndex ]; /* set pointer to start of codebook */
|
||||||
|
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTP_gain_CDF_ptrs[ psDecCtrl->PERIndex ],
|
||||||
|
SKP_Silk_LTP_gain_CDF_offsets[ psDecCtrl->PERIndex ] );
|
||||||
|
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = cbk_ptr_Q14[ Ix * LTP_ORDER + i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************/
|
||||||
|
/* Decode LTP scaling */
|
||||||
|
/**********************/
|
||||||
|
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTPscale_CDF, SKP_Silk_LTPscale_offset );
|
||||||
|
psDecCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ Ix ];
|
||||||
|
} else {
|
||||||
|
SKP_assert( psDecCtrl->sigtype == SIG_TYPE_UNVOICED );
|
||||||
|
SKP_memset( psDecCtrl->pitchL, 0, NB_SUBFR * sizeof( SKP_int ) );
|
||||||
|
SKP_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * NB_SUBFR * sizeof( SKP_int16 ) );
|
||||||
|
psDecCtrl->PERIndex = 0;
|
||||||
|
psDecCtrl->LTP_scale_Q14 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************/
|
||||||
|
/* Decode seed */
|
||||||
|
/***************/
|
||||||
|
SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_Seed_CDF, SKP_Silk_Seed_offset );
|
||||||
|
psDecCtrl->Seed = ( SKP_int32 )Ix;
|
||||||
|
/*********************************************/
|
||||||
|
/* Decode quantization indices of excitation */
|
||||||
|
/*********************************************/
|
||||||
|
SKP_Silk_decode_pulses( psRC, psDecCtrl, q, psDec->frame_length );
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Decode VAD flag */
|
||||||
|
/*********************************************/
|
||||||
|
SKP_Silk_range_decoder( &psDec->vadFlag, psRC, SKP_Silk_vadflag_CDF, SKP_Silk_vadflag_offset );
|
||||||
|
|
||||||
|
/**************************************/
|
||||||
|
/* Decode Frame termination indicator */
|
||||||
|
/**************************************/
|
||||||
|
SKP_Silk_range_decoder( &psDec->FrameTermination, psRC, SKP_Silk_FrameTermination_CDF, SKP_Silk_FrameTermination_offset );
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* get number of bytes used so far */
|
||||||
|
/****************************************/
|
||||||
|
SKP_Silk_range_coder_get_length( psRC, &nBytesUsed );
|
||||||
|
psDec->nBytesLeft = psRC->bufferLength - nBytesUsed;
|
||||||
|
if( psDec->nBytesLeft < 0 ) {
|
||||||
|
psRC->error = RANGE_CODER_READ_BEYOND_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* check remaining bits in last byte */
|
||||||
|
/****************************************/
|
||||||
|
if( psDec->nBytesLeft == 0 ) {
|
||||||
|
SKP_Silk_range_coder_check_after_decoding( psRC );
|
||||||
|
}
|
||||||
|
}
|
57
app/src/main/cpp/src/SKP_Silk_decode_pitch.c
Normal file
57
app/src/main/cpp/src/SKP_Silk_decode_pitch.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Pitch analyser function
|
||||||
|
********************************************************** */
|
||||||
|
#include "SKP_Silk_SigProc_FIX.h"
|
||||||
|
#include "SKP_Silk_common_pitch_est_defines.h"
|
||||||
|
|
||||||
|
void SKP_Silk_decode_pitch(
|
||||||
|
SKP_int lagIndex, /* I */
|
||||||
|
SKP_int contourIndex, /* O */
|
||||||
|
SKP_int pitch_lags[], /* O 4 pitch values */
|
||||||
|
SKP_int Fs_kHz /* I sampling frequency (kHz) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int lag, i, min_lag;
|
||||||
|
|
||||||
|
min_lag = SKP_SMULBB( PITCH_EST_MIN_LAG_MS, Fs_kHz );
|
||||||
|
|
||||||
|
/* Only for 24 / 16 kHz version for now */
|
||||||
|
lag = min_lag + lagIndex;
|
||||||
|
if( Fs_kHz == 8 ) {
|
||||||
|
/* Only a small codebook for 8 khz */
|
||||||
|
for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
|
||||||
|
pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage2[ i ][ contourIndex ];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
|
||||||
|
pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage3[ i ][ contourIndex ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
app/src/main/cpp/src/SKP_Silk_decode_pulses.c
Normal file
105
app/src/main/cpp/src/SKP_Silk_decode_pulses.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Decode quantization indices of excitation */
|
||||||
|
/*********************************************/
|
||||||
|
void SKP_Silk_decode_pulses(
|
||||||
|
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
|
||||||
|
SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||||
|
SKP_int q[], /* O Excitation signal */
|
||||||
|
const SKP_int frame_length /* I Frame length (preliminary) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, j, k, iter, abs_q, nLS, bit;
|
||||||
|
SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ];
|
||||||
|
SKP_int *pulses_ptr;
|
||||||
|
const SKP_uint16 *cdf_ptr;
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
/* Decode rate level */
|
||||||
|
/*********************/
|
||||||
|
SKP_Silk_range_decoder( &psDecCtrl->RateLevelIndex, psRC,
|
||||||
|
SKP_Silk_rate_levels_CDF[ psDecCtrl->sigtype ], SKP_Silk_rate_levels_CDF_offset );
|
||||||
|
|
||||||
|
/* Calculate number of shell blocks */
|
||||||
|
iter = frame_length / SHELL_CODEC_FRAME_LENGTH;
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
/* Sum-Weighted-Pulses Decoding */
|
||||||
|
/***************************************************/
|
||||||
|
cdf_ptr = SKP_Silk_pulses_per_block_CDF[ psDecCtrl->RateLevelIndex ];
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
nLshifts[ i ] = 0;
|
||||||
|
SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, cdf_ptr, SKP_Silk_pulses_per_block_CDF_offset );
|
||||||
|
|
||||||
|
/* LSB indication */
|
||||||
|
while( sum_pulses[ i ] == ( MAX_PULSES + 1 ) ) {
|
||||||
|
nLshifts[ i ]++;
|
||||||
|
SKP_Silk_range_decoder( &sum_pulses[ i ], psRC,
|
||||||
|
SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ], SKP_Silk_pulses_per_block_CDF_offset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
/* Shell decoding */
|
||||||
|
/***************************************************/
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
if( sum_pulses[ i ] > 0 ) {
|
||||||
|
SKP_Silk_shell_decoder( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRC, sum_pulses[ i ] );
|
||||||
|
} else {
|
||||||
|
SKP_memset( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( SKP_int ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
/* LSB Decoding */
|
||||||
|
/***************************************************/
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
if( nLshifts[ i ] > 0 ) {
|
||||||
|
nLS = nLshifts[ i ];
|
||||||
|
pulses_ptr = &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ];
|
||||||
|
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
|
||||||
|
abs_q = pulses_ptr[ k ];
|
||||||
|
for( j = 0; j < nLS; j++ ) {
|
||||||
|
abs_q = SKP_LSHIFT( abs_q, 1 );
|
||||||
|
SKP_Silk_range_decoder( &bit, psRC, SKP_Silk_lsb_CDF, 1 );
|
||||||
|
abs_q += bit;
|
||||||
|
}
|
||||||
|
pulses_ptr[ k ] = abs_q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Decode and add signs to pulse signal */
|
||||||
|
/****************************************/
|
||||||
|
SKP_Silk_decode_signs( psRC, q, frame_length, psDecCtrl->sigtype,
|
||||||
|
psDecCtrl->QuantOffsetType, psDecCtrl->RateLevelIndex);
|
||||||
|
}
|
80
app/src/main/cpp/src/SKP_Silk_decoder_set_fs.c
Normal file
80
app/src/main/cpp/src/SKP_Silk_decoder_set_fs.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/* Set decoder sampling rate */
|
||||||
|
void SKP_Silk_decoder_set_fs(
|
||||||
|
SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */
|
||||||
|
SKP_int fs_kHz /* I Sampling frequency (kHz) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if( psDec->fs_kHz != fs_kHz ) {
|
||||||
|
psDec->fs_kHz = fs_kHz;
|
||||||
|
psDec->frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );
|
||||||
|
psDec->subfr_length = SKP_SMULBB( FRAME_LENGTH_MS / NB_SUBFR, fs_kHz );
|
||||||
|
if( psDec->fs_kHz == 8 ) {
|
||||||
|
psDec->LPC_order = MIN_LPC_ORDER;
|
||||||
|
psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
|
||||||
|
psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
|
||||||
|
} else {
|
||||||
|
psDec->LPC_order = MAX_LPC_ORDER;
|
||||||
|
psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
|
||||||
|
psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
|
||||||
|
}
|
||||||
|
/* Reset part of the decoder state */
|
||||||
|
SKP_memset( psDec->sLPC_Q14, 0, MAX_LPC_ORDER * sizeof( SKP_int32 ) );
|
||||||
|
SKP_memset( psDec->outBuf, 0, MAX_FRAME_LENGTH * sizeof( SKP_int16 ) );
|
||||||
|
SKP_memset( psDec->prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
|
||||||
|
|
||||||
|
psDec->lagPrev = 100;
|
||||||
|
psDec->LastGainIndex = 1;
|
||||||
|
psDec->prev_sigtype = 0;
|
||||||
|
psDec->first_frame_after_reset = 1;
|
||||||
|
|
||||||
|
if( fs_kHz == 24 ) {
|
||||||
|
psDec->HP_A = SKP_Silk_Dec_A_HP_24;
|
||||||
|
psDec->HP_B = SKP_Silk_Dec_B_HP_24;
|
||||||
|
} else if( fs_kHz == 16 ) {
|
||||||
|
psDec->HP_A = SKP_Silk_Dec_A_HP_16;
|
||||||
|
psDec->HP_B = SKP_Silk_Dec_B_HP_16;
|
||||||
|
} else if( fs_kHz == 12 ) {
|
||||||
|
psDec->HP_A = SKP_Silk_Dec_A_HP_12;
|
||||||
|
psDec->HP_B = SKP_Silk_Dec_B_HP_12;
|
||||||
|
} else if( fs_kHz == 8 ) {
|
||||||
|
psDec->HP_A = SKP_Silk_Dec_A_HP_8;
|
||||||
|
psDec->HP_B = SKP_Silk_Dec_B_HP_8;
|
||||||
|
} else {
|
||||||
|
/* unsupported sampling rate */
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that settings are valid */
|
||||||
|
SKP_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
|
||||||
|
}
|
||||||
|
|
306
app/src/main/cpp/src/SKP_Silk_define.h
Normal file
306
app/src/main/cpp/src/SKP_Silk_define.h
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SKP_SILK_DEFINE_H
|
||||||
|
#define SKP_SILK_DEFINE_H
|
||||||
|
|
||||||
|
#include "SKP_Silk_errors.h"
|
||||||
|
#include "SKP_Silk_typedef.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_FRAMES_PER_PACKET 5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Limits on bitrate */
|
||||||
|
#define MIN_TARGET_RATE_BPS 5000
|
||||||
|
#define MAX_TARGET_RATE_BPS 100000
|
||||||
|
|
||||||
|
/* Transition bitrates between modes */
|
||||||
|
#define SWB2WB_BITRATE_BPS 25000
|
||||||
|
#define WB2SWB_BITRATE_BPS 30000
|
||||||
|
#define WB2MB_BITRATE_BPS 14000
|
||||||
|
#define MB2WB_BITRATE_BPS 18000
|
||||||
|
#define MB2NB_BITRATE_BPS 10000
|
||||||
|
#define NB2MB_BITRATE_BPS 14000
|
||||||
|
|
||||||
|
/* Integration/hysteresis threshold for lowering internal sample frequency */
|
||||||
|
/* 30000000 -> 6 sec if bitrate is 5000 bps below limit; 3 sec if bitrate is 10000 bps below limit */
|
||||||
|
#define ACCUM_BITS_DIFF_THRESHOLD 30000000
|
||||||
|
#define TARGET_RATE_TAB_SZ 8
|
||||||
|
|
||||||
|
/* DTX settings */
|
||||||
|
#define NO_SPEECH_FRAMES_BEFORE_DTX 5 /* eq 100 ms */
|
||||||
|
#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
|
||||||
|
|
||||||
|
#define USE_LBRR 1
|
||||||
|
|
||||||
|
/* Amount of concecutive no FEC packets before telling JB */
|
||||||
|
#define NO_LBRR_THRES 10
|
||||||
|
|
||||||
|
/* Maximum delay between real packet and LBRR packet */
|
||||||
|
#define MAX_LBRR_DELAY 2
|
||||||
|
#define LBRR_IDX_MASK 1
|
||||||
|
|
||||||
|
#define INBAND_FEC_MIN_RATE_BPS 18000 /* Dont use inband FEC below this total target rate */
|
||||||
|
#define LBRR_LOSS_THRES 1 /* Start adding LBRR at this loss rate */
|
||||||
|
|
||||||
|
/* LBRR usage defines */
|
||||||
|
#define SKP_SILK_NO_LBRR 0 /* No LBRR information for this packet */
|
||||||
|
#define SKP_SILK_ADD_LBRR_TO_PLUS1 1 /* Add LBRR for this packet to packet n + 1 */
|
||||||
|
#define SKP_SILK_ADD_LBRR_TO_PLUS2 2 /* Add LBRR for this packet to packet n + 2 */
|
||||||
|
|
||||||
|
/* Frame termination indicator defines */
|
||||||
|
#define SKP_SILK_LAST_FRAME 0 /* Last frames in packet */
|
||||||
|
#define SKP_SILK_MORE_FRAMES 1 /* More frames to follow this one */
|
||||||
|
#define SKP_SILK_LBRR_VER1 2 /* LBRR information from packet n - 1 */
|
||||||
|
#define SKP_SILK_LBRR_VER2 3 /* LBRR information from packet n - 2 */
|
||||||
|
#define SKP_SILK_EXT_LAYER 4 /* Extension layers added */
|
||||||
|
|
||||||
|
/* Number of Second order Sections for SWB detection HP filter */
|
||||||
|
#define NB_SOS 3
|
||||||
|
#define HP_8_KHZ_THRES 10 /* average energy per sample, above 8 kHz */
|
||||||
|
#define CONCEC_SWB_SMPLS_THRES 480 * 15 /* 300 ms */
|
||||||
|
#define WB_DETECT_ACTIVE_SPEECH_MS_THRES 15000 /* ms of active speech needed for WB detection */
|
||||||
|
|
||||||
|
/* Low complexity setting */
|
||||||
|
#define LOW_COMPLEXITY_ONLY 0
|
||||||
|
|
||||||
|
/* Activate bandwidth transition filtering for mode switching */
|
||||||
|
#define SWITCH_TRANSITION_FILTERING 1
|
||||||
|
|
||||||
|
/* Decoder Parameters */
|
||||||
|
#define DEC_HP_ORDER 2
|
||||||
|
|
||||||
|
/* Maximum sampling frequency, should be 16 for some embedded platforms */
|
||||||
|
#define MAX_FS_KHZ 24
|
||||||
|
#define MAX_API_FS_KHZ 48
|
||||||
|
|
||||||
|
/* Signal Types used by silk */
|
||||||
|
#define SIG_TYPE_VOICED 0
|
||||||
|
#define SIG_TYPE_UNVOICED 1
|
||||||
|
|
||||||
|
/* VAD Types used by silk */
|
||||||
|
#define NO_VOICE_ACTIVITY 0
|
||||||
|
#define VOICE_ACTIVITY 1
|
||||||
|
|
||||||
|
/* Number of samples per frame */
|
||||||
|
#define FRAME_LENGTH_MS 20
|
||||||
|
#define MAX_FRAME_LENGTH ( FRAME_LENGTH_MS * MAX_FS_KHZ )
|
||||||
|
|
||||||
|
/* Milliseconds of lookahead for pitch analysis */
|
||||||
|
#define LA_PITCH_MS 2
|
||||||
|
#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ )
|
||||||
|
|
||||||
|
/* Length of LPC window used in find pitch */
|
||||||
|
#define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) )
|
||||||
|
#define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ )
|
||||||
|
|
||||||
|
/* Order of LPC used in find pitch */
|
||||||
|
#define MAX_FIND_PITCH_LPC_ORDER 16
|
||||||
|
|
||||||
|
#define PITCH_EST_COMPLEXITY_HC_MODE SKP_Silk_PITCH_EST_MAX_COMPLEX
|
||||||
|
#define PITCH_EST_COMPLEXITY_MC_MODE SKP_Silk_PITCH_EST_MID_COMPLEX
|
||||||
|
#define PITCH_EST_COMPLEXITY_LC_MODE SKP_Silk_PITCH_EST_MIN_COMPLEX
|
||||||
|
|
||||||
|
/* Milliseconds of lookahead for noise shape analysis */
|
||||||
|
#define LA_SHAPE_MS 5
|
||||||
|
#define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ )
|
||||||
|
|
||||||
|
/* Max length of LPC window used in noise shape analysis */
|
||||||
|
#define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ )
|
||||||
|
|
||||||
|
/* Max number of bytes in payload output buffer (may contain multiple frames) */
|
||||||
|
#define MAX_ARITHM_BYTES 1024
|
||||||
|
|
||||||
|
#define RANGE_CODER_WRITE_BEYOND_BUFFER -1
|
||||||
|
#define RANGE_CODER_CDF_OUT_OF_RANGE -2
|
||||||
|
#define RANGE_CODER_NORMALIZATION_FAILED -3
|
||||||
|
#define RANGE_CODER_ZERO_INTERVAL_WIDTH -4
|
||||||
|
#define RANGE_CODER_DECODER_CHECK_FAILED -5
|
||||||
|
#define RANGE_CODER_READ_BEYOND_BUFFER -6
|
||||||
|
#define RANGE_CODER_ILLEGAL_SAMPLING_RATE -7
|
||||||
|
#define RANGE_CODER_DEC_PAYLOAD_TOO_LONG -8
|
||||||
|
|
||||||
|
/* dB level of lowest gain quantization level */
|
||||||
|
#define MIN_QGAIN_DB 6
|
||||||
|
/* dB level of highest gain quantization level */
|
||||||
|
#define MAX_QGAIN_DB 86
|
||||||
|
/* Number of gain quantization levels */
|
||||||
|
#define N_LEVELS_QGAIN 64
|
||||||
|
/* Max increase in gain quantization index */
|
||||||
|
#define MAX_DELTA_GAIN_QUANT 40
|
||||||
|
/* Max decrease in gain quantization index */
|
||||||
|
#define MIN_DELTA_GAIN_QUANT -4
|
||||||
|
|
||||||
|
/* Quantization offsets (multiples of 4) */
|
||||||
|
#define OFFSET_VL_Q10 32
|
||||||
|
#define OFFSET_VH_Q10 100
|
||||||
|
#define OFFSET_UVL_Q10 100
|
||||||
|
#define OFFSET_UVH_Q10 256
|
||||||
|
|
||||||
|
/* Maximum numbers of iterations used to stabilize a LPC vector */
|
||||||
|
#define MAX_LPC_STABILIZE_ITERATIONS 20
|
||||||
|
|
||||||
|
#define MAX_LPC_ORDER 16
|
||||||
|
#define MIN_LPC_ORDER 10
|
||||||
|
|
||||||
|
/* Find Pred Coef defines */
|
||||||
|
#define LTP_ORDER 5
|
||||||
|
|
||||||
|
/* LTP quantization settings */
|
||||||
|
#define NB_LTP_CBKS 3
|
||||||
|
|
||||||
|
/* Number of subframes */
|
||||||
|
#define NB_SUBFR 4
|
||||||
|
|
||||||
|
/* Flag to use harmonic noise shaping */
|
||||||
|
#define USE_HARM_SHAPING 1
|
||||||
|
|
||||||
|
/* Max LPC order of noise shaping filters */
|
||||||
|
#define MAX_SHAPE_LPC_ORDER 16
|
||||||
|
|
||||||
|
#define HARM_SHAPE_FIR_TAPS 3
|
||||||
|
|
||||||
|
/* Maximum number of delayed decision states */
|
||||||
|
#define MAX_DEL_DEC_STATES 4
|
||||||
|
|
||||||
|
#define LTP_BUF_LENGTH 512
|
||||||
|
#define LTP_MASK (LTP_BUF_LENGTH - 1)
|
||||||
|
|
||||||
|
#define DECISION_DELAY 32
|
||||||
|
#define DECISION_DELAY_MASK (DECISION_DELAY - 1)
|
||||||
|
|
||||||
|
/* number of subframes for excitation entropy coding */
|
||||||
|
#define SHELL_CODEC_FRAME_LENGTH 16
|
||||||
|
#define MAX_NB_SHELL_BLOCKS (MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH)
|
||||||
|
|
||||||
|
/* number of rate levels, for entropy coding of excitation */
|
||||||
|
#define N_RATE_LEVELS 10
|
||||||
|
|
||||||
|
/* maximum sum of pulses per shell coding frame */
|
||||||
|
#define MAX_PULSES 18
|
||||||
|
|
||||||
|
#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
|
||||||
|
|
||||||
|
#if( MAX_LPC_ORDER > DECISION_DELAY )
|
||||||
|
# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
|
||||||
|
#else
|
||||||
|
# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* High pass filtering */
|
||||||
|
/***********************/
|
||||||
|
#define HIGH_PASS_INPUT 1
|
||||||
|
|
||||||
|
/***************************/
|
||||||
|
/* Voice activity detector */
|
||||||
|
/***************************/
|
||||||
|
#define VAD_N_BANDS 4
|
||||||
|
|
||||||
|
#define VAD_INTERNAL_SUBFRAMES_LOG2 2
|
||||||
|
#define VAD_INTERNAL_SUBFRAMES (1 << VAD_INTERNAL_SUBFRAMES_LOG2)
|
||||||
|
|
||||||
|
#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */
|
||||||
|
#define VAD_NOISE_LEVELS_BIAS 50
|
||||||
|
|
||||||
|
/* Sigmoid settings */
|
||||||
|
#define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */
|
||||||
|
#define VAD_SNR_FACTOR_Q16 45000
|
||||||
|
|
||||||
|
/* smoothing for SNR measurement */
|
||||||
|
#define VAD_SNR_SMOOTH_COEF_Q18 4096
|
||||||
|
|
||||||
|
/******************/
|
||||||
|
/* NLSF quantizer */
|
||||||
|
/******************/
|
||||||
|
# define NLSF_MSVQ_MAX_CB_STAGES 10 /* Update manually when changing codebooks */
|
||||||
|
# define NLSF_MSVQ_MAX_VECTORS_IN_STAGE 128 /* Update manually when changing codebooks */
|
||||||
|
# define NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END 16 /* Update manually when changing codebooks */
|
||||||
|
|
||||||
|
#define NLSF_MSVQ_FLUCTUATION_REDUCTION 1
|
||||||
|
#define MAX_NLSF_MSVQ_SURVIVORS 16
|
||||||
|
#define MAX_NLSF_MSVQ_SURVIVORS_LC_MODE 2
|
||||||
|
#define MAX_NLSF_MSVQ_SURVIVORS_MC_MODE 4
|
||||||
|
|
||||||
|
/* Based on above defines, calculate how much memory is necessary to allocate */
|
||||||
|
#if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) )
|
||||||
|
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE NLSF_MSVQ_MAX_VECTORS_IN_STAGE
|
||||||
|
#else
|
||||||
|
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) )
|
||||||
|
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED NLSF_MSVQ_MAX_VECTORS_IN_STAGE
|
||||||
|
#else
|
||||||
|
# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NLSF_MSVQ_SURV_MAX_REL_RD 0.1f /* Must be < 0.5 */
|
||||||
|
|
||||||
|
/* Transition filtering for mode switching */
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
# define TRANSITION_TIME_UP_MS 5120 // 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)
|
||||||
|
# define TRANSITION_TIME_DOWN_MS 2560 // 2560 = 32 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 32*(20*4)
|
||||||
|
# define TRANSITION_NB 3 /* Hardcoded in tables */
|
||||||
|
# define TRANSITION_NA 2 /* Hardcoded in tables */
|
||||||
|
# define TRANSITION_INT_NUM 5 /* Hardcoded in tables */
|
||||||
|
# define TRANSITION_FRAMES_UP ( TRANSITION_TIME_UP_MS / FRAME_LENGTH_MS )
|
||||||
|
# define TRANSITION_FRAMES_DOWN ( TRANSITION_TIME_DOWN_MS / FRAME_LENGTH_MS )
|
||||||
|
# define TRANSITION_INT_STEPS_UP ( TRANSITION_FRAMES_UP / ( TRANSITION_INT_NUM - 1 ) )
|
||||||
|
# define TRANSITION_INT_STEPS_DOWN ( TRANSITION_FRAMES_DOWN / ( TRANSITION_INT_NUM - 1 ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Row based */
|
||||||
|
#define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column)))
|
||||||
|
#define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column)))
|
||||||
|
|
||||||
|
/* Column based */
|
||||||
|
#ifndef matrix_c_ptr
|
||||||
|
# define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column)))
|
||||||
|
#endif
|
||||||
|
#define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column)))
|
||||||
|
|
||||||
|
/* BWE factors to apply after packet loss */
|
||||||
|
#define BWE_AFTER_LOSS_Q16 63570
|
||||||
|
|
||||||
|
/* Defines for CN generation */
|
||||||
|
#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */
|
||||||
|
#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */
|
||||||
|
#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
76
app/src/main/cpp/src/SKP_Silk_detect_SWB_input.c
Normal file
76
app/src/main/cpp/src/SKP_Silk_detect_SWB_input.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detect SWB input by measuring energy above 8 kHz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
void SKP_Silk_detect_SWB_input(
|
||||||
|
SKP_Silk_detect_SWB_state *psSWBdetect, /* (I/O) encoder state */
|
||||||
|
const SKP_int16 samplesIn[], /* (I) input to encoder */
|
||||||
|
SKP_int nSamplesIn /* (I) length of input */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int HP_8_kHz_len, i, shift;
|
||||||
|
SKP_int16 in_HP_8_kHz[ MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int32 energy_32;
|
||||||
|
|
||||||
|
/* High pass filter with cutoff at 8 khz */
|
||||||
|
HP_8_kHz_len = SKP_min_int( nSamplesIn, MAX_FRAME_LENGTH );
|
||||||
|
HP_8_kHz_len = SKP_max_int( HP_8_kHz_len, 0 );
|
||||||
|
|
||||||
|
/* Cutoff around 9 khz */
|
||||||
|
/* A = conv(conv([8192,14613, 6868], [8192,12883, 7337]), [8192,11586, 7911]); */
|
||||||
|
/* B = conv(conv([575, -948, 575], [575, -221, 575]), [575, 104, 575]); */
|
||||||
|
SKP_Silk_biquad( samplesIn, SKP_Silk_SWB_detect_B_HP_Q13[ 0 ], SKP_Silk_SWB_detect_A_HP_Q13[ 0 ],
|
||||||
|
psSWBdetect->S_HP_8_kHz[ 0 ], in_HP_8_kHz, HP_8_kHz_len );
|
||||||
|
for( i = 1; i < NB_SOS; i++ ) {
|
||||||
|
SKP_Silk_biquad( in_HP_8_kHz, SKP_Silk_SWB_detect_B_HP_Q13[ i ], SKP_Silk_SWB_detect_A_HP_Q13[ i ],
|
||||||
|
psSWBdetect->S_HP_8_kHz[ i ], in_HP_8_kHz, HP_8_kHz_len );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate energy in HP signal */
|
||||||
|
SKP_Silk_sum_sqr_shift( &energy_32, &shift, in_HP_8_kHz, HP_8_kHz_len );
|
||||||
|
|
||||||
|
/* Count concecutive samples above threshold, after adjusting threshold for number of input samples and shift */
|
||||||
|
if( energy_32 > SKP_RSHIFT( SKP_SMULBB( HP_8_KHZ_THRES, HP_8_kHz_len ), shift ) ) {
|
||||||
|
psSWBdetect->ConsecSmplsAboveThres += nSamplesIn;
|
||||||
|
if( psSWBdetect->ConsecSmplsAboveThres > CONCEC_SWB_SMPLS_THRES ) {
|
||||||
|
psSWBdetect->SWB_detected = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
psSWBdetect->ConsecSmplsAboveThres -= nSamplesIn;
|
||||||
|
psSWBdetect->ConsecSmplsAboveThres = SKP_max( psSWBdetect->ConsecSmplsAboveThres, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If sufficient speech activity and no SWB detected, we detect the signal as being WB */
|
||||||
|
if( ( psSWBdetect->ActiveSpeech_ms > WB_DETECT_ACTIVE_SPEECH_MS_THRES ) && ( psSWBdetect->SWB_detected == 0 ) ) {
|
||||||
|
psSWBdetect->WB_detected = 1;
|
||||||
|
}
|
||||||
|
}
|
35
app/src/main/cpp/src/SKP_Silk_div_oabi.c
Normal file
35
app/src/main/cpp/src/SKP_Silk_div_oabi.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_typedef.h"
|
||||||
|
|
||||||
|
SKP_int32 SKP_DIV32_arm( SKP_int32 a32, SKP_int32 b32 ) {
|
||||||
|
return ( ( SKP_int32 )( ( a32 ) / ( b32 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
247
app/src/main/cpp/src/SKP_Silk_enc_API.c
Normal file
247
app/src/main/cpp/src/SKP_Silk_enc_API.c
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SKP_Silk_define.h"
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_SDK_API.h"
|
||||||
|
#include "SKP_Silk_control.h"
|
||||||
|
#include "SKP_Silk_typedef.h"
|
||||||
|
#include "SKP_Silk_structs.h"
|
||||||
|
#define SKP_Silk_EncodeControlStruct SKP_SILK_SDK_EncControlStruct
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Encoder functions */
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
SKP_int SKP_Silk_SDK_Get_Encoder_Size( SKP_int32 *encSizeBytes )
|
||||||
|
{
|
||||||
|
SKP_int ret = 0;
|
||||||
|
|
||||||
|
*encSizeBytes = sizeof( SKP_Silk_encoder_state_FIX );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************/
|
||||||
|
/* Read control structure from encoder */
|
||||||
|
/***************************************/
|
||||||
|
SKP_int SKP_Silk_SDK_QueryEncoder(
|
||||||
|
const void *encState, /* I: State Vector */
|
||||||
|
SKP_Silk_EncodeControlStruct *encStatus /* O: Control Structure */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc;
|
||||||
|
SKP_int ret = 0;
|
||||||
|
|
||||||
|
psEnc = ( SKP_Silk_encoder_state_FIX* )encState;
|
||||||
|
|
||||||
|
encStatus->API_sampleRate = psEnc->sCmn.API_fs_Hz;
|
||||||
|
encStatus->maxInternalSampleRate = SKP_SMULBB( psEnc->sCmn.maxInternal_fs_kHz, 1000 );
|
||||||
|
encStatus->packetSize = ( SKP_int )SKP_DIV32_16( psEnc->sCmn.API_fs_Hz * psEnc->sCmn.PacketSize_ms, 1000 ); /* convert samples -> ms */
|
||||||
|
encStatus->bitRate = psEnc->sCmn.TargetRate_bps;
|
||||||
|
encStatus->packetLossPercentage = psEnc->sCmn.PacketLoss_perc;
|
||||||
|
encStatus->complexity = psEnc->sCmn.Complexity;
|
||||||
|
encStatus->useInBandFEC = psEnc->sCmn.useInBandFEC;
|
||||||
|
encStatus->useDTX = psEnc->sCmn.useDTX;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************/
|
||||||
|
/* Init or Reset encoder */
|
||||||
|
/*************************/
|
||||||
|
SKP_int SKP_Silk_SDK_InitEncoder(
|
||||||
|
void *encState, /* I/O: State */
|
||||||
|
SKP_Silk_EncodeControlStruct *encStatus /* O: Control structure */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc;
|
||||||
|
SKP_int ret = 0;
|
||||||
|
|
||||||
|
|
||||||
|
psEnc = ( SKP_Silk_encoder_state_FIX* )encState;
|
||||||
|
|
||||||
|
/* Reset Encoder */
|
||||||
|
if( ret += SKP_Silk_init_encoder_FIX( psEnc ) ) {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read control structure */
|
||||||
|
if( ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus ) ) {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* Encode frame with Silk */
|
||||||
|
/**************************/
|
||||||
|
SKP_int SKP_Silk_SDK_Encode(
|
||||||
|
void *encState, /* I/O: State */
|
||||||
|
const SKP_Silk_EncodeControlStruct *encControl, /* I: Control structure */
|
||||||
|
const SKP_int16 *samplesIn, /* I: Speech sample input vector */
|
||||||
|
SKP_int nSamplesIn, /* I: Number of samples in input vector */
|
||||||
|
SKP_uint8 *outData, /* O: Encoded output vector */
|
||||||
|
SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int max_internal_fs_kHz, PacketSize_ms, PacketLoss_perc, UseInBandFEC, UseDTX, ret = 0;
|
||||||
|
SKP_int nSamplesToBuffer, Complexity, input_10ms, nSamplesFromInput = 0;
|
||||||
|
SKP_int32 TargetRate_bps, API_fs_Hz;
|
||||||
|
SKP_int16 MaxBytesOut;
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc = ( SKP_Silk_encoder_state_FIX* )encState;
|
||||||
|
|
||||||
|
SKP_assert( encControl != NULL );
|
||||||
|
|
||||||
|
/* Check sampling frequency first, to avoid divide by zero later */
|
||||||
|
if( ( ( encControl->API_sampleRate != 8000 ) &&
|
||||||
|
( encControl->API_sampleRate != 12000 ) &&
|
||||||
|
( encControl->API_sampleRate != 16000 ) &&
|
||||||
|
( encControl->API_sampleRate != 24000 ) &&
|
||||||
|
( encControl->API_sampleRate != 32000 ) &&
|
||||||
|
( encControl->API_sampleRate != 44100 ) &&
|
||||||
|
( encControl->API_sampleRate != 48000 ) ) ||
|
||||||
|
( ( encControl->maxInternalSampleRate != 8000 ) &&
|
||||||
|
( encControl->maxInternalSampleRate != 12000 ) &&
|
||||||
|
( encControl->maxInternalSampleRate != 16000 ) &&
|
||||||
|
( encControl->maxInternalSampleRate != 24000 ) ) ) {
|
||||||
|
ret = SKP_SILK_ENC_FS_NOT_SUPPORTED;
|
||||||
|
SKP_assert( 0 );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set encoder parameters from control structure */
|
||||||
|
API_fs_Hz = encControl->API_sampleRate;
|
||||||
|
max_internal_fs_kHz = (SKP_int)( encControl->maxInternalSampleRate >> 10 ) + 1; /* convert Hz -> kHz */
|
||||||
|
PacketSize_ms = SKP_DIV32( 1000 * (SKP_int)encControl->packetSize, API_fs_Hz );
|
||||||
|
TargetRate_bps = encControl->bitRate;
|
||||||
|
PacketLoss_perc = encControl->packetLossPercentage;
|
||||||
|
UseInBandFEC = encControl->useInBandFEC;
|
||||||
|
Complexity = encControl->complexity;
|
||||||
|
UseDTX = encControl->useDTX;
|
||||||
|
|
||||||
|
/* Save values in state */
|
||||||
|
psEnc->sCmn.API_fs_Hz = API_fs_Hz;
|
||||||
|
psEnc->sCmn.maxInternal_fs_kHz = max_internal_fs_kHz;
|
||||||
|
psEnc->sCmn.useInBandFEC = UseInBandFEC;
|
||||||
|
|
||||||
|
/* Only accept input lengths that are a multiple of 10 ms */
|
||||||
|
input_10ms = SKP_DIV32( 100 * nSamplesIn, API_fs_Hz );
|
||||||
|
if( input_10ms * API_fs_Hz != 100 * nSamplesIn || nSamplesIn < 0 ) {
|
||||||
|
ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
|
||||||
|
SKP_assert( 0 );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
|
||||||
|
if( ( ret = SKP_Silk_control_encoder_FIX( psEnc, PacketSize_ms, TargetRate_bps,
|
||||||
|
PacketLoss_perc, UseDTX, Complexity) ) != 0 ) {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure no more than one packet can be produced */
|
||||||
|
if( 1000 * (SKP_int32)nSamplesIn > psEnc->sCmn.PacketSize_ms * API_fs_Hz ) {
|
||||||
|
ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
|
||||||
|
SKP_assert( 0 );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MAX_FS_KHZ > 16
|
||||||
|
/* Detect energy above 8 kHz */
|
||||||
|
if( SKP_min( API_fs_Hz, 1000 * max_internal_fs_kHz ) == 24000 &&
|
||||||
|
psEnc->sCmn.sSWBdetect.SWB_detected == 0 &&
|
||||||
|
psEnc->sCmn.sSWBdetect.WB_detected == 0 ) {
|
||||||
|
SKP_Silk_detect_SWB_input( &psEnc->sCmn.sSWBdetect, samplesIn, ( SKP_int )nSamplesIn );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Input buffering/resampling and encoding */
|
||||||
|
MaxBytesOut = 0; /* return 0 output bytes if no encoder called */
|
||||||
|
while( 1 ) {
|
||||||
|
nSamplesToBuffer = psEnc->sCmn.frame_length - psEnc->sCmn.inputBufIx;
|
||||||
|
if( API_fs_Hz == SKP_SMULBB( 1000, psEnc->sCmn.fs_kHz ) ) {
|
||||||
|
nSamplesToBuffer = SKP_min_int( nSamplesToBuffer, nSamplesIn );
|
||||||
|
nSamplesFromInput = nSamplesToBuffer;
|
||||||
|
/* Copy to buffer */
|
||||||
|
SKP_memcpy( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput * sizeof( SKP_int16 ) );
|
||||||
|
} else {
|
||||||
|
nSamplesToBuffer = SKP_min( nSamplesToBuffer, 10 * input_10ms * psEnc->sCmn.fs_kHz );
|
||||||
|
nSamplesFromInput = SKP_DIV32_16( nSamplesToBuffer * API_fs_Hz, psEnc->sCmn.fs_kHz * 1000 );
|
||||||
|
/* Resample and write to buffer */
|
||||||
|
ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state,
|
||||||
|
&psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput );
|
||||||
|
}
|
||||||
|
samplesIn += nSamplesFromInput;
|
||||||
|
nSamplesIn -= nSamplesFromInput;
|
||||||
|
psEnc->sCmn.inputBufIx += nSamplesToBuffer;
|
||||||
|
|
||||||
|
/* Silk encoder */
|
||||||
|
if( psEnc->sCmn.inputBufIx >= psEnc->sCmn.frame_length ) {
|
||||||
|
SKP_assert( psEnc->sCmn.inputBufIx == psEnc->sCmn.frame_length );
|
||||||
|
|
||||||
|
/* Enough data in input buffer, so encode */
|
||||||
|
if( MaxBytesOut == 0 ) {
|
||||||
|
/* No payload obtained so far */
|
||||||
|
MaxBytesOut = *nBytesOut;
|
||||||
|
if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, &MaxBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* outData already contains a payload */
|
||||||
|
if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, nBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
/* Check that no second payload was created */
|
||||||
|
SKP_assert( *nBytesOut == 0 );
|
||||||
|
}
|
||||||
|
psEnc->sCmn.inputBufIx = 0;
|
||||||
|
psEnc->sCmn.controlled_since_last_payload = 0;
|
||||||
|
|
||||||
|
if( nSamplesIn == 0 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*nBytesOut = MaxBytesOut;
|
||||||
|
if( psEnc->sCmn.useDTX && psEnc->sCmn.inDTX ) {
|
||||||
|
/* DTX simulation */
|
||||||
|
*nBytesOut = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
413
app/src/main/cpp/src/SKP_Silk_encode_frame_FIX.c
Normal file
413
app/src/main/cpp/src/SKP_Silk_encode_frame_FIX.c
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_tuning_parameters.h"
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Encode frame */
|
||||||
|
/****************/
|
||||||
|
SKP_int SKP_Silk_encode_frame_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||||
|
SKP_uint8 *pCode, /* O Pointer to payload */
|
||||||
|
SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */
|
||||||
|
/* input: max length; output: used */
|
||||||
|
const SKP_int16 *pIn /* I Pointer to input speech frame */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_encoder_control_FIX sEncCtrl;
|
||||||
|
SKP_int nBytes, ret = 0;
|
||||||
|
SKP_int16 *x_frame, *res_pitch_frame;
|
||||||
|
SKP_int16 xfw[ MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int16 pIn_HP[ MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
|
||||||
|
SKP_int LBRR_idx, frame_terminator, SNR_dB_Q7;
|
||||||
|
const SKP_uint16 *FrameTermination_CDF;
|
||||||
|
/* Low bitrate redundancy parameters */
|
||||||
|
SKP_uint8 LBRRpayload[ MAX_ARITHM_BYTES ];
|
||||||
|
SKP_int16 nBytesLBRR;
|
||||||
|
|
||||||
|
|
||||||
|
sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;
|
||||||
|
/**************************************************************/
|
||||||
|
/* Setup Input Pointers, and insert frame in input buffer */
|
||||||
|
/*************************************************************/
|
||||||
|
x_frame = psEnc->x_buf + psEnc->sCmn.frame_length; /* start of frame to encode */
|
||||||
|
res_pitch_frame = res_pitch + psEnc->sCmn.frame_length; /* start of pitch LPC residual frame */
|
||||||
|
|
||||||
|
/****************************/
|
||||||
|
/* Voice Activity Detection */
|
||||||
|
/****************************/
|
||||||
|
ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7,
|
||||||
|
sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15,
|
||||||
|
pIn,psEnc->sCmn.frame_length );
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
/* High-pass filtering of the input signal */
|
||||||
|
/*******************************************/
|
||||||
|
#if HIGH_PASS_INPUT
|
||||||
|
/* Variable high-pass filter */
|
||||||
|
SKP_Silk_HP_variable_cutoff_FIX( psEnc, &sEncCtrl, pIn_HP, pIn );
|
||||||
|
#else
|
||||||
|
SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SWITCH_TRANSITION_FILTERING
|
||||||
|
/* Ensure smooth bandwidth transitions */
|
||||||
|
SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length );
|
||||||
|
#else
|
||||||
|
SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Find pitch lags, initial LPC analysis */
|
||||||
|
/*****************************************/
|
||||||
|
SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* Noise shape analysis */
|
||||||
|
/************************/
|
||||||
|
SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Prefiltering for noise shaper */
|
||||||
|
/*****************************************/
|
||||||
|
SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
/* Find linear prediction coefficients (LPC + LTP) */
|
||||||
|
/***************************************************/
|
||||||
|
SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch );
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Process gains */
|
||||||
|
/****************************************/
|
||||||
|
SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Low Bitrate Redundant Encoding */
|
||||||
|
/****************************************/
|
||||||
|
nBytesLBRR = MAX_ARITHM_BYTES;
|
||||||
|
SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Noise shaping quantization */
|
||||||
|
/*****************************************/
|
||||||
|
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||||
|
SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sNSQ, xfw,
|
||||||
|
psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2,
|
||||||
|
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||||
|
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10,
|
||||||
|
sEncCtrl.LTP_scale_Q14 );
|
||||||
|
} else {
|
||||||
|
SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sNSQ, xfw,
|
||||||
|
psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2,
|
||||||
|
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||||
|
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10,
|
||||||
|
sEncCtrl.LTP_scale_Q14 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/* Convert speech activity into VAD and DTX flags */
|
||||||
|
/**************************************************/
|
||||||
|
if( psEnc->speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
|
||||||
|
psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;
|
||||||
|
psEnc->sCmn.noSpeechCounter++;
|
||||||
|
if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||||
|
psEnc->sCmn.inDTX = 1;
|
||||||
|
}
|
||||||
|
if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NO_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||||
|
psEnc->sCmn.noSpeechCounter = NO_SPEECH_FRAMES_BEFORE_DTX;
|
||||||
|
psEnc->sCmn.inDTX = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
psEnc->sCmn.noSpeechCounter = 0;
|
||||||
|
psEnc->sCmn.inDTX = 0;
|
||||||
|
psEnc->sCmn.vadFlag = VOICE_ACTIVITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Initialize range coder */
|
||||||
|
/****************************************/
|
||||||
|
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
|
||||||
|
SKP_Silk_range_enc_init( &psEnc->sCmn.sRC );
|
||||||
|
psEnc->sCmn.nBytesInPayloadBuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Encode Parameters */
|
||||||
|
/****************************************/
|
||||||
|
SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC, psEnc->sCmn.q );
|
||||||
|
FrameTermination_CDF = SKP_Silk_FrameTermination_CDF;
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Update Buffers and State */
|
||||||
|
/****************************************/
|
||||||
|
/* Update input buffer */
|
||||||
|
SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
|
||||||
|
( psEnc->sCmn.frame_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
/* Parameters needed for next frame */
|
||||||
|
psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype;
|
||||||
|
psEnc->sCmn.prevLag = sEncCtrl.sCmn.pitchL[ NB_SUBFR - 1];
|
||||||
|
psEnc->sCmn.first_frame_after_reset = 0;
|
||||||
|
|
||||||
|
if( psEnc->sCmn.sRC.error ) {
|
||||||
|
/* Encoder returned error: clear payload buffer */
|
||||||
|
psEnc->sCmn.nFramesInPayloadBuf = 0;
|
||||||
|
} else {
|
||||||
|
psEnc->sCmn.nFramesInPayloadBuf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Finalize payload and copy to output */
|
||||||
|
/****************************************/
|
||||||
|
if( psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms ) {
|
||||||
|
|
||||||
|
LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;
|
||||||
|
|
||||||
|
/* Check if FEC information should be added */
|
||||||
|
frame_terminator = SKP_SILK_LAST_FRAME;
|
||||||
|
if( psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS1 ) {
|
||||||
|
frame_terminator = SKP_SILK_LBRR_VER1;
|
||||||
|
}
|
||||||
|
if( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS2 ) {
|
||||||
|
frame_terminator = SKP_SILK_LBRR_VER2;
|
||||||
|
LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the frame termination info to stream */
|
||||||
|
SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );
|
||||||
|
|
||||||
|
/* Payload length so far */
|
||||||
|
SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );
|
||||||
|
|
||||||
|
/* Check that there is enough space in external output buffer, and move data */
|
||||||
|
if( *pnBytesOut >= nBytes ) {
|
||||||
|
SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC );
|
||||||
|
SKP_memcpy( pCode, psEnc->sCmn.sRC.buffer, nBytes * sizeof( SKP_uint8 ) );
|
||||||
|
|
||||||
|
if( frame_terminator > SKP_SILK_MORE_FRAMES &&
|
||||||
|
*pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {
|
||||||
|
/* Get old packet and add to payload. */
|
||||||
|
SKP_memcpy( &pCode[ nBytes ],
|
||||||
|
psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload,
|
||||||
|
psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) );
|
||||||
|
nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pnBytesOut = nBytes;
|
||||||
|
|
||||||
|
/* Update FEC buffer */
|
||||||
|
SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload,
|
||||||
|
nBytesLBRR * sizeof( SKP_uint8 ) );
|
||||||
|
psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR;
|
||||||
|
/* The line below describes how FEC should be used */
|
||||||
|
psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage;
|
||||||
|
psEnc->sCmn.oldest_LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Not enough space: Payload will be discarded */
|
||||||
|
*pnBytesOut = 0;
|
||||||
|
nBytes = 0;
|
||||||
|
ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the number of frames in payload buffer */
|
||||||
|
psEnc->sCmn.nFramesInPayloadBuf = 0;
|
||||||
|
} else {
|
||||||
|
/* No payload this time */
|
||||||
|
*pnBytesOut = 0;
|
||||||
|
|
||||||
|
/* Encode that more frames follows */
|
||||||
|
frame_terminator = SKP_SILK_MORE_FRAMES;
|
||||||
|
SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );
|
||||||
|
|
||||||
|
/* Payload length so far */
|
||||||
|
SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for arithmetic coder errors */
|
||||||
|
if( psEnc->sCmn.sRC.error ) {
|
||||||
|
ret = SKP_SILK_ENC_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulate number of ms buffered in channel because of exceeding TargetRate */
|
||||||
|
SKP_assert( ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) ==
|
||||||
|
SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );
|
||||||
|
SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );
|
||||||
|
psEnc->BufferedInChannel_ms += SKP_DIV32( 8 * 1000 * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ), psEnc->sCmn.TargetRate_bps );
|
||||||
|
psEnc->BufferedInChannel_ms -= FRAME_LENGTH_MS;
|
||||||
|
psEnc->BufferedInChannel_ms = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );
|
||||||
|
psEnc->sCmn.nBytesInPayloadBuf = nBytes;
|
||||||
|
|
||||||
|
if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES, 8 ) ) {
|
||||||
|
psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, FRAME_LENGTH_MS );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */
|
||||||
|
void SKP_Silk_LBRR_encode_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */
|
||||||
|
SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk encoder control struct */
|
||||||
|
SKP_uint8 *pCode, /* O Pointer to payload */
|
||||||
|
SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */
|
||||||
|
SKP_int16 xfw[] /* I Input signal */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int TempGainsIndices[ NB_SUBFR ], frame_terminator;
|
||||||
|
SKP_int nBytes, nFramesInPayloadBuf;
|
||||||
|
SKP_int32 TempGains_Q16[ NB_SUBFR ];
|
||||||
|
SKP_int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;
|
||||||
|
/*******************************************/
|
||||||
|
/* Control use of inband LBRR */
|
||||||
|
/*******************************************/
|
||||||
|
SKP_Silk_LBRR_ctrl_FIX( psEnc, &psEncCtrl->sCmn );
|
||||||
|
|
||||||
|
if( psEnc->sCmn.LBRR_enabled ) {
|
||||||
|
/* Save original gains */
|
||||||
|
SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, NB_SUBFR * sizeof( SKP_int ) );
|
||||||
|
SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
typeOffset = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten
|
||||||
|
LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;
|
||||||
|
|
||||||
|
/* Set max rate where quant signal is encoded */
|
||||||
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||||
|
Rate_only_parameters = 13500;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
||||||
|
Rate_only_parameters = 15500;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
||||||
|
Rate_only_parameters = 17500;
|
||||||
|
} else if( psEnc->sCmn.fs_kHz == 24 ) {
|
||||||
|
Rate_only_parameters = 19500;
|
||||||
|
} else {
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {
|
||||||
|
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
|
||||||
|
/* First frame in packet; copy everything */
|
||||||
|
SKP_memcpy( &psEnc->sCmn.sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) );
|
||||||
|
|
||||||
|
psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
|
||||||
|
/* Increase Gains to get target LBRR rate */
|
||||||
|
psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
|
||||||
|
psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );
|
||||||
|
}
|
||||||
|
/* Decode to get gains in sync with decoder */
|
||||||
|
/* Overwrite unquantized gains with quantized gains */
|
||||||
|
SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices,
|
||||||
|
&psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf );
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Noise shaping quantization */
|
||||||
|
/*****************************************/
|
||||||
|
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||||
|
SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR,
|
||||||
|
psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||||
|
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||||
|
psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
|
||||||
|
} else {
|
||||||
|
SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR,
|
||||||
|
psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||||
|
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||||
|
psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) );
|
||||||
|
psEncCtrl->sCmn.LTP_scaleIndex = 0;
|
||||||
|
}
|
||||||
|
/****************************************/
|
||||||
|
/* Initialize arithmetic coder */
|
||||||
|
/****************************************/
|
||||||
|
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
|
||||||
|
SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );
|
||||||
|
psEnc->sCmn.nBytesInPayloadBuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Encode Parameters */
|
||||||
|
/****************************************/
|
||||||
|
SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn,
|
||||||
|
&psEnc->sCmn.sRC_LBRR, psEnc->sCmn.q_LBRR );
|
||||||
|
|
||||||
|
if( psEnc->sCmn.sRC_LBRR.error ) {
|
||||||
|
/* Encoder returned error: clear payload buffer */
|
||||||
|
nFramesInPayloadBuf = 0;
|
||||||
|
} else {
|
||||||
|
nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* Finalize payload and copy to output */
|
||||||
|
/****************************************/
|
||||||
|
if( SKP_SMULBB( nFramesInPayloadBuf, FRAME_LENGTH_MS ) >= psEnc->sCmn.PacketSize_ms ) {
|
||||||
|
|
||||||
|
/* Check if FEC information should be added */
|
||||||
|
frame_terminator = SKP_SILK_LAST_FRAME;
|
||||||
|
|
||||||
|
/* Add the frame termination info to stream */
|
||||||
|
SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );
|
||||||
|
|
||||||
|
/* Payload length so far */
|
||||||
|
SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );
|
||||||
|
|
||||||
|
/* Check that there is enough space in external output buffer and move data */
|
||||||
|
if( *pnBytesOut >= nBytes ) {
|
||||||
|
SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC_LBRR );
|
||||||
|
SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.buffer, nBytes * sizeof( SKP_uint8 ) );
|
||||||
|
|
||||||
|
*pnBytesOut = nBytes;
|
||||||
|
} else {
|
||||||
|
/* Not enough space: payload will be discarded */
|
||||||
|
*pnBytesOut = 0;
|
||||||
|
SKP_assert( 0 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No payload this time */
|
||||||
|
*pnBytesOut = 0;
|
||||||
|
|
||||||
|
/* Encode that more frames follows */
|
||||||
|
frame_terminator = SKP_SILK_MORE_FRAMES;
|
||||||
|
SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore original Gains */
|
||||||
|
SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, NB_SUBFR * sizeof( SKP_int ) );
|
||||||
|
SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
|
||||||
|
|
||||||
|
/* Restore LTP scale index and typeoffset */
|
||||||
|
psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;
|
||||||
|
psEnc->sCmn.typeOffsetPrev = typeOffset;
|
||||||
|
}
|
||||||
|
}
|
162
app/src/main/cpp/src/SKP_Silk_encode_parameters.c
Normal file
162
app/src/main/cpp/src/SKP_Silk_encode_parameters.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
/* Encode parameters to create the payload */
|
||||||
|
/*******************************************/
|
||||||
|
void SKP_Silk_encode_parameters(
|
||||||
|
SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||||
|
SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */
|
||||||
|
SKP_Silk_range_coder_state *psRC, /* I/O Range encoder state */
|
||||||
|
const SKP_int8 *q /* I Quantization indices */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, typeOffset;
|
||||||
|
const SKP_Silk_NLSF_CB_struct *psNLSF_CB;
|
||||||
|
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* Encode sampling rate */
|
||||||
|
/************************/
|
||||||
|
/* only done for first frame in packet */
|
||||||
|
if( psEncC->nFramesInPayloadBuf == 0 ) {
|
||||||
|
/* get sampling rate index */
|
||||||
|
for( i = 0; i < 3; i++ ) {
|
||||||
|
if( SKP_Silk_SamplingRates_table[ i ] == psEncC->fs_kHz ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SKP_Silk_range_encoder( psRC, i, SKP_Silk_SamplingRates_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
/* Encode signal type and quantizer offset */
|
||||||
|
/*******************************************/
|
||||||
|
typeOffset = 2 * psEncCtrlC->sigtype + psEncCtrlC->QuantOffsetType;
|
||||||
|
if( psEncC->nFramesInPayloadBuf == 0 ) {
|
||||||
|
/* first frame in packet: independent coding */
|
||||||
|
SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_CDF );
|
||||||
|
} else {
|
||||||
|
/* condidtional coding */
|
||||||
|
SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_joint_CDF[ psEncC->typeOffsetPrev ] );
|
||||||
|
}
|
||||||
|
psEncC->typeOffsetPrev = typeOffset;
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Encode gains */
|
||||||
|
/****************/
|
||||||
|
/* first subframe */
|
||||||
|
if( psEncC->nFramesInPayloadBuf == 0 ) {
|
||||||
|
/* first frame in packet: independent coding */
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_gain_CDF[ psEncCtrlC->sigtype ] );
|
||||||
|
} else {
|
||||||
|
/* condidtional coding */
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_delta_gain_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remaining subframes */
|
||||||
|
for( i = 1; i < NB_SUBFR; i++ ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ i ], SKP_Silk_delta_gain_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Encode NLSFs */
|
||||||
|
/****************/
|
||||||
|
/* Range encoding of the NLSF path */
|
||||||
|
psNLSF_CB = psEncC->psNLSF_CB[ psEncCtrlC->sigtype ];
|
||||||
|
SKP_Silk_range_encoder_multi( psRC, psEncCtrlC->NLSFIndices, psNLSF_CB->StartPtr, psNLSF_CB->nStages );
|
||||||
|
|
||||||
|
/* Encode NLSF interpolation factor */
|
||||||
|
SKP_assert( psEncC->useInterpolatedNLSFs == 1 || psEncCtrlC->NLSFInterpCoef_Q2 == ( 1 << 2 ) );
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->NLSFInterpCoef_Q2, SKP_Silk_NLSF_interpolation_factor_CDF );
|
||||||
|
|
||||||
|
|
||||||
|
if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
|
||||||
|
/*********************/
|
||||||
|
/* Encode pitch lags */
|
||||||
|
/*********************/
|
||||||
|
|
||||||
|
|
||||||
|
/* lag index */
|
||||||
|
if( psEncC->fs_kHz == 8 ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_NB_CDF );
|
||||||
|
} else if( psEncC->fs_kHz == 12 ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_MB_CDF );
|
||||||
|
} else if( psEncC->fs_kHz == 16 ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_WB_CDF );
|
||||||
|
} else {
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_SWB_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* countour index */
|
||||||
|
if( psEncC->fs_kHz == 8 ) {
|
||||||
|
/* Less codevectors used in 8 khz mode */
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_NB_CDF );
|
||||||
|
} else {
|
||||||
|
/* Joint for 12, 16, 24 khz */
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
/* Encode LTP gains */
|
||||||
|
/********************/
|
||||||
|
|
||||||
|
/* PERIndex value */
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->PERIndex, SKP_Silk_LTP_per_index_CDF );
|
||||||
|
|
||||||
|
/* Codebook Indices */
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->LTPIndex[ k ], SKP_Silk_LTP_gain_CDF_ptrs[ psEncCtrlC->PERIndex ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************/
|
||||||
|
/* Encode LTP scaling */
|
||||||
|
/**********************/
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->LTP_scaleIndex, SKP_Silk_LTPscale_CDF );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************/
|
||||||
|
/* Encode seed */
|
||||||
|
/***************/
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncCtrlC->Seed, SKP_Silk_Seed_CDF );
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Encode quantization indices of excitation */
|
||||||
|
/*********************************************/
|
||||||
|
SKP_Silk_encode_pulses( psRC, psEncCtrlC->sigtype, psEncCtrlC->QuantOffsetType, q, psEncC->frame_length );
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Encode VAD flag */
|
||||||
|
/*********************************************/
|
||||||
|
SKP_Silk_range_encoder( psRC, psEncC->vadFlag, SKP_Silk_vadflag_CDF );
|
||||||
|
}
|
195
app/src/main/cpp/src/SKP_Silk_encode_pulses.c
Normal file
195
app/src/main/cpp/src/SKP_Silk_encode_pulses.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main.h"
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Encode quantization indices of excitation */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
SKP_INLINE SKP_int combine_and_check( /* return ok */
|
||||||
|
SKP_int *pulses_comb, /* O */
|
||||||
|
const SKP_int *pulses_in, /* I */
|
||||||
|
SKP_int max_pulses, /* I max value for sum of pulses */
|
||||||
|
SKP_int len /* I number of output values */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k, sum;
|
||||||
|
|
||||||
|
for( k = 0; k < len; k++ ) {
|
||||||
|
sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];
|
||||||
|
if( sum > max_pulses ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pulses_comb[ k ] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encode quantization indices of excitation */
|
||||||
|
void SKP_Silk_encode_pulses(
|
||||||
|
SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
|
||||||
|
const SKP_int sigtype, /* I Sigtype */
|
||||||
|
const SKP_int QuantOffsetType,/* I QuantOffsetType */
|
||||||
|
const SKP_int8 q[], /* I quantization indices */
|
||||||
|
const SKP_int frame_length /* I Frame length */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
|
||||||
|
SKP_int32 abs_q, minSumBits_Q6, sumBits_Q6;
|
||||||
|
SKP_int abs_pulses[ MAX_FRAME_LENGTH ];
|
||||||
|
SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ];
|
||||||
|
SKP_int nRshifts[ MAX_NB_SHELL_BLOCKS ];
|
||||||
|
SKP_int pulses_comb[ 8 ];
|
||||||
|
SKP_int *abs_pulses_ptr;
|
||||||
|
const SKP_int8 *pulses_ptr;
|
||||||
|
const SKP_uint16 *cdf_ptr;
|
||||||
|
const SKP_int16 *nBits_ptr;
|
||||||
|
|
||||||
|
SKP_memset( pulses_comb, 0, 8 * sizeof( SKP_int ) ); // Fixing Valgrind reported problem
|
||||||
|
|
||||||
|
/****************************/
|
||||||
|
/* Prepare for shell coding */
|
||||||
|
/****************************/
|
||||||
|
/* Calculate number of shell blocks */
|
||||||
|
iter = frame_length / SHELL_CODEC_FRAME_LENGTH;
|
||||||
|
|
||||||
|
/* Take the absolute value of the pulses */
|
||||||
|
for( i = 0; i < frame_length; i+=4 ) {
|
||||||
|
abs_pulses[i+0] = ( SKP_int )SKP_abs( q[ i + 0 ] );
|
||||||
|
abs_pulses[i+1] = ( SKP_int )SKP_abs( q[ i + 1 ] );
|
||||||
|
abs_pulses[i+2] = ( SKP_int )SKP_abs( q[ i + 2 ] );
|
||||||
|
abs_pulses[i+3] = ( SKP_int )SKP_abs( q[ i + 3 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calc sum pulses per shell code frame */
|
||||||
|
abs_pulses_ptr = abs_pulses;
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
nRshifts[ i ] = 0;
|
||||||
|
|
||||||
|
while( 1 ) {
|
||||||
|
/* 1+1 -> 2 */
|
||||||
|
scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, SKP_Silk_max_pulses_table[ 0 ], 8 );
|
||||||
|
|
||||||
|
/* 2+2 -> 4 */
|
||||||
|
scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 1 ], 4 );
|
||||||
|
|
||||||
|
/* 4+4 -> 8 */
|
||||||
|
scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 2 ], 2 );
|
||||||
|
|
||||||
|
/* 8+8 -> 16 */
|
||||||
|
sum_pulses[ i ] = pulses_comb[ 0 ] + pulses_comb[ 1 ];
|
||||||
|
if( sum_pulses[ i ] > SKP_Silk_max_pulses_table[ 3 ] ) {
|
||||||
|
scale_down++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( scale_down ) {
|
||||||
|
/* We need to down scale the quantization signal */
|
||||||
|
nRshifts[ i ]++;
|
||||||
|
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
|
||||||
|
abs_pulses_ptr[ k ] = SKP_RSHIFT( abs_pulses_ptr[ k ], 1 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Jump out of while(1) loop and go to next shell coding frame */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************/
|
||||||
|
/* Rate level */
|
||||||
|
/**************/
|
||||||
|
/* find rate level that leads to fewest bits for coding of pulses per block info */
|
||||||
|
minSumBits_Q6 = SKP_int32_MAX;
|
||||||
|
for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {
|
||||||
|
nBits_ptr = SKP_Silk_pulses_per_block_BITS_Q6[ k ];
|
||||||
|
sumBits_Q6 = SKP_Silk_rate_levels_BITS_Q6[sigtype][ k ];
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
if( nRshifts[ i ] > 0 ) {
|
||||||
|
sumBits_Q6 += nBits_ptr[ MAX_PULSES + 1 ];
|
||||||
|
} else {
|
||||||
|
sumBits_Q6 += nBits_ptr[ sum_pulses[ i ] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( sumBits_Q6 < minSumBits_Q6 ) {
|
||||||
|
minSumBits_Q6 = sumBits_Q6;
|
||||||
|
RateLevelIndex = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SKP_Silk_range_encoder( psRC, RateLevelIndex, SKP_Silk_rate_levels_CDF[ sigtype ] );
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
/* Sum-Weighted-Pulses Encoding */
|
||||||
|
/***************************************************/
|
||||||
|
cdf_ptr = SKP_Silk_pulses_per_block_CDF[ RateLevelIndex ];
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
if( nRshifts[ i ] == 0 ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, sum_pulses[ i ], cdf_ptr );
|
||||||
|
} else {
|
||||||
|
SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, cdf_ptr );
|
||||||
|
for( k = 0; k < nRshifts[ i ] - 1; k++ ) {
|
||||||
|
SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] );
|
||||||
|
}
|
||||||
|
SKP_Silk_range_encoder( psRC, sum_pulses[ i ], SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************/
|
||||||
|
/* Shell Encoding */
|
||||||
|
/******************/
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
if( sum_pulses[ i ] > 0 ) {
|
||||||
|
SKP_Silk_shell_encoder( psRC, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* LSB Encoding */
|
||||||
|
/****************/
|
||||||
|
for( i = 0; i < iter; i++ ) {
|
||||||
|
if( nRshifts[ i ] > 0 ) {
|
||||||
|
pulses_ptr = &q[ i * SHELL_CODEC_FRAME_LENGTH ];
|
||||||
|
nLS = nRshifts[ i ] - 1;
|
||||||
|
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
|
||||||
|
abs_q = (SKP_int8)SKP_abs( pulses_ptr[ k ] );
|
||||||
|
for( j = nLS; j > 0; j-- ) {
|
||||||
|
bit = SKP_RSHIFT( abs_q, j ) & 1;
|
||||||
|
SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF );
|
||||||
|
}
|
||||||
|
bit = abs_q & 1;
|
||||||
|
SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Encode signs */
|
||||||
|
/****************/
|
||||||
|
SKP_Silk_encode_signs( psRC, q, frame_length, sigtype, QuantOffsetType, RateLevelIndex );
|
||||||
|
}
|
148
app/src/main/cpp/src/SKP_Silk_find_LPC_FIX.c
Normal file
148
app/src/main/cpp/src/SKP_Silk_find_LPC_FIX.c
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_tuning_parameters.h"
|
||||||
|
|
||||||
|
/* Finds LPC vector from correlations, and converts to NLSF */
|
||||||
|
void SKP_Silk_find_LPC_FIX(
|
||||||
|
SKP_int NLSF_Q15[], /* O NLSFs */
|
||||||
|
SKP_int *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */
|
||||||
|
const SKP_int prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */
|
||||||
|
const SKP_int useInterpolatedNLSFs, /* I Flag */
|
||||||
|
const SKP_int LPC_order, /* I LPC order */
|
||||||
|
const SKP_int16 x[], /* I Input signal */
|
||||||
|
const SKP_int subfr_length /* I Input signal subframe length including preceeding samples */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int k;
|
||||||
|
SKP_int32 a_Q16[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int isInterpLower, shift;
|
||||||
|
SKP_int16 S[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int32 res_nrg0, res_nrg1;
|
||||||
|
SKP_int rshift0, rshift1;
|
||||||
|
|
||||||
|
/* Used only for LSF interpolation */
|
||||||
|
SKP_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
|
||||||
|
SKP_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
|
||||||
|
SKP_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int NLSF0_Q15[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int16 LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
|
||||||
|
|
||||||
|
/* Default: no interpolation */
|
||||||
|
*interpIndex = 4;
|
||||||
|
|
||||||
|
/* Burg AR analysis for the full frame */
|
||||||
|
SKP_Silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, NB_SUBFR, SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
|
||||||
|
|
||||||
|
SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
|
||||||
|
|
||||||
|
if( useInterpolatedNLSFs == 1 ) {
|
||||||
|
|
||||||
|
/* Optimal solution for last 10 ms */
|
||||||
|
SKP_Silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( NB_SUBFR >> 1 ) * subfr_length,
|
||||||
|
subfr_length, ( NB_SUBFR >> 1 ), SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
|
||||||
|
|
||||||
|
SKP_Silk_bwexpander_32( a_tmp_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
|
||||||
|
|
||||||
|
/* subtract residual energy here, as that's easier than adding it to the */
|
||||||
|
/* residual energy of the first 10 ms in each iteration of the search below */
|
||||||
|
shift = res_tmp_nrg_Q - res_nrg_Q;
|
||||||
|
if( shift >= 0 ) {
|
||||||
|
if( shift < 32 ) {
|
||||||
|
res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SKP_assert( shift > -32 );
|
||||||
|
res_nrg = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
|
||||||
|
res_nrg_Q = res_tmp_nrg_Q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert to NLSFs */
|
||||||
|
SKP_Silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order );
|
||||||
|
|
||||||
|
/* Search over interpolation indices to find the one with lowest residual energy */
|
||||||
|
for( k = 3; k >= 0; k-- ) {
|
||||||
|
/* Interpolate NLSFs for first half */
|
||||||
|
SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
||||||
|
|
||||||
|
/* Convert to LPC for residual energy evaluation */
|
||||||
|
SKP_Silk_NLSF2A_stable( a_tmp_Q12, NLSF0_Q15, LPC_order );
|
||||||
|
|
||||||
|
/* Calculate residual energy with NLSF interpolation */
|
||||||
|
SKP_memset( S, 0, LPC_order * sizeof( SKP_int16 ) );
|
||||||
|
SKP_Silk_LPC_analysis_filter( x, a_tmp_Q12, S, LPC_res, 2 * subfr_length, LPC_order );
|
||||||
|
|
||||||
|
SKP_Silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order, subfr_length - LPC_order );
|
||||||
|
SKP_Silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );
|
||||||
|
|
||||||
|
/* Add subframe energies from first half frame */
|
||||||
|
shift = rshift0 - rshift1;
|
||||||
|
if( shift >= 0 ) {
|
||||||
|
res_nrg1 = SKP_RSHIFT( res_nrg1, shift );
|
||||||
|
res_nrg_interp_Q = -rshift0;
|
||||||
|
} else {
|
||||||
|
res_nrg0 = SKP_RSHIFT( res_nrg0, -shift );
|
||||||
|
res_nrg_interp_Q = -rshift1;
|
||||||
|
}
|
||||||
|
res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 );
|
||||||
|
|
||||||
|
/* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
|
||||||
|
shift = res_nrg_interp_Q - res_nrg_Q;
|
||||||
|
if( shift >= 0 ) {
|
||||||
|
if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
|
||||||
|
isInterpLower = SKP_TRUE;
|
||||||
|
} else {
|
||||||
|
isInterpLower = SKP_FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if( -shift < 32 ) {
|
||||||
|
if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) {
|
||||||
|
isInterpLower = SKP_TRUE;
|
||||||
|
} else {
|
||||||
|
isInterpLower = SKP_FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isInterpLower = SKP_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine whether current interpolated NLSFs are best so far */
|
||||||
|
if( isInterpLower == SKP_TRUE ) {
|
||||||
|
/* Interpolation has lower residual energy */
|
||||||
|
res_nrg = res_nrg_interp;
|
||||||
|
res_nrg_Q = res_nrg_interp_Q;
|
||||||
|
*interpIndex = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *interpIndex == 4 ) {
|
||||||
|
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
||||||
|
SKP_Silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order );
|
||||||
|
}
|
||||||
|
}
|
243
app/src/main/cpp/src/SKP_Silk_find_LTP_FIX.c
Normal file
243
app/src/main/cpp/src/SKP_Silk_find_LTP_FIX.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_tuning_parameters.h"
|
||||||
|
|
||||||
|
/* Head room for correlations */
|
||||||
|
#define LTP_CORRS_HEAD_ROOM 2
|
||||||
|
|
||||||
|
void SKP_Silk_fit_LTP(
|
||||||
|
SKP_int32 LTP_coefs_Q16[ LTP_ORDER ],
|
||||||
|
SKP_int16 LTP_coefs_Q14[ LTP_ORDER ]
|
||||||
|
);
|
||||||
|
|
||||||
|
void SKP_Silk_find_LTP_FIX(
|
||||||
|
SKP_int16 b_Q14[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
|
||||||
|
SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||||
|
SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */
|
||||||
|
const SKP_int16 r_first[], /* I residual signal after LPC signal + state for first 10 ms */
|
||||||
|
const SKP_int16 r_last[], /* I residual signal after LPC signal + state for last 10 ms */
|
||||||
|
const SKP_int lag[ NB_SUBFR ], /* I LTP lags */
|
||||||
|
const SKP_int32 Wght_Q15[ NB_SUBFR ], /* I weights */
|
||||||
|
const SKP_int subfr_length, /* I subframe length */
|
||||||
|
const SKP_int mem_offset, /* I number of samples in LTP memory */
|
||||||
|
SKP_int corr_rshifts[ NB_SUBFR ] /* O right shifts applied to correlations */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i, k, lshift;
|
||||||
|
const SKP_int16 *r_ptr, *lag_ptr;
|
||||||
|
SKP_int16 *b_Q14_ptr;
|
||||||
|
|
||||||
|
SKP_int32 regu;
|
||||||
|
SKP_int32 *WLTP_ptr;
|
||||||
|
SKP_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ NB_SUBFR ], nrg[ NB_SUBFR ], g_Q26;
|
||||||
|
SKP_int32 w[ NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;
|
||||||
|
|
||||||
|
SKP_int32 temp32, denom32;
|
||||||
|
SKP_int extra_shifts;
|
||||||
|
SKP_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;
|
||||||
|
SKP_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;
|
||||||
|
SKP_int32 Rr[ LTP_ORDER ], rr[ NB_SUBFR ];
|
||||||
|
SKP_int32 wd, m_Q12;
|
||||||
|
|
||||||
|
b_Q14_ptr = b_Q14;
|
||||||
|
WLTP_ptr = WLTP;
|
||||||
|
r_ptr = &r_first[ mem_offset ];
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
if( k == ( NB_SUBFR >> 1 ) ) { /* shift residual for last 10 ms */
|
||||||
|
r_ptr = &r_last[ mem_offset ];
|
||||||
|
}
|
||||||
|
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
|
||||||
|
|
||||||
|
SKP_Silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */
|
||||||
|
|
||||||
|
/* Assure headroom */
|
||||||
|
LZs = SKP_Silk_CLZ32( rr[k] );
|
||||||
|
if( LZs < LTP_CORRS_HEAD_ROOM ) {
|
||||||
|
rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );
|
||||||
|
rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );
|
||||||
|
}
|
||||||
|
corr_rshifts[ k ] = rr_shifts;
|
||||||
|
SKP_Silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */
|
||||||
|
|
||||||
|
/* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */
|
||||||
|
SKP_Silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */
|
||||||
|
if( corr_rshifts[ k ] > rr_shifts ) {
|
||||||
|
rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */
|
||||||
|
}
|
||||||
|
SKP_assert( rr[ k ] >= 0 );
|
||||||
|
|
||||||
|
regu = 1;
|
||||||
|
regu = SKP_SMLAWB( regu, rr[ k ], SKP_FIX_CONST( LTP_DAMPING/3, 16 ) );
|
||||||
|
regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) );
|
||||||
|
regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) );
|
||||||
|
SKP_Silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );
|
||||||
|
|
||||||
|
SKP_Silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */
|
||||||
|
|
||||||
|
/* Limit and store in Q14 */
|
||||||
|
SKP_Silk_fit_LTP( b_Q16, b_Q14_ptr );
|
||||||
|
|
||||||
|
/* Calculate residual energy */
|
||||||
|
nrg[ k ] = SKP_Silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */
|
||||||
|
|
||||||
|
/* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */
|
||||||
|
extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );
|
||||||
|
denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */
|
||||||
|
SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */
|
||||||
|
denom32 = SKP_max( denom32, 1 );
|
||||||
|
SKP_assert( ((SKP_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX ); /* Wght always < 0.5 in Q0 */
|
||||||
|
temp32 = SKP_DIV32( SKP_LSHIFT( ( SKP_int32 )Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
|
||||||
|
temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */
|
||||||
|
|
||||||
|
/* Limit temp such that the below scaling never wraps around */
|
||||||
|
WLTP_max = 0;
|
||||||
|
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||||
|
WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max );
|
||||||
|
}
|
||||||
|
lshift = SKP_Silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
|
||||||
|
SKP_assert( 26 - 18 + lshift >= 0 );
|
||||||
|
if( 26 - 18 + lshift < 31 ) {
|
||||||
|
temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( SKP_int32 )1, 26 - 18 + lshift ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
SKP_Silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
|
||||||
|
|
||||||
|
w[ k ] = matrix_ptr( WLTP_ptr, ( LTP_ORDER >> 1 ), ( LTP_ORDER >> 1 ), LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */
|
||||||
|
SKP_assert( w[k] >= 0 );
|
||||||
|
|
||||||
|
r_ptr += subfr_length;
|
||||||
|
b_Q14_ptr += LTP_ORDER;
|
||||||
|
WLTP_ptr += LTP_ORDER * LTP_ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxRshifts = 0;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute LTP coding gain */
|
||||||
|
if( LTPredCodGain_Q7 != NULL ) {
|
||||||
|
LPC_LTP_res_nrg = 0;
|
||||||
|
LPC_res_nrg = 0;
|
||||||
|
SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
LPC_res_nrg = SKP_ADD32( LPC_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
|
||||||
|
LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
|
||||||
|
}
|
||||||
|
LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */
|
||||||
|
|
||||||
|
div_Q16 = SKP_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );
|
||||||
|
*LTPredCodGain_Q7 = ( SKP_int )SKP_SMULBB( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) );
|
||||||
|
|
||||||
|
SKP_assert( *LTPredCodGain_Q7 == ( SKP_int )SKP_SAT16( SKP_MUL( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* smoothing */
|
||||||
|
/* d = sum( B, 1 ); */
|
||||||
|
b_Q14_ptr = b_Q14;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
d_Q14[ k ] = 0;
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
d_Q14[ k ] += b_Q14_ptr[ i ];
|
||||||
|
}
|
||||||
|
b_Q14_ptr += LTP_ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
|
||||||
|
|
||||||
|
/* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */
|
||||||
|
max_abs_d_Q14 = 0;
|
||||||
|
max_w_bits = 0;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) );
|
||||||
|
/* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */
|
||||||
|
/* Find bits needed in Q( 18 - maxRshifts ) */
|
||||||
|
max_w_bits = SKP_max_32( max_w_bits, 32 - SKP_Silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */
|
||||||
|
SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) );
|
||||||
|
|
||||||
|
/* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */
|
||||||
|
extra_shifts = max_w_bits + 32 - SKP_Silk_CLZ32( max_abs_d_Q14 ) - 14;
|
||||||
|
|
||||||
|
/* Subtract what we got available; bits in output var plus maxRshifts */
|
||||||
|
extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */
|
||||||
|
extra_shifts = SKP_max_int( extra_shifts, 0 );
|
||||||
|
|
||||||
|
maxRshifts_wxtra = maxRshifts + extra_shifts;
|
||||||
|
|
||||||
|
temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */
|
||||||
|
wd = 0;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
/* w has at least 2 bits of headroom so no overflow should happen */
|
||||||
|
temp32 = SKP_ADD32( temp32, SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */
|
||||||
|
wd = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */
|
||||||
|
}
|
||||||
|
m_Q12 = SKP_DIV32_varQ( wd, temp32, 12 );
|
||||||
|
|
||||||
|
b_Q14_ptr = b_Q14;
|
||||||
|
for( k = 0; k < NB_SUBFR; k++ ) {
|
||||||
|
/* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */
|
||||||
|
if( 2 - corr_rshifts[k] > 0 ) {
|
||||||
|
temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );
|
||||||
|
} else {
|
||||||
|
temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
g_Q26 = SKP_MUL(
|
||||||
|
SKP_DIV32(
|
||||||
|
SKP_FIX_CONST( LTP_SMOOTHING, 26 ),
|
||||||
|
SKP_RSHIFT( SKP_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */
|
||||||
|
SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( SKP_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */
|
||||||
|
|
||||||
|
temp32 = 0;
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */
|
||||||
|
temp32 += delta_b_Q14[ i ]; /* Q14 */
|
||||||
|
}
|
||||||
|
temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
b_Q14_ptr[ i ] = SKP_LIMIT_32( ( SKP_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
|
||||||
|
}
|
||||||
|
b_Q14_ptr += LTP_ORDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SKP_Silk_fit_LTP(
|
||||||
|
SKP_int32 LTP_coefs_Q16[ LTP_ORDER ],
|
||||||
|
SKP_int16 LTP_coefs_Q14[ LTP_ORDER ]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_int i;
|
||||||
|
|
||||||
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
|
LTP_coefs_Q14[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
|
||||||
|
}
|
||||||
|
}
|
125
app/src/main/cpp/src/SKP_Silk_find_pitch_lags_FIX.c
Normal file
125
app/src/main/cpp/src/SKP_Silk_find_pitch_lags_FIX.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, (subject to the limitations in the disclaimer below)
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of Skype Limited, nor the names of specific
|
||||||
|
contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||||
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "SKP_Silk_main_FIX.h"
|
||||||
|
#include "SKP_Silk_tuning_parameters.h"
|
||||||
|
|
||||||
|
/* Find pitch lags */
|
||||||
|
void SKP_Silk_find_pitch_lags_FIX(
|
||||||
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||||
|
SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||||
|
SKP_int16 res[], /* O residual */
|
||||||
|
const SKP_int16 x[] /* I Speech signal */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SKP_Silk_predict_state_FIX *psPredSt = &psEnc->sPred;
|
||||||
|
SKP_int buf_len, i, scale;
|
||||||
|
SKP_int32 thrhld_Q15, res_nrg;
|
||||||
|
const SKP_int16 *x_buf, *x_buf_ptr;
|
||||||
|
SKP_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr;
|
||||||
|
SKP_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
|
||||||
|
SKP_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||||
|
SKP_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||||
|
SKP_int32 FiltState[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||||
|
SKP_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
/* Setup buffer lengths etc based on Fs */
|
||||||
|
/******************************************/
|
||||||
|
buf_len = SKP_ADD_LSHIFT( psEnc->sCmn.la_pitch, psEnc->sCmn.frame_length, 1 );
|
||||||
|
|
||||||
|
/* Safty check */
|
||||||
|
SKP_assert( buf_len >= psPredSt->pitch_LPC_win_length );
|
||||||
|
|
||||||
|
x_buf = x - psEnc->sCmn.frame_length;
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
/* Estimate LPC AR coefficients */
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
/* Calculate windowed signal */
|
||||||
|
|
||||||
|
/* First LA_LTP samples */
|
||||||
|
x_buf_ptr = x_buf + buf_len - psPredSt->pitch_LPC_win_length;
|
||||||
|
Wsig_ptr = Wsig;
|
||||||
|
SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
|
||||||
|
|
||||||
|
/* Middle un - windowed samples */
|
||||||
|
Wsig_ptr += psEnc->sCmn.la_pitch;
|
||||||
|
x_buf_ptr += psEnc->sCmn.la_pitch;
|
||||||
|
SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
/* Last LA_LTP samples */
|
||||||
|
Wsig_ptr += psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||||
|
x_buf_ptr += psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||||
|
SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
|
||||||
|
|
||||||
|
/* Calculate autocorrelation sequence */
|
||||||
|
SKP_Silk_autocorr( auto_corr, &scale, Wsig, psPredSt->pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );
|
||||||
|
|
||||||
|
/* Add white noise, as fraction of energy */
|
||||||
|
auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
|
||||||
|
|
||||||
|
/* Calculate the reflection coefficients using schur */
|
||||||
|
res_nrg = SKP_Silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||||
|
|
||||||
|
/* Prediction gain */
|
||||||
|
psEncCtrl->predGain_Q16 = SKP_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 );
|
||||||
|
|
||||||
|
/* Convert reflection coefficients to prediction coefficients */
|
||||||
|
SKP_Silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||||
|
|
||||||
|
/* Convert From 32 bit Q24 to 16 bit Q12 coefs */
|
||||||
|
for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
|
||||||
|
A_Q12[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do BWE */
|
||||||
|
SKP_Silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SKP_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) );
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* LPC analysis filtering */
|
||||||
|
/*****************************************/
|
||||||
|
SKP_memset( FiltState, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind will complain otherwise */
|
||||||
|
SKP_Silk_MA_Prediction( x_buf, A_Q12, FiltState, res, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||||
|
SKP_memset( res, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_int16 ) );
|
||||||
|
|
||||||
|
/* Threshold for pitch estimator */
|
||||||
|
thrhld_Q15 = SKP_FIX_CONST( 0.45, 15 );
|
||||||
|
thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder );
|
||||||
|
thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.1, 7 ), psEnc->speech_activity_Q8 );
|
||||||
|
thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( 0.15, 15 ), psEnc->sCmn.prev_sigtype );
|
||||||
|
thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SKP_FIX_CONST( -0.1, 16 ), psEncCtrl->input_tilt_Q15 );
|
||||||
|
thrhld_Q15 = SKP_SAT16( thrhld_Q15 );
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Call pitch estimator */
|
||||||
|
/*****************************************/
|
||||||
|
psEncCtrl->sCmn.sigtype = SKP_Silk_pitch_analysis_core( res, psEncCtrl->sCmn.pitchL, &psEncCtrl->sCmn.lagIndex,
|
||||||
|
&psEncCtrl->sCmn.contourIndex, &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
|
||||||
|
( SKP_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, SKP_FALSE );
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user