├── eclipse-project
├── javadoc
│ ├── package-list
│ ├── index.html
│ ├── help-doc.html
│ ├── stylesheet.css
│ ├── overview-tree.html
│ ├── allclasses-frame.html
│ ├── constant-values.html
│ ├── deprecated-list.html
│ ├── resources
│ │ └── inherit.gif
│ ├── allclasses-noframe.html
│ ├── index-files
│ │ ├── index-1.html
│ │ ├── index-2.html
│ │ ├── index-3.html
│ │ ├── index-4.html
│ │ ├── index-5.html
│ │ ├── index-6.html
│ │ ├── index-7.html
│ │ ├── index-8.html
│ │ └── index-9.html
│ └── com
│ │ └── android
│ │ └── webrtc
│ │ └── audio
│ │ ├── MobileAEC.html
│ │ ├── package-use.html
│ │ ├── package-frame.html
│ │ ├── package-tree.html
│ │ ├── package-summary.html
│ │ ├── MobileAEC.AecmConfig.html
│ │ ├── class-use
│ │ ├── MobileAEC.html
│ │ ├── MobileAEC.AecmConfig.html
│ │ ├── MobileAEC.AggressiveMode.html
│ │ └── MobileAEC.SamplingFrequency.html
│ │ ├── MobileAEC.AggressiveMode.html
│ │ └── MobileAEC.SamplingFrequency.html
├── jni
│ ├── Android.mk
│ ├── Application.mk
│ └── aecm
│ │ ├── Android.mk
│ │ ├── compile_assert_c.h
│ │ ├── cross_correlation.c
│ │ ├── delay_estimator_internal.h
│ │ ├── cpu_features_wrapper.h
│ │ ├── downsample_fast.c
│ │ ├── spl_sqrt_floor.c
│ │ ├── ring_buffer.h
│ │ ├── compile_assert.h
│ │ ├── typedefs.h
│ │ ├── division_operations.c
│ │ ├── aecm_defines.h
│ │ ├── real_fft.c
│ │ ├── complex_bit_reverse.c
│ │ ├── spl_inl.h
│ │ ├── vector_scaling_operations.c
│ │ ├── real_fft.h
│ │ ├── spl_init.c
│ │ ├── min_max_operations.c
│ │ ├── randomization_functions.c
│ │ ├── ring_buffer.c
│ │ ├── delay_estimator_wrapper.h
│ │ ├── delay_estimator.h
│ │ ├── complex_fft_tables.h
│ │ ├── echo_control_mobile.h
│ │ ├── aecm_wrapper.c
│ │ ├── aecm_core.h
│ │ ├── complex_fft.c
│ │ ├── delay_estimator_wrapper.c
│ │ └── delay_estimator.c
├── lint.xml
├── ic_launcher-web.png
├── libs
│ ├── android-support-v4.jar
│ └── armeabi
│ │ └── libwebrtc_aecm.so
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── layout
│ │ └── activity_main.xml
│ ├── menu
│ │ └── activity_main.xml
│ ├── values-v11
│ │ └── styles.xml
│ └── values-v14
│ │ └── styles.xml
├── project.properties
├── proguard-project.txt
├── AndroidManifest.xml
└── src
│ └── com
│ └── billhoo
│ └── android
│ └── aec
│ └── demo
│ └── DemoActivity.java
├── android-aec.jar
├── libwebrtc_aecm.so
├── audio
├── cn
│ ├── cn-01-raw-pcm.jpg
│ ├── cn-02-10ms-echo-tail-output.jpg
│ ├── cn-03-1ms-echo-tail-output.jpg
│ └── cn-00-raw-pcm-16000Hz-16bit-mono.pcm
└── en
│ ├── en-01-raw-pcm.jpg
│ ├── en-02-10ms-echo-tail-output.jpg
│ ├── en-03-1ms-echo-tail-output.jpg
│ └── en-00-raw-pcm-16000Hz-16bit-mono.pcm
├── .gitattributes
├── README.md
├── LISENCE
└── .gitignore
/eclipse-project/javadoc/package-list:
--------------------------------------------------------------------------------
1 | com.android.webrtc.audio
2 |
--------------------------------------------------------------------------------
/eclipse-project/jni/Android.mk:
--------------------------------------------------------------------------------
1 | include $(call all-subdir-makefiles)
2 |
--------------------------------------------------------------------------------
/eclipse-project/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/android-aec.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/android-aec.jar
--------------------------------------------------------------------------------
/libwebrtc_aecm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/libwebrtc_aecm.so
--------------------------------------------------------------------------------
/audio/cn/cn-01-raw-pcm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/cn/cn-01-raw-pcm.jpg
--------------------------------------------------------------------------------
/audio/en/en-01-raw-pcm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/en/en-01-raw-pcm.jpg
--------------------------------------------------------------------------------
/eclipse-project/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/ic_launcher-web.png
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/help-doc.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/help-doc.html
--------------------------------------------------------------------------------
/audio/cn/cn-02-10ms-echo-tail-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/cn/cn-02-10ms-echo-tail-output.jpg
--------------------------------------------------------------------------------
/audio/cn/cn-03-1ms-echo-tail-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/cn/cn-03-1ms-echo-tail-output.jpg
--------------------------------------------------------------------------------
/audio/en/en-02-10ms-echo-tail-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/en/en-02-10ms-echo-tail-output.jpg
--------------------------------------------------------------------------------
/audio/en/en-03-1ms-echo-tail-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/en/en-03-1ms-echo-tail-output.jpg
--------------------------------------------------------------------------------
/eclipse-project/javadoc/stylesheet.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/stylesheet.css
--------------------------------------------------------------------------------
/eclipse-project/javadoc/overview-tree.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/overview-tree.html
--------------------------------------------------------------------------------
/audio/cn/cn-00-raw-pcm-16000Hz-16bit-mono.pcm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/cn/cn-00-raw-pcm-16000Hz-16bit-mono.pcm
--------------------------------------------------------------------------------
/audio/en/en-00-raw-pcm-16000Hz-16bit-mono.pcm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/audio/en/en-00-raw-pcm-16000Hz-16bit-mono.pcm
--------------------------------------------------------------------------------
/eclipse-project/javadoc/allclasses-frame.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/allclasses-frame.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/constant-values.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/constant-values.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/deprecated-list.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/deprecated-list.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/resources/inherit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/resources/inherit.gif
--------------------------------------------------------------------------------
/eclipse-project/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/eclipse-project/javadoc/allclasses-noframe.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/allclasses-noframe.html
--------------------------------------------------------------------------------
/eclipse-project/libs/armeabi/libwebrtc_aecm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/libs/armeabi/libwebrtc_aecm.so
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-1.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-1.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-2.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-2.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-3.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-3.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-4.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-4.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-5.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-5.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-6.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-6.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-7.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-7.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-8.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-8.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/index-files/index-9.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/index-files/index-9.html
--------------------------------------------------------------------------------
/eclipse-project/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/eclipse-project/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/eclipse-project/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/eclipse-project/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/eclipse-project/jni/Application.mk:
--------------------------------------------------------------------------------
1 | # Build both ARMv5TE and ARMv7-A machine code.
2 |
3 | # TODO(billhoo) if use arm_neon mode, enable this
4 | # APP_ABI := armeabi armeabi-v7a
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/package-use.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/package-use.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/package-frame.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/package-frame.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/package-tree.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/package-tree.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/package-summary.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/package-summary.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.AecmConfig.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.AecmConfig.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.AggressiveMode.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.AggressiveMode.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.SamplingFrequency.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/MobileAEC.SamplingFrequency.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.AecmConfig.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.AecmConfig.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.AggressiveMode.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.AggressiveMode.html
--------------------------------------------------------------------------------
/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.SamplingFrequency.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lhc180/webrtc-based-android-aecm/HEAD/eclipse-project/javadoc/com/android/webrtc/audio/class-use/MobileAEC.SamplingFrequency.html
--------------------------------------------------------------------------------
/eclipse-project/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AecmDemo
5 | Hello world!
6 | Settings
7 |
8 |
--------------------------------------------------------------------------------
/eclipse-project/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/eclipse-project/res/menu/activity_main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/eclipse-project/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/eclipse-project/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/eclipse-project/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-14
15 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | include $(CLEAR_VARS)
4 |
5 | LOCAL_MODULE := webrtc_aecm
6 | LOCAL_CFLAGS += -DWEBRTC_POSIX
7 | LOCAL_SRC_FILES := \
8 | randomization_functions.c \
9 | spl_sqrt_floor.c \
10 | division_operations.c \
11 | vector_scaling_operations.c \
12 | downsample_fast.c \
13 | cross_correlation.c \
14 | spl_init.c \
15 | min_max_operations.c \
16 | complex_fft.c \
17 | complex_bit_reverse.c \
18 | real_fft.c \
19 | delay_estimator.c \
20 | delay_estimator_wrapper.c \
21 | ring_buffer.c \
22 | aecm_core.c \
23 | echo_control_mobile.c \
24 | aecm_wrapper.c
25 |
26 | include $(BUILD_SHARED_LIBRARY)
--------------------------------------------------------------------------------
/eclipse-project/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/eclipse-project/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | webrtc-based-android-aecm
2 | =========================
3 |
4 | Java API for android acoustic echo cancellation.
5 |
6 | I already tested and using it on a LAN demo several monthes ago, it worked well most of the time but sometimes with little squeal, I know there must have something todo to make it better.
7 | To make it better
8 | =========================
9 | 1. Maybe I should build the whole VOE and using the C++ interface proveded by apm? I'll try this later.
10 | 2. The API is a low level one, most of them are just wrappers of native WebRTC aecm interface. We should handle so many things by ourselves, like estimate the echo tail,handle capture/render threads etc. I'm planning to provide a higher level of the API, which can handle those things for us automatically.
11 |
12 | TODO List
13 | =========================
14 | 1. Build the apm interface.
15 | 2. Provide a higher level of the API.
16 | 3. Provide a VoIP demo to show how to use this API instead of doing AECM on PCM files.
17 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/compile_assert_c.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
12 | #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
13 |
14 | // Only use this for C files. For C++, use compile_assert.h.
15 | //
16 | // Use this macro to verify at compile time that certain restrictions are met.
17 | // The argument is the boolean expression to evaluate.
18 | // Example:
19 | // COMPILE_ASSERT(sizeof(foo) < 128);
20 | #define COMPILE_ASSERT(expression) switch (0) {case 0: case expression:;}
21 |
22 | #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
23 |
--------------------------------------------------------------------------------
/eclipse-project/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/cross_correlation.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "signal_processing_library.h"
12 |
13 | /* C version of WebRtcSpl_CrossCorrelation() for generic platforms. */
14 | void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation,
15 | const int16_t* seq1,
16 | const int16_t* seq2,
17 | int16_t dim_seq,
18 | int16_t dim_cross_correlation,
19 | int16_t right_shifts,
20 | int16_t step_seq2) {
21 | int i = 0, j = 0;
22 |
23 | for (i = 0; i < dim_cross_correlation; i++) {
24 | *cross_correlation = 0;
25 | /* Unrolling doesn't seem to improve performance. */
26 | for (j = 0; j < dim_seq; j++) {
27 | *cross_correlation += (seq1[j] * seq2[step_seq2 * i + j]) >> right_shifts;
28 | }
29 | cross_correlation++;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LISENCE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, BillHoo. All rights reserved.
2 | Copyright (c) 2011, The WebRTC project authors. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are
6 | met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | * Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in
13 | the documentation and/or other materials provided with the
14 | distribution.
15 |
16 | * Neither the name of Google nor the names of its contributors may
17 | be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/delay_estimator_internal.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // Header file including the delay estimator handle used for testing.
12 |
13 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_INTERNAL_H_
14 | #define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_INTERNAL_H_
15 |
16 | #include "delay_estimator.h"
17 | #include "typedefs.h"
18 |
19 | typedef union {
20 | float float_;
21 | int32_t int32_;
22 | } SpectrumType;
23 |
24 | typedef struct {
25 | // Pointers to mean values of spectrum.
26 | SpectrumType* mean_far_spectrum;
27 | // |mean_far_spectrum| initialization indicator.
28 | int far_spectrum_initialized;
29 |
30 | int spectrum_size;
31 |
32 | // Far-end part of binary spectrum based delay estimation.
33 | BinaryDelayEstimatorFarend* binary_farend;
34 | } DelayEstimatorFarend;
35 |
36 | typedef struct {
37 | // Pointers to mean values of spectrum.
38 | SpectrumType* mean_near_spectrum;
39 | // |mean_near_spectrum| initialization indicator.
40 | int near_spectrum_initialized;
41 |
42 | int spectrum_size;
43 |
44 | // Binary spectrum based delay estimator
45 | BinaryDelayEstimator* binary_handle;
46 | } DelayEstimator;
47 |
48 | #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_INTERNAL_H_
49 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/cpu_features_wrapper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_
12 | #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_
13 |
14 | #if defined(__cplusplus) || defined(c_plusplus)
15 | extern "C" {
16 | #endif
17 |
18 | #include
19 |
20 | // List of features in x86.
21 | typedef enum {
22 | kSSE2,
23 | kSSE3
24 | } CPUFeature;
25 |
26 | // List of features in ARM.
27 | enum {
28 | kCPUFeatureARMv7 = (1 << 0),
29 | kCPUFeatureVFPv3 = (1 << 1),
30 | kCPUFeatureNEON = (1 << 2),
31 | kCPUFeatureLDREXSTREX = (1 << 3)
32 | };
33 |
34 | typedef int (*WebRtc_CPUInfo)(CPUFeature feature);
35 |
36 | // Returns true if the CPU supports the feature.
37 | extern WebRtc_CPUInfo WebRtc_GetCPUInfo;
38 |
39 | // No CPU feature is available => straight C path.
40 | extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM;
41 |
42 | // Return the features in an ARM device.
43 | // It detects the features in the hardware platform, and returns supported
44 | // values in the above enum definition as a bitmask.
45 | extern uint64_t WebRtc_GetCPUFeaturesARM(void);
46 |
47 | #if defined(__cplusplus) || defined(c_plusplus)
48 | } // extern "C"
49 | #endif
50 |
51 | #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_
52 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/downsample_fast.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "signal_processing_library.h"
12 |
13 | // TODO(Bjornv): Change the function parameter order to WebRTC code style.
14 | // C version of WebRtcSpl_DownsampleFast() for generic platforms.
15 | int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
16 | int data_in_length,
17 | int16_t* data_out,
18 | int data_out_length,
19 | const int16_t* __restrict coefficients,
20 | int coefficients_length,
21 | int factor,
22 | int delay) {
23 | int i = 0;
24 | int j = 0;
25 | int32_t out_s32 = 0;
26 | int endpos = delay + factor * (data_out_length - 1) + 1;
27 |
28 | // Return error if any of the running conditions doesn't meet.
29 | if (data_out_length <= 0 || coefficients_length <= 0
30 | || data_in_length < endpos) {
31 | return -1;
32 | }
33 |
34 | for (i = delay; i < endpos; i += factor) {
35 | out_s32 = 2048; // Round value, 0.5 in Q12.
36 |
37 | for (j = 0; j < coefficients_length; j++) {
38 | out_s32 += coefficients[j] * data_in[i - j]; // Q12.
39 | }
40 |
41 | out_s32 >>= 12; // Q0.
42 |
43 | // Saturate and store the output.
44 | *data_out++ = WebRtcSpl_SatW32ToW16(out_s32);
45 | }
46 |
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/spl_sqrt_floor.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Written by Wilco Dijkstra, 1996. The following email exchange establishes the
3 | * license.
4 | *
5 | * From: Wilco Dijkstra
6 | * Date: Fri, Jun 24, 2011 at 3:20 AM
7 | * Subject: Re: sqrt routine
8 | * To: Kevin Ma
9 | * Hi Kevin,
10 | * Thanks for asking. Those routines are public domain (originally posted to
11 | * comp.sys.arm a long time ago), so you can use them freely for any purpose.
12 | * Cheers,
13 | * Wilco
14 | *
15 | * ----- Original Message -----
16 | * From: "Kevin Ma"
17 | * To:
18 | * Sent: Thursday, June 23, 2011 11:44 PM
19 | * Subject: Fwd: sqrt routine
20 | * Hi Wilco,
21 | * I saw your sqrt routine from several web sites, including
22 | * http://www.finesse.demon.co.uk/steven/sqrt.html.
23 | * Just wonder if there's any copyright information with your Successive
24 | * approximation routines, or if I can freely use it for any purpose.
25 | * Thanks.
26 | * Kevin
27 | */
28 |
29 | // Minor modifications in code style for WebRTC, 2012.
30 |
31 | #include "signal_processing_library.h"
32 |
33 | /*
34 | * Algorithm:
35 | * Successive approximation of the equation (root + delta) ^ 2 = N
36 | * until delta < 1. If delta < 1 we have the integer part of SQRT (N).
37 | * Use delta = 2^i for i = 15 .. 0.
38 | *
39 | * Output precision is 16 bits. Note for large input values (close to
40 | * 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word)
41 | * contains the MSB information (a non-sign value). Do with caution
42 | * if you need to cast the output to int16_t type.
43 | *
44 | * If the input value is negative, it returns 0.
45 | */
46 |
47 | #define WEBRTC_SPL_SQRT_ITER(N) \
48 | try1 = root + (1 << (N)); \
49 | if (value >= try1 << (N)) \
50 | { \
51 | value -= try1 << (N); \
52 | root |= 2 << (N); \
53 | }
54 |
55 | int32_t WebRtcSpl_SqrtFloor(int32_t value)
56 | {
57 | int32_t root = 0, try1;
58 |
59 | WEBRTC_SPL_SQRT_ITER (15);
60 | WEBRTC_SPL_SQRT_ITER (14);
61 | WEBRTC_SPL_SQRT_ITER (13);
62 | WEBRTC_SPL_SQRT_ITER (12);
63 | WEBRTC_SPL_SQRT_ITER (11);
64 | WEBRTC_SPL_SQRT_ITER (10);
65 | WEBRTC_SPL_SQRT_ITER ( 9);
66 | WEBRTC_SPL_SQRT_ITER ( 8);
67 | WEBRTC_SPL_SQRT_ITER ( 7);
68 | WEBRTC_SPL_SQRT_ITER ( 6);
69 | WEBRTC_SPL_SQRT_ITER ( 5);
70 | WEBRTC_SPL_SQRT_ITER ( 4);
71 | WEBRTC_SPL_SQRT_ITER ( 3);
72 | WEBRTC_SPL_SQRT_ITER ( 2);
73 | WEBRTC_SPL_SQRT_ITER ( 1);
74 | WEBRTC_SPL_SQRT_ITER ( 0);
75 |
76 | return root >> 1;
77 | }
78 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/ring_buffer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // A ring buffer to hold arbitrary data. Provides no thread safety. Unless
12 | // otherwise specified, functions return 0 on success and -1 on error.
13 |
14 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_
15 | #define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_
16 |
17 | #include // size_t
18 |
19 | typedef struct RingBuffer RingBuffer;
20 |
21 | // Returns NULL on failure.
22 | RingBuffer* WebRtc_CreateBuffer(size_t element_count, size_t element_size);
23 | int WebRtc_InitBuffer(RingBuffer* handle);
24 | void WebRtc_FreeBuffer(void* handle);
25 |
26 | // Reads data from the buffer. The |data_ptr| will point to the address where
27 | // it is located. If all |element_count| data are feasible to read without
28 | // buffer wrap around |data_ptr| will point to the location in the buffer.
29 | // Otherwise, the data will be copied to |data| (memory allocation done by the
30 | // user) and |data_ptr| points to the address of |data|. |data_ptr| is only
31 | // guaranteed to be valid until the next call to WebRtc_WriteBuffer().
32 | //
33 | // To force a copying to |data|, pass a NULL |data_ptr|.
34 | //
35 | // Returns number of elements read.
36 | size_t WebRtc_ReadBuffer(RingBuffer* handle,
37 | void** data_ptr,
38 | void* data,
39 | size_t element_count);
40 |
41 | // Writes |data| to buffer and returns the number of elements written.
42 | size_t WebRtc_WriteBuffer(RingBuffer* handle, const void* data,
43 | size_t element_count);
44 |
45 | // Moves the buffer read position and returns the number of elements moved.
46 | // Positive |element_count| moves the read position towards the write position,
47 | // that is, flushing the buffer. Negative |element_count| moves the read
48 | // position away from the the write position, that is, stuffing the buffer.
49 | // Returns number of elements moved.
50 | int WebRtc_MoveReadPtr(RingBuffer* handle, int element_count);
51 |
52 | // Returns number of available elements to read.
53 | size_t WebRtc_available_read(const RingBuffer* handle);
54 |
55 | // Returns number of available elements for write.
56 | size_t WebRtc_available_write(const RingBuffer* handle);
57 |
58 | #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_
59 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/compile_assert.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // Borrowed from Chromium's src/base/basictypes.h.
12 |
13 | #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
14 | #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
15 |
16 | // The COMPILE_ASSERT macro can be used to verify that a compile time
17 | // expression is true. For example, you could use it to verify the
18 | // size of a static array:
19 | //
20 | // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES,
21 | // content_type_names_incorrect_size);
22 | //
23 | // or to make sure a struct is smaller than a certain size:
24 | //
25 | // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
26 | //
27 | // The second argument to the macro is the name of the variable. If
28 | // the expression is false, most compilers will issue a warning/error
29 | // containing the name of the variable.
30 |
31 | // TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
32 | // libjingle are merged.
33 | #if !defined(COMPILE_ASSERT)
34 | template
35 | struct CompileAssert {
36 | };
37 |
38 | #define COMPILE_ASSERT(expr, msg) \
39 | typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
40 | #endif // COMPILE_ASSERT
41 |
42 | // Implementation details of COMPILE_ASSERT:
43 | //
44 | // - COMPILE_ASSERT works by defining an array type that has -1
45 | // elements (and thus is invalid) when the expression is false.
46 | //
47 | // - The simpler definition
48 | //
49 | // #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
50 | //
51 | // does not work, as gcc supports variable-length arrays whose sizes
52 | // are determined at run-time (this is gcc's extension and not part
53 | // of the C++ standard). As a result, gcc fails to reject the
54 | // following code with the simple definition:
55 | //
56 | // int foo;
57 | // COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
58 | // // not a compile-time constant.
59 | //
60 | // - By using the type CompileAssert<(bool(expr))>, we ensures that
61 | // expr is a compile-time constant. (Template arguments must be
62 | // determined at compile-time.)
63 | //
64 | // - The outer parentheses in CompileAssert<(bool(expr))> are necessary
65 | // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
66 | //
67 | // CompileAssert
68 | //
69 | // instead, these compilers will refuse to compile
70 | //
71 | // COMPILE_ASSERT(5 > 0, some_message);
72 | //
73 | // (They seem to think the ">" in "5 > 0" marks the end of the
74 | // template argument list.)
75 | //
76 | // - The array size is (bool(expr) ? 1 : -1), instead of simply
77 | //
78 | // ((expr) ? 1 : -1).
79 | //
80 | // This is to avoid running into a bug in MS VC 7.1, which
81 | // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
82 |
83 | #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
84 |
--------------------------------------------------------------------------------
/eclipse-project/src/com/billhoo/android/aec/demo/DemoActivity.java:
--------------------------------------------------------------------------------
1 | package com.billhoo.android.aec.demo;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileOutputStream;
6 | import java.nio.ByteBuffer;
7 | import java.nio.ByteOrder;
8 |
9 | import android.app.Activity;
10 | import android.os.Bundle;
11 | import android.os.Environment;
12 |
13 | import com.android.webrtc.audio.MobileAEC;
14 | import com.android.webrtc.audio.R;
15 |
16 | /**
17 | * This demo will show you how to use MobileAEC class to deal with echo things
18 | * on android.
19 | *
20 | *
21 | * [NOTICE]
22 | *
23 | * you should add "android.permission.WRITE_EXTERNAL_STORAGE" in your
24 | * AndroidManifest.xml file to allow this DEMO write data into your SDcard.
25 | *
26 | * [TODO List]
27 | *
28 | * -
29 | * (billhoo): should write all the demo processes into separate thread instead
30 | * of the UI thread.
31 | *
32 | *
33 | * @author billhoo E-mail: billhoo@126.com
34 | */
35 | public class DemoActivity extends Activity {
36 | private static final boolean AECM_DEBUG = true;
37 |
38 | @Override
39 | public void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.activity_main);
42 |
43 | if (AECM_DEBUG) {
44 | doAECM();
45 | }
46 | }
47 |
48 | // //////////////////////////////////////////////////////////////////////////
49 | // ACOUSTIC ECHO CANCELLATION MOBILE EDITION
50 |
51 | public void doAECM() {
52 | try {
53 | MobileAEC aecm = new MobileAEC(null);
54 | aecm.setAecmMode(MobileAEC.AggressiveMode.MOST_AGGRESSIVE)
55 | .prepare();
56 |
57 | // get pcm raw data file in root of android sd card.
58 | // if you test this demo, you should put these files into your
59 | // android device or emulator.
60 | // the ideal output of pcm is almost down to zero.
61 | FileInputStream fin = new FileInputStream(new File(
62 | Environment.getExternalStorageDirectory()
63 | + "/en-00-raw-pcm-16000Hz-16bit-mono.pcm"));
64 |
65 | FileOutputStream fout = new FileOutputStream(new File(
66 | Environment.getExternalStorageDirectory()
67 | + "/aecm-output-pcm-16000Hz-16bit-mono.pcm"));
68 |
69 | final int cacheSize = 320;
70 | byte[] pcmInputCache = new byte[cacheSize];
71 |
72 | // core procession
73 | for (/* empty */; fin.read(pcmInputCache, 0, pcmInputCache.length) != -1; /* empty */) {
74 | // convert bytes[] to shorts[], and make it into little endian.
75 | short[] aecTmpIn = new short[cacheSize / 2];
76 | short[] aecTmpOut = new short[cacheSize / 2];
77 | ByteBuffer.wrap(pcmInputCache).order(ByteOrder.LITTLE_ENDIAN)
78 | .asShortBuffer().get(aecTmpIn);
79 |
80 | // aecm procession, for now the echo tail is hard-coded 10ms,
81 | // but you
82 | // should estimate it correctly each time you call
83 | // echoCancellation, otherwise aecm
84 | // cannot work.
85 | aecm.farendBuffer(aecTmpIn, cacheSize / 2);
86 | aecm.echoCancellation(aecTmpIn, null, aecTmpOut,
87 | (short) (cacheSize / 2), (short) 10);
88 |
89 | // output
90 | byte[] aecBuf = new byte[cacheSize];
91 | ByteBuffer.wrap(aecBuf).order(ByteOrder.LITTLE_ENDIAN)
92 | .asShortBuffer().put(aecTmpOut);
93 |
94 | fout.write(aecBuf);
95 | }
96 |
97 | fout.close();
98 | fin.close();
99 | aecm.close();
100 | } catch (Exception e) {
101 | e.printStackTrace();
102 | }
103 | }
104 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | sql/
144 | *.Cache
145 | ClientBin/
146 | [Ss]tyle[Cc]op.*
147 | ~$*
148 | *~
149 | *.dbmdl
150 | *.[Pp]ublish.xml
151 | *.pfx
152 | *.publishsettings
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | App_Data/*.mdf
166 | App_Data/*.ldf
167 |
168 | #############
169 | ## Windows detritus
170 | #############
171 |
172 | # Windows image file caches
173 | Thumbs.db
174 | ehthumbs.db
175 |
176 | # Folder config file
177 | Desktop.ini
178 |
179 | # Recycle Bin used on file shares
180 | $RECYCLE.BIN/
181 |
182 | # Mac crap
183 | .DS_Store
184 |
185 |
186 | #############
187 | ## Python
188 | #############
189 |
190 | *.py[co]
191 |
192 | # Packages
193 | *.egg
194 | *.egg-info
195 | dist/
196 | build/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/typedefs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // This file contains platform-specific typedefs and defines.
12 | // Much of it is derived from Chromium's build/build_config.h.
13 |
14 | #ifndef WEBRTC_TYPEDEFS_H_
15 | #define WEBRTC_TYPEDEFS_H_
16 |
17 | // For access to standard POSIXish features, use WEBRTC_POSIX instead of a
18 | // more specific macro.
19 | #if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) || \
20 | defined(WEBRTC_ANDROID)
21 | #define WEBRTC_POSIX
22 | #endif
23 |
24 | // Processor architecture detection. For more info on what's defined, see:
25 | // http://msdn.microsoft.com/en-us/library/b0084kay.aspx
26 | // http://www.agner.org/optimize/calling_conventions.pdf
27 | // or with gcc, run: "echo | gcc -E -dM -"
28 | #if defined(_M_X64) || defined(__x86_64__)
29 | #define WEBRTC_ARCH_X86_FAMILY
30 | #define WEBRTC_ARCH_X86_64
31 | #define WEBRTC_ARCH_64_BITS
32 | #define WEBRTC_ARCH_LITTLE_ENDIAN
33 | #elif defined(_M_IX86) || defined(__i386__)
34 | #define WEBRTC_ARCH_X86_FAMILY
35 | #define WEBRTC_ARCH_X86
36 | #define WEBRTC_ARCH_32_BITS
37 | #define WEBRTC_ARCH_LITTLE_ENDIAN
38 | #elif defined(__ARMEL__)
39 | // TODO(ajm): We'd prefer to control platform defines here, but this is
40 | // currently provided by the Android makefiles. Commented to avoid duplicate
41 | // definition warnings.
42 | //#define WEBRTC_ARCH_ARM
43 | // TODO(ajm): Chromium uses the following two defines. Should we switch?
44 | //#define WEBRTC_ARCH_ARM_FAMILY
45 | //#define WEBRTC_ARCH_ARMEL
46 | #define WEBRTC_ARCH_32_BITS
47 | #define WEBRTC_ARCH_LITTLE_ENDIAN
48 | #elif defined(__MIPSEL__)
49 | #define WEBRTC_ARCH_32_BITS
50 | #define WEBRTC_ARCH_LITTLE_ENDIAN
51 | #else
52 | #error Please add support for your architecture in typedefs.h
53 | #endif
54 |
55 | #if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN))
56 | #error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN
57 | #endif
58 |
59 | #if defined(__SSE2__) || defined(_MSC_VER)
60 | #define WEBRTC_USE_SSE2
61 | #endif
62 |
63 | #if !defined(_MSC_VER)
64 | #include
65 | #else
66 | // Define C99 equivalent types, since MSVC doesn't provide stdint.h.
67 | typedef signed char int8_t;
68 | typedef signed short int16_t;
69 | typedef signed int int32_t;
70 | typedef __int64 int64_t;
71 | typedef unsigned char uint8_t;
72 | typedef unsigned short uint16_t;
73 | typedef unsigned int uint32_t;
74 | typedef unsigned __int64 uint64_t;
75 | #endif
76 |
77 | // Borrowed from Chromium's base/compiler_specific.h.
78 | // Annotate a virtual method indicating it must be overriding a virtual
79 | // method in the parent class.
80 | // Use like:
81 | // virtual void foo() OVERRIDE;
82 | #if defined(_MSC_VER)
83 | #define OVERRIDE override
84 | #elif defined(__clang__)
85 | // Clang defaults to C++03 and warns about using override. Squelch that.
86 | // Intentionally no push/pop here so all users of OVERRIDE ignore the warning
87 | // too. This is like passing -Wno-c++11-extensions, except that GCC won't die
88 | // (because it won't see this pragma).
89 | #pragma clang diagnostic ignored "-Wc++11-extensions"
90 | #define OVERRIDE override
91 | #else
92 | #define OVERRIDE
93 | #endif
94 |
95 | // Annotate a function indicating the caller must examine the return value.
96 | // Use like:
97 | // int foo() WARN_UNUSED_RESULT;
98 | // TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
99 | // libjingle are merged.
100 | #if !defined(WARN_UNUSED_RESULT)
101 | #if defined(__GNUC__)
102 | #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
103 | #else
104 | #define WARN_UNUSED_RESULT
105 | #endif
106 | #endif // WARN_UNUSED_RESULT
107 |
108 | #endif // WEBRTC_TYPEDEFS_H_
109 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/division_operations.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 |
12 | /*
13 | * This file contains implementations of the divisions
14 | * WebRtcSpl_DivU32U16()
15 | * WebRtcSpl_DivW32W16()
16 | * WebRtcSpl_DivW32W16ResW16()
17 | * WebRtcSpl_DivResultInQ31()
18 | * WebRtcSpl_DivW32HiLow()
19 | *
20 | * The description header can be found in signal_processing_library.h
21 | *
22 | */
23 |
24 | #include "signal_processing_library.h"
25 |
26 | uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den)
27 | {
28 | // Guard against division with 0
29 | if (den != 0)
30 | {
31 | return (uint32_t)(num / den);
32 | } else
33 | {
34 | return (uint32_t)0xFFFFFFFF;
35 | }
36 | }
37 |
38 | int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den)
39 | {
40 | // Guard against division with 0
41 | if (den != 0)
42 | {
43 | return (int32_t)(num / den);
44 | } else
45 | {
46 | return (int32_t)0x7FFFFFFF;
47 | }
48 | }
49 |
50 | int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den)
51 | {
52 | // Guard against division with 0
53 | if (den != 0)
54 | {
55 | return (int16_t)(num / den);
56 | } else
57 | {
58 | return (int16_t)0x7FFF;
59 | }
60 | }
61 |
62 | int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den)
63 | {
64 | int32_t L_num = num;
65 | int32_t L_den = den;
66 | int32_t div = 0;
67 | int k = 31;
68 | int change_sign = 0;
69 |
70 | if (num == 0)
71 | return 0;
72 |
73 | if (num < 0)
74 | {
75 | change_sign++;
76 | L_num = -num;
77 | }
78 | if (den < 0)
79 | {
80 | change_sign++;
81 | L_den = -den;
82 | }
83 | while (k--)
84 | {
85 | div <<= 1;
86 | L_num <<= 1;
87 | if (L_num >= L_den)
88 | {
89 | L_num -= L_den;
90 | div++;
91 | }
92 | }
93 | if (change_sign == 1)
94 | {
95 | div = -div;
96 | }
97 | return div;
98 | }
99 |
100 | int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
101 | {
102 | int16_t approx, tmp_hi, tmp_low, num_hi, num_low;
103 | int32_t tmpW32;
104 |
105 | approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi);
106 | // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
107 |
108 | // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
109 | tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)
110 | + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);
111 | // tmpW32 = den * approx
112 |
113 | tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
114 |
115 | // Store tmpW32 in hi and low format
116 | tmp_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
117 | tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((tmpW32
118 | - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
119 |
120 | // tmpW32 = 1/den in Q29
121 | tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
122 | >> 15)) << 1);
123 |
124 | // 1/den in hi and low format
125 | tmp_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
126 | tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((tmpW32
127 | - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
128 |
129 | // Store num in hi and low format
130 | num_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(num, 16);
131 | num_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((num
132 | - WEBRTC_SPL_LSHIFT_W32((int32_t)num_hi, 16)), 1);
133 |
134 | // num * (1/den) by 32 bit multiplication (result in Q28)
135 |
136 | tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)
137 | >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));
138 |
139 | // Put result in Q31 (convert from Q28)
140 | tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
141 |
142 | return tmpW32;
143 | }
144 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/aecm_defines.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_AECM_DEFINES_H_
12 | #define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_AECM_DEFINES_H_
13 |
14 | #define AECM_DYNAMIC_Q /* Turn on/off dynamic Q-domain. */
15 |
16 | /* Algorithm parameters */
17 | #define FRAME_LEN 80 /* Total frame length, 10 ms. */
18 |
19 | #define PART_LEN 64 /* Length of partition. */
20 | #define PART_LEN_SHIFT 7 /* Length of (PART_LEN * 2) in base 2. */
21 |
22 | #define PART_LEN1 (PART_LEN + 1) /* Unique fft coefficients. */
23 | #define PART_LEN2 (PART_LEN << 1) /* Length of partition * 2. */
24 | #define PART_LEN4 (PART_LEN << 2) /* Length of partition * 4. */
25 | #define FAR_BUF_LEN PART_LEN4 /* Length of buffers. */
26 | #define MAX_DELAY 100
27 |
28 | /* Counter parameters */
29 | #define CONV_LEN 512 /* Convergence length used at startup. */
30 | #define CONV_LEN2 (CONV_LEN << 1) /* Used at startup. */
31 |
32 | /* Energy parameters */
33 | #define MAX_BUF_LEN 64 /* History length of energy signals. */
34 | #define FAR_ENERGY_MIN 1025 /* Lowest Far energy level: At least 2 */
35 | /* in energy. */
36 | #define FAR_ENERGY_DIFF 929 /* Allowed difference between max */
37 | /* and min. */
38 | #define ENERGY_DEV_OFFSET 0 /* The energy error offset in Q8. */
39 | #define ENERGY_DEV_TOL 400 /* The energy estimation tolerance (Q8). */
40 | #define FAR_ENERGY_VAD_REGION 230 /* Far VAD tolerance region. */
41 |
42 | /* Stepsize parameters */
43 | #define MU_MIN 10 /* Min stepsize 2^-MU_MIN (far end energy */
44 | /* dependent). */
45 | #define MU_MAX 1 /* Max stepsize 2^-MU_MAX (far end energy */
46 | /* dependent). */
47 | #define MU_DIFF 9 /* MU_MIN - MU_MAX */
48 |
49 | /* Channel parameters */
50 | #define MIN_MSE_COUNT 20 /* Min number of consecutive blocks with enough */
51 | /* far end energy to compare channel estimates. */
52 | #define MIN_MSE_DIFF 29 /* The ratio between adapted and stored channel to */
53 | /* accept a new storage (0.8 in Q-MSE_RESOLUTION). */
54 | #define MSE_RESOLUTION 5 /* MSE parameter resolution. */
55 | #define RESOLUTION_CHANNEL16 12 /* W16 Channel in Q-RESOLUTION_CHANNEL16. */
56 | #define RESOLUTION_CHANNEL32 28 /* W32 Channel in Q-RESOLUTION_CHANNEL. */
57 | #define CHANNEL_VAD 16 /* Minimum energy in frequency band */
58 | /* to update channel. */
59 |
60 | /* Suppression gain parameters: SUPGAIN parameters in Q-(RESOLUTION_SUPGAIN). */
61 | #define RESOLUTION_SUPGAIN 8 /* Channel in Q-(RESOLUTION_SUPGAIN). */
62 | #define SUPGAIN_DEFAULT (1 << RESOLUTION_SUPGAIN) /* Default. */
63 | #define SUPGAIN_ERROR_PARAM_A 3072 /* Estimation error parameter */
64 | /* (Maximum gain) (8 in Q8). */
65 | #define SUPGAIN_ERROR_PARAM_B 1536 /* Estimation error parameter */
66 | /* (Gain before going down). */
67 | #define SUPGAIN_ERROR_PARAM_D SUPGAIN_DEFAULT /* Estimation error parameter */
68 | /* (Should be the same as Default) (1 in Q8). */
69 | #define SUPGAIN_EPC_DT 200 /* SUPGAIN_ERROR_PARAM_C * ENERGY_DEV_TOL */
70 |
71 | /* Defines for "check delay estimation" */
72 | #define CORR_WIDTH 31 /* Number of samples to correlate over. */
73 | #define CORR_MAX 16 /* Maximum correlation offset. */
74 | #define CORR_MAX_BUF 63
75 | #define CORR_DEV 4
76 | #define CORR_MAX_LEVEL 20
77 | #define CORR_MAX_LOW 4
78 | #define CORR_BUF_LEN (CORR_MAX << 1) + 1
79 | /* Note that CORR_WIDTH + 2*CORR_MAX <= MAX_BUF_LEN. */
80 |
81 | #define ONE_Q14 (1 << 14)
82 |
83 | /* NLP defines */
84 | #define NLP_COMP_LOW 3277 /* 0.2 in Q14 */
85 | #define NLP_COMP_HIGH ONE_Q14 /* 1 in Q14 */
86 |
87 | #endif
88 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/real_fft.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "real_fft.h"
12 |
13 | #include
14 |
15 | #include "signal_processing_library.h"
16 |
17 | struct RealFFT {
18 | int order;
19 | };
20 |
21 | struct RealFFT* WebRtcSpl_CreateRealFFTC(int order) {
22 | struct RealFFT* self = NULL;
23 |
24 | if (order > kMaxFFTOrder || order < 0) {
25 | return NULL;
26 | }
27 |
28 | self = malloc(sizeof(struct RealFFT));
29 | if (self == NULL) {
30 | return NULL;
31 | }
32 | self->order = order;
33 |
34 | return self;
35 | }
36 |
37 | void WebRtcSpl_FreeRealFFTC(struct RealFFT* self) {
38 | if (self != NULL) {
39 | free(self);
40 | }
41 | }
42 |
43 | // The C version FFT functions (i.e. WebRtcSpl_RealForwardFFTC and
44 | // WebRtcSpl_RealInverseFFTC) are real-valued FFT wrappers for complex-valued
45 | // FFT implementation in SPL.
46 |
47 | int WebRtcSpl_RealForwardFFTC(struct RealFFT* self,
48 | const int16_t* real_data_in,
49 | int16_t* complex_data_out) {
50 | int i = 0;
51 | int j = 0;
52 | int result = 0;
53 | int n = 1 << self->order;
54 | // The complex-value FFT implementation needs a buffer to hold 2^order
55 | // 16-bit COMPLEX numbers, for both time and frequency data.
56 | int16_t complex_buffer[2 << kMaxFFTOrder];
57 |
58 | // Insert zeros to the imaginary parts for complex forward FFT input.
59 | for (i = 0, j = 0; i < n; i += 1, j += 2) {
60 | complex_buffer[j] = real_data_in[i];
61 | complex_buffer[j + 1] = 0;
62 | };
63 |
64 | WebRtcSpl_ComplexBitReverse(complex_buffer, self->order);
65 | result = WebRtcSpl_ComplexFFT(complex_buffer, self->order, 1);
66 |
67 | // For real FFT output, use only the first N + 2 elements from
68 | // complex forward FFT.
69 | memcpy(complex_data_out, complex_buffer, sizeof(int16_t) * (n + 2));
70 |
71 | return result;
72 | }
73 |
74 | int WebRtcSpl_RealInverseFFTC(struct RealFFT* self,
75 | const int16_t* complex_data_in,
76 | int16_t* real_data_out) {
77 | int i = 0;
78 | int j = 0;
79 | int result = 0;
80 | int n = 1 << self->order;
81 | // Create the buffer specific to complex-valued FFT implementation.
82 | int16_t complex_buffer[2 << kMaxFFTOrder];
83 |
84 | // For n-point FFT, first copy the first n + 2 elements into complex
85 | // FFT, then construct the remaining n - 2 elements by real FFT's
86 | // conjugate-symmetric properties.
87 | memcpy(complex_buffer, complex_data_in, sizeof(int16_t) * (n + 2));
88 | for (i = n + 2; i < 2 * n; i += 2) {
89 | complex_buffer[i] = complex_data_in[2 * n - i];
90 | complex_buffer[i + 1] = -complex_data_in[2 * n - i + 1];
91 | }
92 |
93 | WebRtcSpl_ComplexBitReverse(complex_buffer, self->order);
94 | result = WebRtcSpl_ComplexIFFT(complex_buffer, self->order, 1);
95 |
96 | // Strip out the imaginary parts of the complex inverse FFT output.
97 | for (i = 0, j = 0; i < n; i += 1, j += 2) {
98 | real_data_out[i] = complex_buffer[j];
99 | }
100 |
101 | return result;
102 | }
103 |
104 | #if defined(WEBRTC_DETECT_ARM_NEON) || defined(WEBRTC_ARCH_ARM_NEON)
105 | // TODO(kma): Replace the following function bodies into optimized functions
106 | // for ARM Neon.
107 | struct RealFFT* WebRtcSpl_CreateRealFFTNeon(int order) {
108 | return WebRtcSpl_CreateRealFFTC(order);
109 | }
110 |
111 | void WebRtcSpl_FreeRealFFTNeon(struct RealFFT* self) {
112 | WebRtcSpl_FreeRealFFTC(self);
113 | }
114 |
115 | int WebRtcSpl_RealForwardFFTNeon(struct RealFFT* self,
116 | const int16_t* real_data_in,
117 | int16_t* complex_data_out) {
118 | return WebRtcSpl_RealForwardFFTC(self, real_data_in, complex_data_out);
119 | }
120 |
121 | int WebRtcSpl_RealInverseFFTNeon(struct RealFFT* self,
122 | const int16_t* complex_data_in,
123 | int16_t* real_data_out) {
124 | return WebRtcSpl_RealInverseFFTC(self, complex_data_in, real_data_out);
125 | }
126 | #endif // WEBRTC_DETECT_ARM_NEON || WEBRTC_ARCH_ARM_NEON
127 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/complex_bit_reverse.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "signal_processing_library.h"
12 |
13 | /* Tables for data buffer indexes that are bit reversed and thus need to be
14 | * swapped. Note that, index_7[{0, 2, 4, ...}] are for the left side of the swap
15 | * operations, while index_7[{1, 3, 5, ...}] are for the right side of the
16 | * operation. Same for index_8.
17 | */
18 |
19 | /* Indexes for the case of stages == 7. */
20 | static const int16_t index_7[112] = {
21 | 1, 64, 2, 32, 3, 96, 4, 16, 5, 80, 6, 48, 7, 112, 9, 72, 10, 40, 11, 104,
22 | 12, 24, 13, 88, 14, 56, 15, 120, 17, 68, 18, 36, 19, 100, 21, 84, 22, 52,
23 | 23, 116, 25, 76, 26, 44, 27, 108, 29, 92, 30, 60, 31, 124, 33, 66, 35, 98,
24 | 37, 82, 38, 50, 39, 114, 41, 74, 43, 106, 45, 90, 46, 58, 47, 122, 49, 70,
25 | 51, 102, 53, 86, 55, 118, 57, 78, 59, 110, 61, 94, 63, 126, 67, 97, 69,
26 | 81, 71, 113, 75, 105, 77, 89, 79, 121, 83, 101, 87, 117, 91, 109, 95, 125,
27 | 103, 115, 111, 123
28 | };
29 |
30 | /* Indexes for the case of stages == 8. */
31 | static const int16_t index_8[240] = {
32 | 1, 128, 2, 64, 3, 192, 4, 32, 5, 160, 6, 96, 7, 224, 8, 16, 9, 144, 10, 80,
33 | 11, 208, 12, 48, 13, 176, 14, 112, 15, 240, 17, 136, 18, 72, 19, 200, 20,
34 | 40, 21, 168, 22, 104, 23, 232, 25, 152, 26, 88, 27, 216, 28, 56, 29, 184,
35 | 30, 120, 31, 248, 33, 132, 34, 68, 35, 196, 37, 164, 38, 100, 39, 228, 41,
36 | 148, 42, 84, 43, 212, 44, 52, 45, 180, 46, 116, 47, 244, 49, 140, 50, 76,
37 | 51, 204, 53, 172, 54, 108, 55, 236, 57, 156, 58, 92, 59, 220, 61, 188, 62,
38 | 124, 63, 252, 65, 130, 67, 194, 69, 162, 70, 98, 71, 226, 73, 146, 74, 82,
39 | 75, 210, 77, 178, 78, 114, 79, 242, 81, 138, 83, 202, 85, 170, 86, 106, 87,
40 | 234, 89, 154, 91, 218, 93, 186, 94, 122, 95, 250, 97, 134, 99, 198, 101,
41 | 166, 103, 230, 105, 150, 107, 214, 109, 182, 110, 118, 111, 246, 113, 142,
42 | 115, 206, 117, 174, 119, 238, 121, 158, 123, 222, 125, 190, 127, 254, 131,
43 | 193, 133, 161, 135, 225, 137, 145, 139, 209, 141, 177, 143, 241, 147, 201,
44 | 149, 169, 151, 233, 155, 217, 157, 185, 159, 249, 163, 197, 167, 229, 171,
45 | 213, 173, 181, 175, 245, 179, 205, 183, 237, 187, 221, 191, 253, 199, 227,
46 | 203, 211, 207, 243, 215, 235, 223, 251, 239, 247
47 | };
48 |
49 | void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages) {
50 | /* For any specific value of stages, we know exactly the indexes that are
51 | * bit reversed. Currently (Feb. 2012) in WebRTC the only possible values of
52 | * stages are 7 and 8, so we use tables to save unnecessary iterations and
53 | * calculations for these two cases.
54 | */
55 | if (stages == 7 || stages == 8) {
56 | int m = 0;
57 | int length = 112;
58 | const int16_t* index = index_7;
59 |
60 | if (stages == 8) {
61 | length = 240;
62 | index = index_8;
63 | }
64 |
65 | /* Decimation in time. Swap the elements with bit-reversed indexes. */
66 | for (m = 0; m < length; m += 2) {
67 | /* We declare a int32_t* type pointer, to load both the 16-bit real
68 | * and imaginary elements from complex_data in one instruction, reducing
69 | * complexity.
70 | */
71 | int32_t* complex_data_ptr = (int32_t*)complex_data;
72 | int32_t temp = 0;
73 |
74 | temp = complex_data_ptr[index[m]]; /* Real and imaginary */
75 | complex_data_ptr[index[m]] = complex_data_ptr[index[m + 1]];
76 | complex_data_ptr[index[m + 1]] = temp;
77 | }
78 | }
79 | else {
80 | int m = 0, mr = 0, l = 0;
81 | int n = 1 << stages;
82 | int nn = n - 1;
83 |
84 | /* Decimation in time - re-order data */
85 | for (m = 1; m <= nn; ++m) {
86 | int32_t* complex_data_ptr = (int32_t*)complex_data;
87 | int32_t temp = 0;
88 |
89 | /* Find out indexes that are bit-reversed. */
90 | l = n;
91 | do {
92 | l >>= 1;
93 | } while (l > nn - mr);
94 | mr = (mr & (l - 1)) + l;
95 |
96 | if (mr <= m) {
97 | continue;
98 | }
99 |
100 | /* Swap the elements with bit-reversed indexes.
101 | * This is similar to the loop in the stages == 7 or 8 cases.
102 | */
103 | temp = complex_data_ptr[m]; /* Real and imaginary */
104 | complex_data_ptr[m] = complex_data_ptr[mr];
105 | complex_data_ptr[mr] = temp;
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/spl_inl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 |
12 | // This header file includes the inline functions in
13 | // the fix point signal processing library.
14 |
15 | #ifndef WEBRTC_SPL_SPL_INL_H_
16 | #define WEBRTC_SPL_SPL_INL_H_
17 |
18 | #ifdef WEBRTC_ARCH_ARM_V7
19 | #include "webrtc/common_audio/signal_processing/include/spl_inl_armv7.h"
20 | #else
21 |
22 | #if defined(MIPS32_LE)
23 | #include "webrtc/common_audio/signal_processing/include/spl_inl_mips.h"
24 | #endif
25 |
26 | #if !defined(MIPS_DSP_R1_LE)
27 | static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
28 | int16_t out16 = (int16_t) value32;
29 |
30 | if (value32 > 32767)
31 | out16 = 32767;
32 | else if (value32 < -32768)
33 | out16 = -32768;
34 |
35 | return out16;
36 | }
37 |
38 | static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
39 | return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b);
40 | }
41 |
42 | static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
43 | return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2);
44 | }
45 | #endif // #if !defined(MIPS_DSP_R1_LE)
46 |
47 | #if !defined(MIPS32_LE)
48 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
49 | int bits;
50 |
51 | if (0xFFFF0000 & n) {
52 | bits = 16;
53 | } else {
54 | bits = 0;
55 | }
56 | if (0x0000FF00 & (n >> bits)) bits += 8;
57 | if (0x000000F0 & (n >> bits)) bits += 4;
58 | if (0x0000000C & (n >> bits)) bits += 2;
59 | if (0x00000002 & (n >> bits)) bits += 1;
60 | if (0x00000001 & (n >> bits)) bits += 1;
61 |
62 | return bits;
63 | }
64 |
65 | static __inline int WebRtcSpl_NormW32(int32_t a) {
66 | int zeros;
67 |
68 | if (a == 0) {
69 | return 0;
70 | }
71 | else if (a < 0) {
72 | a = ~a;
73 | }
74 |
75 | if (!(0xFFFF8000 & a)) {
76 | zeros = 16;
77 | } else {
78 | zeros = 0;
79 | }
80 | if (!(0xFF800000 & (a << zeros))) zeros += 8;
81 | if (!(0xF8000000 & (a << zeros))) zeros += 4;
82 | if (!(0xE0000000 & (a << zeros))) zeros += 2;
83 | if (!(0xC0000000 & (a << zeros))) zeros += 1;
84 |
85 | return zeros;
86 | }
87 |
88 | static __inline int WebRtcSpl_NormU32(uint32_t a) {
89 | int zeros;
90 |
91 | if (a == 0) return 0;
92 |
93 | if (!(0xFFFF0000 & a)) {
94 | zeros = 16;
95 | } else {
96 | zeros = 0;
97 | }
98 | if (!(0xFF000000 & (a << zeros))) zeros += 8;
99 | if (!(0xF0000000 & (a << zeros))) zeros += 4;
100 | if (!(0xC0000000 & (a << zeros))) zeros += 2;
101 | if (!(0x80000000 & (a << zeros))) zeros += 1;
102 |
103 | return zeros;
104 | }
105 |
106 | static __inline int WebRtcSpl_NormW16(int16_t a) {
107 | int zeros;
108 |
109 | if (a == 0) {
110 | return 0;
111 | }
112 | else if (a < 0) {
113 | a = ~a;
114 | }
115 |
116 | if (!(0xFF80 & a)) {
117 | zeros = 8;
118 | } else {
119 | zeros = 0;
120 | }
121 | if (!(0xF800 & (a << zeros))) zeros += 4;
122 | if (!(0xE000 & (a << zeros))) zeros += 2;
123 | if (!(0xC000 & (a << zeros))) zeros += 1;
124 |
125 | return zeros;
126 | }
127 |
128 | static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
129 | return (a * b + c);
130 | }
131 | #endif // #if !defined(MIPS32_LE)
132 |
133 | #endif // WEBRTC_ARCH_ARM_V7
134 |
135 | // The following functions have no optimized versions.
136 | // TODO(kma): Consider saturating add/sub instructions in X86 platform.
137 | #if !defined(MIPS_DSP_R1_LE)
138 | static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
139 | int32_t l_sum;
140 |
141 | // Perform long addition
142 | l_sum = l_var1 + l_var2;
143 |
144 | if (l_var1 < 0) { // Check for underflow.
145 | if ((l_var2 < 0) && (l_sum >= 0)) {
146 | l_sum = (int32_t)0x80000000;
147 | }
148 | } else { // Check for overflow.
149 | if ((l_var2 > 0) && (l_sum < 0)) {
150 | l_sum = (int32_t)0x7FFFFFFF;
151 | }
152 | }
153 |
154 | return l_sum;
155 | }
156 |
157 | static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
158 | int32_t l_diff;
159 |
160 | // Perform subtraction.
161 | l_diff = l_var1 - l_var2;
162 |
163 | if (l_var1 < 0) { // Check for underflow.
164 | if ((l_var2 > 0) && (l_diff > 0)) {
165 | l_diff = (int32_t)0x80000000;
166 | }
167 | } else { // Check for overflow.
168 | if ((l_var2 < 0) && (l_diff < 0)) {
169 | l_diff = (int32_t)0x7FFFFFFF;
170 | }
171 | }
172 |
173 | return l_diff;
174 | }
175 | #endif // #if !defined(MIPS_DSP_R1_LE)
176 |
177 | #endif // WEBRTC_SPL_SPL_INL_H_
178 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/vector_scaling_operations.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 |
12 | /*
13 | * This file contains implementations of the functions
14 | * WebRtcSpl_VectorBitShiftW16()
15 | * WebRtcSpl_VectorBitShiftW32()
16 | * WebRtcSpl_VectorBitShiftW32ToW16()
17 | * WebRtcSpl_ScaleVector()
18 | * WebRtcSpl_ScaleVectorWithSat()
19 | * WebRtcSpl_ScaleAndAddVectors()
20 | * WebRtcSpl_ScaleAndAddVectorsWithRoundC()
21 | */
22 |
23 | #include "signal_processing_library.h"
24 |
25 | void WebRtcSpl_VectorBitShiftW16(int16_t *res, int16_t length,
26 | const int16_t *in, int16_t right_shifts)
27 | {
28 | int i;
29 |
30 | if (right_shifts > 0)
31 | {
32 | for (i = length; i > 0; i--)
33 | {
34 | (*res++) = ((*in++) >> right_shifts);
35 | }
36 | } else
37 | {
38 | for (i = length; i > 0; i--)
39 | {
40 | (*res++) = ((*in++) << (-right_shifts));
41 | }
42 | }
43 | }
44 |
45 | void WebRtcSpl_VectorBitShiftW32(int32_t *out_vector,
46 | int16_t vector_length,
47 | const int32_t *in_vector,
48 | int16_t right_shifts)
49 | {
50 | int i;
51 |
52 | if (right_shifts > 0)
53 | {
54 | for (i = vector_length; i > 0; i--)
55 | {
56 | (*out_vector++) = ((*in_vector++) >> right_shifts);
57 | }
58 | } else
59 | {
60 | for (i = vector_length; i > 0; i--)
61 | {
62 | (*out_vector++) = ((*in_vector++) << (-right_shifts));
63 | }
64 | }
65 | }
66 |
67 | void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out, int length,
68 | const int32_t* in, int right_shifts) {
69 | int i;
70 | int32_t tmp_w32;
71 |
72 | if (right_shifts >= 0) {
73 | for (i = length; i > 0; i--) {
74 | tmp_w32 = (*in++) >> right_shifts;
75 | (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32);
76 | }
77 | } else {
78 | int16_t left_shifts = -right_shifts;
79 | for (i = length; i > 0; i--) {
80 | tmp_w32 = (*in++) << left_shifts;
81 | (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32);
82 | }
83 | }
84 | }
85 |
86 | void WebRtcSpl_ScaleVector(const int16_t *in_vector, int16_t *out_vector,
87 | int16_t gain, int16_t in_vector_length,
88 | int16_t right_shifts)
89 | {
90 | // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
91 | int i;
92 | const int16_t *inptr;
93 | int16_t *outptr;
94 |
95 | inptr = in_vector;
96 | outptr = out_vector;
97 |
98 | for (i = 0; i < in_vector_length; i++)
99 | {
100 | (*outptr++) = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);
101 | }
102 | }
103 |
104 | void WebRtcSpl_ScaleVectorWithSat(const int16_t *in_vector, int16_t *out_vector,
105 | int16_t gain, int16_t in_vector_length,
106 | int16_t right_shifts)
107 | {
108 | // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
109 | int i;
110 | int32_t tmpW32;
111 | const int16_t *inptr;
112 | int16_t *outptr;
113 |
114 | inptr = in_vector;
115 | outptr = out_vector;
116 |
117 | for (i = 0; i < in_vector_length; i++)
118 | {
119 | tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);
120 | (*outptr++) = WebRtcSpl_SatW32ToW16(tmpW32);
121 | }
122 | }
123 |
124 | void WebRtcSpl_ScaleAndAddVectors(const int16_t *in1, int16_t gain1, int shift1,
125 | const int16_t *in2, int16_t gain2, int shift2,
126 | int16_t *out, int vector_length)
127 | {
128 | // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2
129 | int i;
130 | const int16_t *in1ptr;
131 | const int16_t *in2ptr;
132 | int16_t *outptr;
133 |
134 | in1ptr = in1;
135 | in2ptr = in2;
136 | outptr = out;
137 |
138 | for (i = 0; i < vector_length; i++)
139 | {
140 | (*outptr++) = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1)
141 | + (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2);
142 | }
143 | }
144 |
145 | // C version of WebRtcSpl_ScaleAndAddVectorsWithRound() for generic platforms.
146 | int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1,
147 | int16_t in_vector1_scale,
148 | const int16_t* in_vector2,
149 | int16_t in_vector2_scale,
150 | int right_shifts,
151 | int16_t* out_vector,
152 | int length) {
153 | int i = 0;
154 | int round_value = (1 << right_shifts) >> 1;
155 |
156 | if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL ||
157 | length <= 0 || right_shifts < 0) {
158 | return -1;
159 | }
160 |
161 | for (i = 0; i < length; i++) {
162 | out_vector[i] = (int16_t)((
163 | WEBRTC_SPL_MUL_16_16(in_vector1[i], in_vector1_scale)
164 | + WEBRTC_SPL_MUL_16_16(in_vector2[i], in_vector2_scale)
165 | + round_value) >> right_shifts);
166 | }
167 |
168 | return 0;
169 | }
170 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/real_fft.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
12 | #define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
13 |
14 | #include "typedefs.h"
15 |
16 | // For ComplexFFT(), the maximum fft order is 10;
17 | // for OpenMax FFT in ARM, it is 12;
18 | // WebRTC APM uses orders of only 7 and 8.
19 | enum {kMaxFFTOrder = 10};
20 |
21 | struct RealFFT;
22 |
23 | #ifdef __cplusplus
24 | extern "C" {
25 | #endif
26 |
27 | typedef struct RealFFT* (*CreateRealFFT)(int order);
28 | typedef void (*FreeRealFFT)(struct RealFFT* self);
29 | typedef int (*RealForwardFFT)(struct RealFFT* self,
30 | const int16_t* real_data_in,
31 | int16_t* complex_data_out);
32 | typedef int (*RealInverseFFT)(struct RealFFT* self,
33 | const int16_t* complex_data_in,
34 | int16_t* real_data_out);
35 |
36 | extern CreateRealFFT WebRtcSpl_CreateRealFFT;
37 | extern FreeRealFFT WebRtcSpl_FreeRealFFT;
38 | extern RealForwardFFT WebRtcSpl_RealForwardFFT;
39 | extern RealInverseFFT WebRtcSpl_RealInverseFFT;
40 |
41 | struct RealFFT* WebRtcSpl_CreateRealFFTC(int order);
42 | void WebRtcSpl_FreeRealFFTC(struct RealFFT* self);
43 |
44 | #if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
45 | struct RealFFT* WebRtcSpl_CreateRealFFTNeon(int order);
46 | void WebRtcSpl_FreeRealFFTNeon(struct RealFFT* self);
47 | #endif
48 |
49 | // Compute an FFT for a real-valued signal of length of 2^order,
50 | // where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
51 | // specification structure, which must be initialized prior to calling the FFT
52 | // function with WebRtcSpl_CreateRealFFT().
53 | // The relationship between the input and output sequences can
54 | // be expressed in terms of the DFT, i.e.:
55 | // x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
56 | // n=0,1,2,...N-1
57 | // N=2^order.
58 | // The conjugate-symmetric output sequence is represented using a CCS vector,
59 | // which is of length N+2, and is organized as follows:
60 | // Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1
61 | // Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0
62 | // where R[n] and I[n], respectively, denote the real and imaginary components
63 | // for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length.
64 | // Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
65 | // the foldover frequency.
66 | //
67 | // Input Arguments:
68 | // self - pointer to preallocated and initialized FFT specification structure.
69 | // real_data_in - the input signal. For an ARM Neon platform, it must be
70 | // aligned on a 32-byte boundary.
71 | //
72 | // Output Arguments:
73 | // complex_data_out - the output complex signal with (2^order + 2) 16-bit
74 | // elements. For an ARM Neon platform, it must be different
75 | // from real_data_in, and aligned on a 32-byte boundary.
76 | //
77 | // Return Value:
78 | // 0 - FFT calculation is successful.
79 | // -1 - Error with bad arguments (NULL pointers).
80 | int WebRtcSpl_RealForwardFFTC(struct RealFFT* self,
81 | const int16_t* real_data_in,
82 | int16_t* complex_data_out);
83 |
84 | #if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
85 | int WebRtcSpl_RealForwardFFTNeon(struct RealFFT* self,
86 | const int16_t* real_data_in,
87 | int16_t* complex_data_out);
88 | #endif
89 |
90 | // Compute the inverse FFT for a conjugate-symmetric input sequence of length of
91 | // 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
92 | // the specification structure, which must be initialized prior to calling the
93 | // FFT function with WebRtcSpl_CreateRealFFT().
94 | // For a transform of length M, the input sequence is represented using a packed
95 | // CCS vector of length M+2, which is explained in the comments for
96 | // WebRtcSpl_RealForwardFFTC above.
97 | //
98 | // Input Arguments:
99 | // self - pointer to preallocated and initialized FFT specification structure.
100 | // complex_data_in - the input complex signal with (2^order + 2) 16-bit
101 | // elements. For an ARM Neon platform, it must be aligned on
102 | // a 32-byte boundary.
103 | //
104 | // Output Arguments:
105 | // real_data_out - the output real signal. For an ARM Neon platform, it must
106 | // be different to complex_data_in, and aligned on a 32-byte
107 | // boundary.
108 | //
109 | // Return Value:
110 | // 0 or a positive number - a value that the elements in the |real_data_out|
111 | // should be shifted left with in order to get
112 | // correct physical values.
113 | // -1 - Error with bad arguments (NULL pointers).
114 | int WebRtcSpl_RealInverseFFTC(struct RealFFT* self,
115 | const int16_t* complex_data_in,
116 | int16_t* real_data_out);
117 |
118 | #if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
119 | int WebRtcSpl_RealInverseFFTNeon(struct RealFFT* self,
120 | const int16_t* complex_data_in,
121 | int16_t* real_data_out);
122 | #endif
123 |
124 | #ifdef __cplusplus
125 | }
126 | #endif
127 |
128 | #endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
129 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/spl_init.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | /* The global function contained in this file initializes SPL function
12 | * pointers, currently only for ARM platforms.
13 | *
14 | * Some code came from common/rtcd.c in the WebM project.
15 | */
16 |
17 | #include "real_fft.h"
18 | #include "signal_processing_library.h"
19 | #include "cpu_features_wrapper.h"
20 |
21 | /* Declare function pointers. */
22 | MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
23 | MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
24 | MaxValueW16 WebRtcSpl_MaxValueW16;
25 | MaxValueW32 WebRtcSpl_MaxValueW32;
26 | MinValueW16 WebRtcSpl_MinValueW16;
27 | MinValueW32 WebRtcSpl_MinValueW32;
28 | CrossCorrelation WebRtcSpl_CrossCorrelation;
29 | DownsampleFast WebRtcSpl_DownsampleFast;
30 | ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
31 | CreateRealFFT WebRtcSpl_CreateRealFFT;
32 | FreeRealFFT WebRtcSpl_FreeRealFFT;
33 | RealForwardFFT WebRtcSpl_RealForwardFFT;
34 | RealInverseFFT WebRtcSpl_RealInverseFFT;
35 |
36 | #if (defined(WEBRTC_DETECT_ARM_NEON) || !defined(WEBRTC_ARCH_ARM_NEON)) && \
37 | !defined(MIPS32_LE)
38 | /* Initialize function pointers to the generic C version. */
39 | static void InitPointersToC() {
40 | WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C;
41 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
42 | WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C;
43 | WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C;
44 | WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C;
45 | WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C;
46 | WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC;
47 | WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC;
48 | WebRtcSpl_ScaleAndAddVectorsWithRound =
49 | WebRtcSpl_ScaleAndAddVectorsWithRoundC;
50 | WebRtcSpl_CreateRealFFT = WebRtcSpl_CreateRealFFTC;
51 | WebRtcSpl_FreeRealFFT = WebRtcSpl_FreeRealFFTC;
52 | WebRtcSpl_RealForwardFFT = WebRtcSpl_RealForwardFFTC;
53 | WebRtcSpl_RealInverseFFT = WebRtcSpl_RealInverseFFTC;
54 | }
55 | #endif
56 |
57 | #if defined(WEBRTC_DETECT_ARM_NEON) || defined(WEBRTC_ARCH_ARM_NEON)
58 | /* Initialize function pointers to the Neon version. */
59 | static void InitPointersToNeon() {
60 | WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon;
61 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon;
62 | WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon;
63 | WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon;
64 | WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon;
65 | WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon;
66 | WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationNeon;
67 | WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon;
68 | WebRtcSpl_ScaleAndAddVectorsWithRound =
69 | WebRtcSpl_ScaleAndAddVectorsWithRoundNeon;
70 | WebRtcSpl_CreateRealFFT = WebRtcSpl_CreateRealFFTNeon;
71 | WebRtcSpl_FreeRealFFT = WebRtcSpl_FreeRealFFTNeon;
72 | WebRtcSpl_RealForwardFFT = WebRtcSpl_RealForwardFFTNeon;
73 | WebRtcSpl_RealInverseFFT = WebRtcSpl_RealInverseFFTNeon;
74 | }
75 | #endif
76 |
77 | #if defined(MIPS32_LE)
78 | /* Initialize function pointers to the MIPS version. */
79 | static void InitPointersToMIPS() {
80 | WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips;
81 | WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips;
82 | WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips;
83 | WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips;
84 | WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips;
85 | WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelation_mips;
86 | WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips;
87 | WebRtcSpl_CreateRealFFT = WebRtcSpl_CreateRealFFTC;
88 | WebRtcSpl_FreeRealFFT = WebRtcSpl_FreeRealFFTC;
89 | WebRtcSpl_RealForwardFFT = WebRtcSpl_RealForwardFFTC;
90 | WebRtcSpl_RealInverseFFT = WebRtcSpl_RealInverseFFTC;
91 | #if defined(MIPS_DSP_R1_LE)
92 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32_mips;
93 | WebRtcSpl_ScaleAndAddVectorsWithRound =
94 | WebRtcSpl_ScaleAndAddVectorsWithRound_mips;
95 | #else
96 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
97 | WebRtcSpl_ScaleAndAddVectorsWithRound =
98 | WebRtcSpl_ScaleAndAddVectorsWithRoundC;
99 | #endif
100 | }
101 | #endif
102 |
103 | static void InitFunctionPointers(void) {
104 | #if defined(WEBRTC_DETECT_ARM_NEON)
105 | if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
106 | InitPointersToNeon();
107 | } else {
108 | InitPointersToC();
109 | }
110 | #elif defined(WEBRTC_ARCH_ARM_NEON)
111 | InitPointersToNeon();
112 | #elif defined(MIPS32_LE)
113 | InitPointersToMIPS();
114 | #else
115 | InitPointersToC();
116 | #endif /* WEBRTC_DETECT_ARM_NEON */
117 | }
118 |
119 | #if defined(WEBRTC_POSIX)
120 | #include
121 |
122 | static void once(void (*func)(void)) {
123 | static pthread_once_t lock = PTHREAD_ONCE_INIT;
124 | pthread_once(&lock, func);
125 | }
126 |
127 | #elif defined(_WIN32)
128 | #include
129 |
130 | static void once(void (*func)(void)) {
131 | /* Didn't use InitializeCriticalSection() since there's no race-free context
132 | * in which to execute it.
133 | *
134 | * TODO(kma): Change to different implementation (e.g.
135 | * InterlockedCompareExchangePointer) to avoid issues similar to
136 | * http://code.google.com/p/webm/issues/detail?id=467.
137 | */
138 | static CRITICAL_SECTION lock = {(void *)((size_t)-1), -1, 0, 0, 0, 0};
139 | static int done = 0;
140 |
141 | EnterCriticalSection(&lock);
142 | if (!done) {
143 | func();
144 | done = 1;
145 | }
146 | LeaveCriticalSection(&lock);
147 | }
148 |
149 | /* There's no fallback version as an #else block here to ensure thread safety.
150 | * In case of neither pthread for WEBRTC_POSIX nor _WIN32 is present, build
151 | * system should pick it up.
152 | */
153 | #endif /* WEBRTC_POSIX */
154 |
155 | void WebRtcSpl_Init() {
156 | once(InitFunctionPointers);
157 | }
158 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/min_max_operations.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | /*
12 | * This file contains the implementation of functions
13 | * WebRtcSpl_MaxAbsValueW16C()
14 | * WebRtcSpl_MaxAbsValueW32C()
15 | * WebRtcSpl_MaxValueW16C()
16 | * WebRtcSpl_MaxValueW32C()
17 | * WebRtcSpl_MinValueW16C()
18 | * WebRtcSpl_MinValueW32C()
19 | * WebRtcSpl_MaxAbsIndexW16()
20 | * WebRtcSpl_MaxIndexW16()
21 | * WebRtcSpl_MaxIndexW32()
22 | * WebRtcSpl_MinIndexW16()
23 | * WebRtcSpl_MinIndexW32()
24 | *
25 | */
26 |
27 | #include "signal_processing_library.h"
28 |
29 | #include
30 |
31 | // TODO(bjorn/kma): Consolidate function pairs (e.g. combine
32 | // WebRtcSpl_MaxAbsValueW16C and WebRtcSpl_MaxAbsIndexW16 into a single one.)
33 | // TODO(kma): Move the next six functions into min_max_operations_c.c.
34 |
35 | // Maximum absolute value of word16 vector. C version for generic platforms.
36 | int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, int length) {
37 | int i = 0, absolute = 0, maximum = 0;
38 |
39 | if (vector == NULL || length <= 0) {
40 | return -1;
41 | }
42 |
43 | for (i = 0; i < length; i++) {
44 | absolute = abs((int)vector[i]);
45 |
46 | if (absolute > maximum) {
47 | maximum = absolute;
48 | }
49 | }
50 |
51 | // Guard the case for abs(-32768).
52 | if (maximum > WEBRTC_SPL_WORD16_MAX) {
53 | maximum = WEBRTC_SPL_WORD16_MAX;
54 | }
55 |
56 | return (int16_t)maximum;
57 | }
58 |
59 | // Maximum absolute value of word32 vector. C version for generic platforms.
60 | int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, int length) {
61 | // Use uint32_t for the local variables, to accommodate the return value
62 | // of abs(0x80000000), which is 0x80000000.
63 |
64 | uint32_t absolute = 0, maximum = 0;
65 | int i = 0;
66 |
67 | if (vector == NULL || length <= 0) {
68 | return -1;
69 | }
70 |
71 | for (i = 0; i < length; i++) {
72 | absolute = abs((int)vector[i]);
73 | if (absolute > maximum) {
74 | maximum = absolute;
75 | }
76 | }
77 |
78 | maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX);
79 |
80 | return (int32_t)maximum;
81 | }
82 |
83 | // Maximum value of word16 vector. C version for generic platforms.
84 | int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, int length) {
85 | int16_t maximum = WEBRTC_SPL_WORD16_MIN;
86 | int i = 0;
87 |
88 | if (vector == NULL || length <= 0) {
89 | return maximum;
90 | }
91 |
92 | for (i = 0; i < length; i++) {
93 | if (vector[i] > maximum)
94 | maximum = vector[i];
95 | }
96 | return maximum;
97 | }
98 |
99 | // Maximum value of word32 vector. C version for generic platforms.
100 | int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, int length) {
101 | int32_t maximum = WEBRTC_SPL_WORD32_MIN;
102 | int i = 0;
103 |
104 | if (vector == NULL || length <= 0) {
105 | return maximum;
106 | }
107 |
108 | for (i = 0; i < length; i++) {
109 | if (vector[i] > maximum)
110 | maximum = vector[i];
111 | }
112 | return maximum;
113 | }
114 |
115 | // Minimum value of word16 vector. C version for generic platforms.
116 | int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, int length) {
117 | int16_t minimum = WEBRTC_SPL_WORD16_MAX;
118 | int i = 0;
119 |
120 | if (vector == NULL || length <= 0) {
121 | return minimum;
122 | }
123 |
124 | for (i = 0; i < length; i++) {
125 | if (vector[i] < minimum)
126 | minimum = vector[i];
127 | }
128 | return minimum;
129 | }
130 |
131 | // Minimum value of word32 vector. C version for generic platforms.
132 | int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, int length) {
133 | int32_t minimum = WEBRTC_SPL_WORD32_MAX;
134 | int i = 0;
135 |
136 | if (vector == NULL || length <= 0) {
137 | return minimum;
138 | }
139 |
140 | for (i = 0; i < length; i++) {
141 | if (vector[i] < minimum)
142 | minimum = vector[i];
143 | }
144 | return minimum;
145 | }
146 |
147 | // Index of maximum absolute value in a word16 vector.
148 | int WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, int length) {
149 | // Use type int for local variables, to accomodate the value of abs(-32768).
150 |
151 | int i = 0, absolute = 0, maximum = 0, index = 0;
152 |
153 | if (vector == NULL || length <= 0) {
154 | return -1;
155 | }
156 |
157 | for (i = 0; i < length; i++) {
158 | absolute = abs((int)vector[i]);
159 |
160 | if (absolute > maximum) {
161 | maximum = absolute;
162 | index = i;
163 | }
164 | }
165 |
166 | return index;
167 | }
168 |
169 | // Index of maximum value in a word16 vector.
170 | int WebRtcSpl_MaxIndexW16(const int16_t* vector, int length) {
171 | int i = 0, index = 0;
172 | int16_t maximum = WEBRTC_SPL_WORD16_MIN;
173 |
174 | if (vector == NULL || length <= 0) {
175 | return -1;
176 | }
177 |
178 | for (i = 0; i < length; i++) {
179 | if (vector[i] > maximum) {
180 | maximum = vector[i];
181 | index = i;
182 | }
183 | }
184 |
185 | return index;
186 | }
187 |
188 | // Index of maximum value in a word32 vector.
189 | int WebRtcSpl_MaxIndexW32(const int32_t* vector, int length) {
190 | int i = 0, index = 0;
191 | int32_t maximum = WEBRTC_SPL_WORD32_MIN;
192 |
193 | if (vector == NULL || length <= 0) {
194 | return -1;
195 | }
196 |
197 | for (i = 0; i < length; i++) {
198 | if (vector[i] > maximum) {
199 | maximum = vector[i];
200 | index = i;
201 | }
202 | }
203 |
204 | return index;
205 | }
206 |
207 | // Index of minimum value in a word16 vector.
208 | int WebRtcSpl_MinIndexW16(const int16_t* vector, int length) {
209 | int i = 0, index = 0;
210 | int16_t minimum = WEBRTC_SPL_WORD16_MAX;
211 |
212 | if (vector == NULL || length <= 0) {
213 | return -1;
214 | }
215 |
216 | for (i = 0; i < length; i++) {
217 | if (vector[i] < minimum) {
218 | minimum = vector[i];
219 | index = i;
220 | }
221 | }
222 |
223 | return index;
224 | }
225 |
226 | // Index of minimum value in a word32 vector.
227 | int WebRtcSpl_MinIndexW32(const int32_t* vector, int length) {
228 | int i = 0, index = 0;
229 | int32_t minimum = WEBRTC_SPL_WORD32_MAX;
230 |
231 | if (vector == NULL || length <= 0) {
232 | return -1;
233 | }
234 |
235 | for (i = 0; i < length; i++) {
236 | if (vector[i] < minimum) {
237 | minimum = vector[i];
238 | index = i;
239 | }
240 | }
241 |
242 | return index;
243 | }
244 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/randomization_functions.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 |
12 | /*
13 | * This file contains implementations of the randomization functions
14 | * WebRtcSpl_IncreaseSeed()
15 | * WebRtcSpl_RandU()
16 | * WebRtcSpl_RandN()
17 | * WebRtcSpl_RandUArray()
18 | *
19 | * The description header can be found in signal_processing_library.h
20 | *
21 | */
22 |
23 | #include "signal_processing_library.h"
24 |
25 | static const int16_t kRandNTable[] = {
26 | 9178, -7260, 40, 10189, 4894, -3531, -13779, 14764,
27 | -4008, -8884, -8990, 1008, 7368, 5184, 3251, -5817,
28 | -9786, 5963, 1770, 8066, -7135, 10772, -2298, 1361,
29 | 6484, 2241, -8633, 792, 199, -3344, 6553, -10079,
30 | -15040, 95, 11608, -12469, 14161, -4176, 2476, 6403,
31 | 13685, -16005, 6646, 2239, 10916, -3004, -602, -3141,
32 | 2142, 14144, -5829, 5305, 8209, 4713, 2697, -5112,
33 | 16092, -1210, -2891, -6631, -5360, -11878, -6781, -2739,
34 | -6392, 536, 10923, 10872, 5059, -4748, -7770, 5477,
35 | 38, -1025, -2892, 1638, 6304, 14375, -11028, 1553,
36 | -1565, 10762, -393, 4040, 5257, 12310, 6554, -4799,
37 | 4899, -6354, 1603, -1048, -2220, 8247, -186, -8944,
38 | -12004, 2332, 4801, -4933, 6371, 131, 8614, -5927,
39 | -8287, -22760, 4033, -15162, 3385, 3246, 3153, -5250,
40 | 3766, 784, 6494, -62, 3531, -1582, 15572, 662,
41 | -3952, -330, -3196, 669, 7236, -2678, -6569, 23319,
42 | -8645, -741, 14830, -15976, 4903, 315, -11342, 10311,
43 | 1858, -7777, 2145, 5436, 5677, -113, -10033, 826,
44 | -1353, 17210, 7768, 986, -1471, 8291, -4982, 8207,
45 | -14911, -6255, -2449, -11881, -7059, -11703, -4338, 8025,
46 | 7538, -2823, -12490, 9470, -1613, -2529, -10092, -7807,
47 | 9480, 6970, -12844, 5123, 3532, 4816, 4803, -8455,
48 | -5045, 14032, -4378, -1643, 5756, -11041, -2732, -16618,
49 | -6430, -18375, -3320, 6098, 5131, -4269, -8840, 2482,
50 | -7048, 1547, -21890, -6505, -7414, -424, -11722, 7955,
51 | 1653, -17299, 1823, 473, -9232, 3337, 1111, 873,
52 | 4018, -8982, 9889, 3531, -11763, -3799, 7373, -4539,
53 | 3231, 7054, -8537, 7616, 6244, 16635, 447, -2915,
54 | 13967, 705, -2669, -1520, -1771, -16188, 5956, 5117,
55 | 6371, -9936, -1448, 2480, 5128, 7550, -8130, 5236,
56 | 8213, -6443, 7707, -1950, -13811, 7218, 7031, -3883,
57 | 67, 5731, -2874, 13480, -3743, 9298, -3280, 3552,
58 | -4425, -18, -3785, -9988, -5357, 5477, -11794, 2117,
59 | 1416, -9935, 3376, 802, -5079, -8243, 12652, 66,
60 | 3653, -2368, 6781, -21895, -7227, 2487, 7839, -385,
61 | 6646, -7016, -4658, 5531, -1705, 834, 129, 3694,
62 | -1343, 2238, -22640, -6417, -11139, 11301, -2945, -3494,
63 | -5626, 185, -3615, -2041, -7972, -3106, -60, -23497,
64 | -1566, 17064, 3519, 2518, 304, -6805, -10269, 2105,
65 | 1936, -426, -736, -8122, -1467, 4238, -6939, -13309,
66 | 360, 7402, -7970, 12576, 3287, 12194, -6289, -16006,
67 | 9171, 4042, -9193, 9123, -2512, 6388, -4734, -8739,
68 | 1028, -5406, -1696, 5889, -666, -4736, 4971, 3565,
69 | 9362, -6292, 3876, -3652, -19666, 7523, -4061, 391,
70 | -11773, 7502, -3763, 4929, -9478, 13278, 2805, 4496,
71 | 7814, 16419, 12455, -14773, 2127, -2746, 3763, 4847,
72 | 3698, 6978, 4751, -6957, -3581, -45, 6252, 1513,
73 | -4797, -7925, 11270, 16188, -2359, -5269, 9376, -10777,
74 | 7262, 20031, -6515, -2208, -5353, 8085, -1341, -1303,
75 | 7333, 5576, 3625, 5763, -7931, 9833, -3371, -10305,
76 | 6534, -13539, -9971, 997, 8464, -4064, -1495, 1857,
77 | 13624, 5458, 9490, -11086, -4524, 12022, -550, -198,
78 | 408, -8455, -7068, 10289, 9712, -3366, 9028, -7621,
79 | -5243, 2362, 6909, 4672, -4933, -1799, 4709, -4563,
80 | -62, -566, 1624, -7010, 14730, -17791, -3697, -2344,
81 | -1741, 7099, -9509, -6855, -1989, 3495, -2289, 2031,
82 | 12784, 891, 14189, -3963, -5683, 421, -12575, 1724,
83 | -12682, -5970, -8169, 3143, -1824, -5488, -5130, 8536,
84 | 12799, 794, 5738, 3459, -11689, -258, -3738, -3775,
85 | -8742, 2333, 8312, -9383, 10331, 13119, 8398, 10644,
86 | -19433, -6446, -16277, -11793, 16284, 9345, 15222, 15834,
87 | 2009, -7349, 130, -14547, 338, -5998, 3337, 21492,
88 | 2406, 7703, -951, 11196, -564, 3406, 2217, 4806,
89 | 2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492
90 | };
91 |
92 | uint32_t WebRtcSpl_IncreaseSeed(uint32_t *seed)
93 | {
94 | seed[0] = (seed[0] * ((int32_t)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1);
95 | return seed[0];
96 | }
97 |
98 | int16_t WebRtcSpl_RandU(uint32_t *seed)
99 | {
100 | return (int16_t)(WebRtcSpl_IncreaseSeed(seed) >> 16);
101 | }
102 |
103 | int16_t WebRtcSpl_RandN(uint32_t *seed)
104 | {
105 | return kRandNTable[WebRtcSpl_IncreaseSeed(seed) >> 23];
106 | }
107 |
108 | // Creates an array of uniformly distributed variables
109 | int16_t WebRtcSpl_RandUArray(int16_t* vector,
110 | int16_t vector_length,
111 | uint32_t* seed)
112 | {
113 | int i;
114 | for (i = 0; i < vector_length; i++)
115 | {
116 | vector[i] = WebRtcSpl_RandU(seed);
117 | }
118 | return vector_length;
119 | }
120 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/ring_buffer.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // A ring buffer to hold arbitrary data. Provides no thread safety. Unless
12 | // otherwise specified, functions return 0 on success and -1 on error.
13 |
14 | #include "ring_buffer.h"
15 |
16 | #include // size_t
17 | #include
18 | #include
19 |
20 | enum Wrap {
21 | SAME_WRAP,
22 | DIFF_WRAP
23 | };
24 |
25 | struct RingBuffer {
26 | size_t read_pos;
27 | size_t write_pos;
28 | size_t element_count;
29 | size_t element_size;
30 | enum Wrap rw_wrap;
31 | char* data;
32 | };
33 |
34 | // Get address of region(s) from which we can read data.
35 | // If the region is contiguous, |data_ptr_bytes_2| will be zero.
36 | // If non-contiguous, |data_ptr_bytes_2| will be the size in bytes of the second
37 | // region. Returns room available to be read or |element_count|, whichever is
38 | // smaller.
39 | static size_t GetBufferReadRegions(RingBuffer* buf,
40 | size_t element_count,
41 | void** data_ptr_1,
42 | size_t* data_ptr_bytes_1,
43 | void** data_ptr_2,
44 | size_t* data_ptr_bytes_2) {
45 |
46 | const size_t readable_elements = WebRtc_available_read(buf);
47 | const size_t read_elements = (readable_elements < element_count ?
48 | readable_elements : element_count);
49 | const size_t margin = buf->element_count - buf->read_pos;
50 |
51 | // Check to see if read is not contiguous.
52 | if (read_elements > margin) {
53 | // Write data in two blocks that wrap the buffer.
54 | *data_ptr_1 = buf->data + buf->read_pos * buf->element_size;
55 | *data_ptr_bytes_1 = margin * buf->element_size;
56 | *data_ptr_2 = buf->data;
57 | *data_ptr_bytes_2 = (read_elements - margin) * buf->element_size;
58 | } else {
59 | *data_ptr_1 = buf->data + buf->read_pos * buf->element_size;
60 | *data_ptr_bytes_1 = read_elements * buf->element_size;
61 | *data_ptr_2 = NULL;
62 | *data_ptr_bytes_2 = 0;
63 | }
64 |
65 | return read_elements;
66 | }
67 |
68 | RingBuffer* WebRtc_CreateBuffer(size_t element_count, size_t element_size) {
69 | RingBuffer* self = NULL;
70 | if (element_count == 0 || element_size == 0) {
71 | return NULL;
72 | }
73 |
74 | self = malloc(sizeof(RingBuffer));
75 | if (!self) {
76 | return NULL;
77 | }
78 |
79 | self->data = malloc(element_count * element_size);
80 | if (!self->data) {
81 | free(self);
82 | self = NULL;
83 | return NULL;
84 | }
85 |
86 | self->element_count = element_count;
87 | self->element_size = element_size;
88 |
89 | return self;
90 | }
91 |
92 | int WebRtc_InitBuffer(RingBuffer* self) {
93 | if (!self) {
94 | return -1;
95 | }
96 |
97 | self->read_pos = 0;
98 | self->write_pos = 0;
99 | self->rw_wrap = SAME_WRAP;
100 |
101 | // Initialize buffer to zeros
102 | memset(self->data, 0, self->element_count * self->element_size);
103 |
104 | return 0;
105 | }
106 |
107 | void WebRtc_FreeBuffer(void* handle) {
108 | RingBuffer* self = (RingBuffer*)handle;
109 | if (!self) {
110 | return;
111 | }
112 |
113 | free(self->data);
114 | free(self);
115 | }
116 |
117 | size_t WebRtc_ReadBuffer(RingBuffer* self,
118 | void** data_ptr,
119 | void* data,
120 | size_t element_count) {
121 |
122 | if (self == NULL) {
123 | return 0;
124 | }
125 | if (data == NULL) {
126 | return 0;
127 | }
128 |
129 | {
130 | void* buf_ptr_1 = NULL;
131 | void* buf_ptr_2 = NULL;
132 | size_t buf_ptr_bytes_1 = 0;
133 | size_t buf_ptr_bytes_2 = 0;
134 | const size_t read_count = GetBufferReadRegions(self,
135 | element_count,
136 | &buf_ptr_1,
137 | &buf_ptr_bytes_1,
138 | &buf_ptr_2,
139 | &buf_ptr_bytes_2);
140 |
141 | if (buf_ptr_bytes_2 > 0) {
142 | // We have a wrap around when reading the buffer. Copy the buffer data to
143 | // |data| and point to it.
144 | memcpy(data, buf_ptr_1, buf_ptr_bytes_1);
145 | memcpy(((char*) data) + buf_ptr_bytes_1, buf_ptr_2, buf_ptr_bytes_2);
146 | buf_ptr_1 = data;
147 | } else if (!data_ptr) {
148 | // No wrap, but a memcpy was requested.
149 | memcpy(data, buf_ptr_1, buf_ptr_bytes_1);
150 | }
151 | if (data_ptr) {
152 | // |buf_ptr_1| == |data| in the case of a wrap.
153 | *data_ptr = buf_ptr_1;
154 | }
155 |
156 | // Update read position
157 | WebRtc_MoveReadPtr(self, (int) read_count);
158 |
159 | return read_count;
160 | }
161 | }
162 |
163 | size_t WebRtc_WriteBuffer(RingBuffer* self,
164 | const void* data,
165 | size_t element_count) {
166 | if (!self) {
167 | return 0;
168 | }
169 | if (!data) {
170 | return 0;
171 | }
172 |
173 | {
174 | const size_t free_elements = WebRtc_available_write(self);
175 | const size_t write_elements = (free_elements < element_count ? free_elements
176 | : element_count);
177 | size_t n = write_elements;
178 | const size_t margin = self->element_count - self->write_pos;
179 |
180 | if (write_elements > margin) {
181 | // Buffer wrap around when writing.
182 | memcpy(self->data + self->write_pos * self->element_size,
183 | data, margin * self->element_size);
184 | self->write_pos = 0;
185 | n -= margin;
186 | self->rw_wrap = DIFF_WRAP;
187 | }
188 | memcpy(self->data + self->write_pos * self->element_size,
189 | ((const char*) data) + ((write_elements - n) * self->element_size),
190 | n * self->element_size);
191 | self->write_pos += n;
192 |
193 | return write_elements;
194 | }
195 | }
196 |
197 | int WebRtc_MoveReadPtr(RingBuffer* self, int element_count) {
198 | if (!self) {
199 | return 0;
200 | }
201 |
202 | {
203 | // We need to be able to take care of negative changes, hence use "int"
204 | // instead of "size_t".
205 | const int free_elements = (int) WebRtc_available_write(self);
206 | const int readable_elements = (int) WebRtc_available_read(self);
207 | int read_pos = (int) self->read_pos;
208 |
209 | if (element_count > readable_elements) {
210 | element_count = readable_elements;
211 | }
212 | if (element_count < -free_elements) {
213 | element_count = -free_elements;
214 | }
215 |
216 | read_pos += element_count;
217 | if (read_pos > (int) self->element_count) {
218 | // Buffer wrap around. Restart read position and wrap indicator.
219 | read_pos -= (int) self->element_count;
220 | self->rw_wrap = SAME_WRAP;
221 | }
222 | if (read_pos < 0) {
223 | // Buffer wrap around. Restart read position and wrap indicator.
224 | read_pos += (int) self->element_count;
225 | self->rw_wrap = DIFF_WRAP;
226 | }
227 |
228 | self->read_pos = (size_t) read_pos;
229 |
230 | return element_count;
231 | }
232 | }
233 |
234 | size_t WebRtc_available_read(const RingBuffer* self) {
235 | if (!self) {
236 | return 0;
237 | }
238 |
239 | if (self->rw_wrap == SAME_WRAP) {
240 | return self->write_pos - self->read_pos;
241 | } else {
242 | return self->element_count - self->read_pos + self->write_pos;
243 | }
244 | }
245 |
246 | size_t WebRtc_available_write(const RingBuffer* self) {
247 | if (!self) {
248 | return 0;
249 | }
250 |
251 | return self->element_count - WebRtc_available_read(self);
252 | }
253 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/delay_estimator_wrapper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // Performs delay estimation on block by block basis.
12 | // The return value is 0 - OK and -1 - Error, unless otherwise stated.
13 |
14 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
15 | #define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
16 |
17 | #include "typedefs.h"
18 |
19 | // Releases the memory allocated by WebRtc_CreateDelayEstimatorFarend(...)
20 | // Input:
21 | // - handle : Pointer to the delay estimation far-end instance.
22 | //
23 | void WebRtc_FreeDelayEstimatorFarend(void* handle);
24 |
25 | // Allocates the memory needed by the far-end part of the delay estimation. The
26 | // memory needs to be initialized separately through
27 | // WebRtc_InitDelayEstimatorFarend(...).
28 | //
29 | // Inputs:
30 | // - spectrum_size : Size of the spectrum used both in far-end and
31 | // near-end. Used to allocate memory for spectrum
32 | // specific buffers.
33 | // - history_size : The far-end history buffer size. Note that the maximum
34 | // delay which can be estimated is controlled together
35 | // with |lookahead| through
36 | // WebRtc_CreateDelayEstimator().
37 | //
38 | // Return value:
39 | // - void* : Created |handle|. If the memory can't be allocated or
40 | // if any of the input parameters are invalid NULL is
41 | // returned.
42 | //
43 | void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size);
44 |
45 | // Initializes the far-end part of the delay estimation instance returned by
46 | // WebRtc_CreateDelayEstimatorFarend(...)
47 | // Input:
48 | // - handle : Pointer to the delay estimation far-end instance.
49 | //
50 | // Output:
51 | // - handle : Initialized instance.
52 | //
53 | int WebRtc_InitDelayEstimatorFarend(void* handle);
54 |
55 | // Adds the far-end spectrum to the far-end history buffer. This spectrum is
56 | // used as reference when calculating the delay using
57 | // WebRtc_ProcessSpectrum().
58 | //
59 | // Inputs:
60 | // - handle : Pointer to the delay estimation far-end instance.
61 | // - far_spectrum : Far-end spectrum.
62 | // - spectrum_size : The size of the data arrays (same for both far- and
63 | // near-end).
64 | // - far_q : The Q-domain of the far-end data.
65 | //
66 | // Output:
67 | // - handle : Updated far-end instance.
68 | //
69 | int WebRtc_AddFarSpectrumFix(void* handle, uint16_t* far_spectrum,
70 | int spectrum_size, int far_q);
71 |
72 | // See WebRtc_AddFarSpectrumFix() for description.
73 | int WebRtc_AddFarSpectrumFloat(void* handle, float* far_spectrum,
74 | int spectrum_size);
75 |
76 | // Releases the memory allocated by WebRtc_CreateDelayEstimator(...)
77 | // Input:
78 | // - handle : Pointer to the delay estimation instance.
79 | //
80 | void WebRtc_FreeDelayEstimator(void* handle);
81 |
82 | // Allocates the memory needed by the delay estimation. The memory needs to be
83 | // initialized separately through WebRtc_InitDelayEstimator(...).
84 | //
85 | // Inputs:
86 | // - farend_handle : Pointer to the far-end part of the delay estimation
87 | // instance created prior to this call using
88 | // WebRtc_CreateDelayEstimatorFarend().
89 | //
90 | // Note that WebRtc_CreateDelayEstimator does not take
91 | // ownership of |farend_handle|, which has to be torn
92 | // down properly after this instance.
93 | //
94 | // - lookahead : Amount of non-causal lookahead to use. This can
95 | // detect cases in which a near-end signal occurs before
96 | // the corresponding far-end signal. It will delay the
97 | // estimate for the current block by an equal amount,
98 | // and the returned values will be offset by it.
99 | //
100 | // A value of zero is the typical no-lookahead case.
101 | // This also represents the minimum delay which can be
102 | // estimated.
103 | //
104 | // Note that the effective range of delay estimates is
105 | // [-|lookahead|,... ,|history_size|-|lookahead|)
106 | // where |history_size| was set upon creating the far-end
107 | // history buffer size.
108 | //
109 | // Return value:
110 | // - void* : Created |handle|. If the memory can't be allocated or
111 | // if any of the input parameters are invalid NULL is
112 | // returned.
113 | //
114 | void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead);
115 |
116 | // Initializes the delay estimation instance returned by
117 | // WebRtc_CreateDelayEstimator(...)
118 | // Input:
119 | // - handle : Pointer to the delay estimation instance.
120 | //
121 | // Output:
122 | // - handle : Initialized instance.
123 | //
124 | int WebRtc_InitDelayEstimator(void* handle);
125 |
126 | // Estimates and returns the delay between the far-end and near-end blocks. The
127 | // value will be offset by the lookahead (i.e. the lookahead should be
128 | // subtracted from the returned value).
129 | // Inputs:
130 | // - handle : Pointer to the delay estimation instance.
131 | // - near_spectrum : Pointer to the near-end spectrum data of the current
132 | // block.
133 | // - spectrum_size : The size of the data arrays (same for both far- and
134 | // near-end).
135 | // - near_q : The Q-domain of the near-end data.
136 | //
137 | // Output:
138 | // - handle : Updated instance.
139 | //
140 | // Return value:
141 | // - delay : >= 0 - Calculated delay value.
142 | // -1 - Error.
143 | // -2 - Insufficient data for estimation.
144 | //
145 | int WebRtc_DelayEstimatorProcessFix(void* handle,
146 | uint16_t* near_spectrum,
147 | int spectrum_size,
148 | int near_q);
149 |
150 | // See WebRtc_DelayEstimatorProcessFix() for description.
151 | int WebRtc_DelayEstimatorProcessFloat(void* handle,
152 | float* near_spectrum,
153 | int spectrum_size);
154 |
155 | // Returns the last calculated delay updated by the function
156 | // WebRtc_DelayEstimatorProcess(...).
157 | //
158 | // Input:
159 | // - handle : Pointer to the delay estimation instance.
160 | //
161 | // Return value:
162 | // - delay : >= 0 - Last calculated delay value.
163 | // -1 - Error.
164 | // -2 - Insufficient data for estimation.
165 | //
166 | int WebRtc_last_delay(void* handle);
167 |
168 | // Returns the estimation quality/probability of the last calculated delay
169 | // updated by the function WebRtc_DelayEstimatorProcess(...). The estimation
170 | // quality is a value in the interval [0, 1] in Q9. The higher the value, the
171 | // better quality.
172 | //
173 | // Input:
174 | // - handle : Pointer to the delay estimation instance.
175 | //
176 | // Return value:
177 | // - delay_quality : >= 0 - Estimation quality (in Q9) of last calculated
178 | // delay value.
179 | // -1 - Error.
180 | // -2 - Insufficient data for estimation.
181 | //
182 | int WebRtc_last_delay_quality(void* handle);
183 |
184 | #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
185 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/delay_estimator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // Performs delay estimation on binary converted spectra.
12 | // The return value is 0 - OK and -1 - Error, unless otherwise stated.
13 |
14 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
15 | #define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
16 |
17 | #include "typedefs.h"
18 |
19 | typedef struct {
20 | // Pointer to bit counts.
21 | int* far_bit_counts;
22 | // Binary history variables.
23 | uint32_t* binary_far_history;
24 | int history_size;
25 | } BinaryDelayEstimatorFarend;
26 |
27 | typedef struct {
28 | // Pointer to bit counts.
29 | int32_t* mean_bit_counts;
30 | // Array only used locally in ProcessBinarySpectrum() but whose size is
31 | // determined at run-time.
32 | int32_t* bit_counts;
33 |
34 | // Binary history variables.
35 | uint32_t* binary_near_history;
36 | int near_history_size;
37 |
38 | // Delay estimation variables.
39 | int32_t minimum_probability;
40 | int last_delay_probability;
41 |
42 | // Delay memory.
43 | int last_delay;
44 |
45 | // Far-end binary spectrum history buffer etc.
46 | BinaryDelayEstimatorFarend* farend;
47 | } BinaryDelayEstimator;
48 |
49 | // Releases the memory allocated by
50 | // WebRtc_CreateBinaryDelayEstimatorFarend(...).
51 | // Input:
52 | // - self : Pointer to the binary delay estimation far-end
53 | // instance which is the return value of
54 | // WebRtc_CreateBinaryDelayEstimatorFarend().
55 | //
56 | void WebRtc_FreeBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self);
57 |
58 | // Allocates the memory needed by the far-end part of the binary delay
59 | // estimation. The memory needs to be initialized separately through
60 | // WebRtc_InitBinaryDelayEstimatorFarend(...).
61 | //
62 | // Inputs:
63 | // - history_size : Size of the far-end binary spectrum history.
64 | //
65 | // Return value:
66 | // - BinaryDelayEstimatorFarend*
67 | // : Created |handle|. If the memory can't be allocated
68 | // or if any of the input parameters are invalid NULL
69 | // is returned.
70 | //
71 | BinaryDelayEstimatorFarend* WebRtc_CreateBinaryDelayEstimatorFarend(
72 | int history_size);
73 |
74 | // Initializes the delay estimation far-end instance created with
75 | // WebRtc_CreateBinaryDelayEstimatorFarend(...).
76 | //
77 | // Input:
78 | // - self : Pointer to the delay estimation far-end instance.
79 | //
80 | // Output:
81 | // - self : Initialized far-end instance.
82 | //
83 | void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self);
84 |
85 | // Adds the binary far-end spectrum to the internal far-end history buffer. This
86 | // spectrum is used as reference when calculating the delay using
87 | // WebRtc_ProcessBinarySpectrum().
88 | //
89 | // Inputs:
90 | // - self : Pointer to the delay estimation far-end
91 | // instance.
92 | // - binary_far_spectrum : Far-end binary spectrum.
93 | //
94 | // Output:
95 | // - self : Updated far-end instance.
96 | //
97 | void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* self,
98 | uint32_t binary_far_spectrum);
99 |
100 | // Releases the memory allocated by WebRtc_CreateBinaryDelayEstimator(...).
101 | //
102 | // Note that BinaryDelayEstimator utilizes BinaryDelayEstimatorFarend, but does
103 | // not take ownership of it, hence the BinaryDelayEstimator has to be torn down
104 | // before the far-end.
105 | //
106 | // Input:
107 | // - self : Pointer to the binary delay estimation instance
108 | // which is the return value of
109 | // WebRtc_CreateBinaryDelayEstimator().
110 | //
111 | void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self);
112 |
113 | // Allocates the memory needed by the binary delay estimation. The memory needs
114 | // to be initialized separately through WebRtc_InitBinaryDelayEstimator(...).
115 | //
116 | // Inputs:
117 | // - farend : Pointer to the far-end part of the Binary Delay
118 | // Estimator. This memory has to be created separately
119 | // prior to this call using
120 | // WebRtc_CreateBinaryDelayEstimatorFarend().
121 | //
122 | // Note that BinaryDelayEstimator does not take
123 | // ownership of |farend|.
124 | //
125 | // - lookahead : Amount of non-causal lookahead to use. This can
126 | // detect cases in which a near-end signal occurs before
127 | // the corresponding far-end signal. It will delay the
128 | // estimate for the current block by an equal amount,
129 | // and the returned values will be offset by it.
130 | //
131 | // A value of zero is the typical no-lookahead case.
132 | // This also represents the minimum delay which can be
133 | // estimated.
134 | //
135 | // Note that the effective range of delay estimates is
136 | // [-|lookahead|,... ,|history_size|-|lookahead|)
137 | // where |history_size| was set upon creating the far-end
138 | // history buffer size.
139 | //
140 | // Return value:
141 | // - BinaryDelayEstimator*
142 | // : Created |handle|. If the memory can't be allocated
143 | // or if any of the input parameters are invalid NULL
144 | // is returned.
145 | //
146 | BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
147 | BinaryDelayEstimatorFarend* farend, int lookahead);
148 |
149 | // Initializes the delay estimation instance created with
150 | // WebRtc_CreateBinaryDelayEstimator(...).
151 | //
152 | // Input:
153 | // - self : Pointer to the delay estimation instance.
154 | //
155 | // Output:
156 | // - self : Initialized instance.
157 | //
158 | void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self);
159 |
160 | // Estimates and returns the delay between the binary far-end and binary near-
161 | // end spectra. It is assumed the binary far-end spectrum has been added using
162 | // WebRtc_AddBinaryFarSpectrum() prior to this call. The value will be offset by
163 | // the lookahead (i.e. the lookahead should be subtracted from the returned
164 | // value).
165 | //
166 | // Inputs:
167 | // - self : Pointer to the delay estimation instance.
168 | // - binary_near_spectrum : Near-end binary spectrum of the current block.
169 | //
170 | // Output:
171 | // - self : Updated instance.
172 | //
173 | // Return value:
174 | // - delay : >= 0 - Calculated delay value.
175 | // -2 - Insufficient data for estimation.
176 | //
177 | int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self,
178 | uint32_t binary_near_spectrum);
179 |
180 | // Returns the last calculated delay updated by the function
181 | // WebRtc_ProcessBinarySpectrum(...).
182 | //
183 | // Input:
184 | // - self : Pointer to the delay estimation instance.
185 | //
186 | // Return value:
187 | // - delay : >= 0 - Last calculated delay value
188 | // -2 - Insufficient data for estimation.
189 | //
190 | int WebRtc_binary_last_delay(BinaryDelayEstimator* self);
191 |
192 | // Returns the estimation quality of the last calculated delay updated by the
193 | // function WebRtc_ProcessBinarySpectrum(...). The estimation quality is a value
194 | // in the interval [0, 1] in Q14. The higher the value, the better quality.
195 | //
196 | // Input:
197 | // - self : Pointer to the delay estimation instance.
198 | //
199 | // Return value:
200 | // - delay_quality : >= 0 - Estimation quality (in Q14) of last
201 | // calculated delay value.
202 | // -2 - Insufficient data for estimation.
203 | //
204 | int WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self);
205 |
206 | // Updates the |mean_value| recursively with a step size of 2^-|factor|. This
207 | // function is used internally in the Binary Delay Estimator as well as the
208 | // Fixed point wrapper.
209 | //
210 | // Inputs:
211 | // - new_value : The new value the mean should be updated with.
212 | // - factor : The step size, in number of right shifts.
213 | //
214 | // Input/Output:
215 | // - mean_value : Pointer to the mean value.
216 | //
217 | void WebRtc_MeanEstimatorFix(int32_t new_value,
218 | int factor,
219 | int32_t* mean_value);
220 |
221 |
222 | #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
223 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/complex_fft_tables.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 |
12 | #ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
13 | #define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
14 |
15 | #include "typedefs.h"
16 |
17 | static const int16_t kSinTable1024[] = {
18 | 0, 201, 402, 603, 804, 1005, 1206, 1406,
19 | 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
20 | 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
21 | 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
22 | 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
23 | 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
24 | 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
25 | 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
26 | 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
27 | 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
28 | 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
29 | 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
30 | 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
31 | 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
32 | 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
33 | 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
34 | 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
35 | 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
36 | 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
37 | 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
38 | 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
39 | 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
40 | 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
41 | 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
42 | 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
43 | 30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297,
44 | 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
45 | 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
46 | 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
47 | 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
48 | 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
49 | 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
50 | 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
51 | 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
52 | 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
53 | 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
54 | 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
55 | 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
56 | 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
57 | 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
58 | 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
59 | 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
60 | 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
61 | 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
62 | 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
63 | 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
64 | 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
65 | 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
66 | 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
67 | 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
68 | 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
69 | 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
70 | 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
71 | 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
72 | 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
73 | 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
74 | 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
75 | 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
76 | 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
77 | 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
78 | 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
79 | 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
80 | 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
81 | 1607, 1406, 1206, 1005, 804, 603, 402, 201,
82 | 0, -201, -402, -603, -804, -1005, -1206, -1406,
83 | -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011,
84 | -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608,
85 | -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195,
86 | -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766,
87 | -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319,
88 | -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849,
89 | -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
90 | -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
91 | -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
92 | -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
93 | -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
94 | -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
95 | -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
96 | -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
97 | -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
98 | -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
99 | -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
100 | -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
101 | -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
102 | -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
103 | -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
104 | -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
105 | -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
106 | -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
107 | -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
108 | -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
109 | -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
110 | -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
111 | -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
112 | -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
113 | -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
114 | -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736,
115 | -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628,
116 | -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
117 | -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176,
118 | -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833,
119 | -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413,
120 | -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918,
121 | -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349,
122 | -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706,
123 | -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992,
124 | -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208,
125 | -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
126 | -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437,
127 | -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456,
128 | -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413,
129 | -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311,
130 | -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153,
131 | -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942,
132 | -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680,
133 | -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371,
134 | -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
135 | -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623,
136 | -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191,
137 | -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724,
138 | -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227,
139 | -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703,
140 | -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156,
141 | -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589,
142 | -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006,
143 | -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
144 | -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808,
145 | -1607, -1406, -1206, -1005, -804, -603, -402, -201
146 | };
147 |
148 | #endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
149 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/echo_control_mobile.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_INCLUDE_ECHO_CONTROL_MOBILE_H_
12 | #define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_INCLUDE_ECHO_CONTROL_MOBILE_H_
13 |
14 | #include
15 |
16 | #include "typedefs.h"
17 |
18 | enum {
19 | AecmFalse = 0,
20 | AecmTrue
21 | };
22 |
23 | // Errors
24 | #define AECM_UNSPECIFIED_ERROR 12000
25 | #define AECM_UNSUPPORTED_FUNCTION_ERROR 12001
26 | #define AECM_UNINITIALIZED_ERROR 12002
27 | #define AECM_NULL_POINTER_ERROR 12003
28 | #define AECM_BAD_PARAMETER_ERROR 12004
29 |
30 | // Warnings
31 | #define AECM_BAD_PARAMETER_WARNING 12100
32 |
33 | typedef struct {
34 | int16_t cngMode; // AECM_FALSE, AECM_TRUE (default)
35 | int16_t echoMode; // 0, 1, 2, 3 (default), 4
36 | } AecmConfig;
37 |
38 | #ifdef __cplusplus
39 | extern "C" {
40 | #endif
41 |
42 | /*
43 | * Allocates the memory needed by the AECM. The memory needs to be
44 | * initialized separately using the WebRtcAecm_Init() function.
45 | *
46 | * Inputs Description
47 | * -------------------------------------------------------------------
48 | * void **aecmInst Pointer to the AECM instance to be
49 | * created and initialized
50 | *
51 | * Outputs Description
52 | * -------------------------------------------------------------------
53 | * int32_t return 0: OK
54 | * -1: error
55 | */
56 | int32_t WebRtcAecm_Create(void **aecmInst);
57 |
58 | /*
59 | * This function releases the memory allocated by WebRtcAecm_Create()
60 | *
61 | * Inputs Description
62 | * -------------------------------------------------------------------
63 | * void *aecmInst Pointer to the AECM instance
64 | *
65 | * Outputs Description
66 | * -------------------------------------------------------------------
67 | * int32_t return 0: OK
68 | * -1: error
69 | */
70 | int32_t WebRtcAecm_Free(void *aecmInst);
71 |
72 | /*
73 | * Initializes an AECM instance.
74 | *
75 | * Inputs Description
76 | * -------------------------------------------------------------------
77 | * void *aecmInst Pointer to the AECM instance
78 | * int32_t sampFreq Sampling frequency of data
79 | *
80 | * Outputs Description
81 | * -------------------------------------------------------------------
82 | * int32_t return 0: OK
83 | * -1: error
84 | */
85 | int32_t WebRtcAecm_Init(void* aecmInst, int32_t sampFreq);
86 |
87 | /*
88 | * Inserts an 80 or 160 sample block of data into the farend buffer.
89 | *
90 | * Inputs Description
91 | * -------------------------------------------------------------------
92 | * void *aecmInst Pointer to the AECM instance
93 | * int16_t *farend In buffer containing one frame of
94 | * farend signal
95 | * int16_t nrOfSamples Number of samples in farend buffer
96 | *
97 | * Outputs Description
98 | * -------------------------------------------------------------------
99 | * int32_t return 0: OK
100 | * -1: error
101 | */
102 | int32_t WebRtcAecm_BufferFarend(void* aecmInst,
103 | const int16_t* farend,
104 | int16_t nrOfSamples);
105 |
106 | /*
107 | * Runs the AECM on an 80 or 160 sample blocks of data.
108 | *
109 | * Inputs Description
110 | * -------------------------------------------------------------------
111 | * void *aecmInst Pointer to the AECM instance
112 | * int16_t *nearendNoisy In buffer containing one frame of
113 | * reference nearend+echo signal. If
114 | * noise reduction is active, provide
115 | * the noisy signal here.
116 | * int16_t *nearendClean In buffer containing one frame of
117 | * nearend+echo signal. If noise
118 | * reduction is active, provide the
119 | * clean signal here. Otherwise pass a
120 | * NULL pointer.
121 | * int16_t nrOfSamples Number of samples in nearend buffer
122 | * int16_t msInSndCardBuf Delay estimate for sound card and
123 | * system buffers
124 | *
125 | * Outputs Description
126 | * -------------------------------------------------------------------
127 | * int16_t *out Out buffer, one frame of processed nearend
128 | * int32_t return 0: OK
129 | * -1: error
130 | */
131 | int32_t WebRtcAecm_Process(void* aecmInst,
132 | const int16_t* nearendNoisy,
133 | const int16_t* nearendClean,
134 | int16_t* out,
135 | int16_t nrOfSamples,
136 | int16_t msInSndCardBuf);
137 |
138 | /*
139 | * This function enables the user to set certain parameters on-the-fly
140 | *
141 | * Inputs Description
142 | * -------------------------------------------------------------------
143 | * void *aecmInst Pointer to the AECM instance
144 | * AecmConfig config Config instance that contains all
145 | * properties to be set
146 | *
147 | * Outputs Description
148 | * -------------------------------------------------------------------
149 | * int32_t return 0: OK
150 | * -1: error
151 | */
152 | int32_t WebRtcAecm_set_config(void* aecmInst, AecmConfig config);
153 |
154 | /*
155 | * This function enables the user to set certain parameters on-the-fly
156 | *
157 | * Inputs Description
158 | * -------------------------------------------------------------------
159 | * void *aecmInst Pointer to the AECM instance
160 | *
161 | * Outputs Description
162 | * -------------------------------------------------------------------
163 | * AecmConfig *config Pointer to the config instance that
164 | * all properties will be written to
165 | * int32_t return 0: OK
166 | * -1: error
167 | */
168 | int32_t WebRtcAecm_get_config(void *aecmInst, AecmConfig *config);
169 |
170 | /*
171 | * This function enables the user to set the echo path on-the-fly.
172 | *
173 | * Inputs Description
174 | * -------------------------------------------------------------------
175 | * void* aecmInst Pointer to the AECM instance
176 | * void* echo_path Pointer to the echo path to be set
177 | * size_t size_bytes Size in bytes of the echo path
178 | *
179 | * Outputs Description
180 | * -------------------------------------------------------------------
181 | * int32_t return 0: OK
182 | * -1: error
183 | */
184 | int32_t WebRtcAecm_InitEchoPath(void* aecmInst,
185 | const void* echo_path,
186 | size_t size_bytes);
187 |
188 | /*
189 | * This function enables the user to get the currently used echo path
190 | * on-the-fly
191 | *
192 | * Inputs Description
193 | * -------------------------------------------------------------------
194 | * void* aecmInst Pointer to the AECM instance
195 | * void* echo_path Pointer to echo path
196 | * size_t size_bytes Size in bytes of the echo path
197 | *
198 | * Outputs Description
199 | * -------------------------------------------------------------------
200 | * int32_t return 0: OK
201 | * -1: error
202 | */
203 | int32_t WebRtcAecm_GetEchoPath(void* aecmInst,
204 | void* echo_path,
205 | size_t size_bytes);
206 |
207 | /*
208 | * This function enables the user to get the echo path size in bytes
209 | *
210 | * Outputs Description
211 | * -------------------------------------------------------------------
212 | * size_t return : size in bytes
213 | */
214 | size_t WebRtcAecm_echo_path_size_bytes();
215 |
216 | /*
217 | * Gets the last error code.
218 | *
219 | * Inputs Description
220 | * -------------------------------------------------------------------
221 | * void *aecmInst Pointer to the AECM instance
222 | *
223 | * Outputs Description
224 | * -------------------------------------------------------------------
225 | * int32_t return 11000-11100: error code
226 | */
227 | int32_t WebRtcAecm_get_error_code(void *aecmInst);
228 |
229 | #ifdef __cplusplus
230 | }
231 | #endif
232 | #endif // WEBRTC_MODULES_AUDIO_PROCESSING_AECM_INCLUDE_ECHO_CONTROL_MOBILE_H_
233 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/aecm_wrapper.c:
--------------------------------------------------------------------------------
1 | /**
2 | * These are wrappers of native webrtc echo cancellation mobile edition functions.
3 | *
4 | *@author billhoo E-mail: billhoo@126.com
5 | *@version 0.1 2013-3-8
6 | */
7 | #include
8 | #include // for NULL
9 | #include
10 | #include
11 |
12 | /**
13 | * This function is a wrapper which wraps the WebRtcAecm_Create function in WebRtc echo_control_mobile.c
14 | * Allocates the memory needed by the AECM. The memory needs to be initialized
15 | * separately using the WebRtcAecm_Init() function.
16 | *
17 | * Inputs:
18 | * NONE
19 | * Outputs:
20 | * NONE
21 | * Returns:
22 | * -1: error
23 | * other values: created AECM instance handler.
24 | *
25 | */JNIEXPORT jint JNICALL
26 | Java_com_android_webrtc_audio_MobileAEC_nativeCreateAecmInstance(JNIEnv *env,
27 | jclass jclazz) {
28 | void *aecmInstHandler = NULL;
29 | if (WebRtcAecm_Create(&aecmInstHandler) == -1)
30 | return -1;
31 | else
32 | return ((int) aecmInstHandler); //returns the pointer which points to created AECM instance to JAVA layer.
33 | }
34 |
35 | /**
36 | * This is a wrapper wraps WebRtcAecm_Free function in echo_control_mobile.c
37 | * This function releases the memory allocated by WebRtcAecm_Create().
38 | *
39 | * Inputs:
40 | * aecmHandler - handler of the AECM instance created by nativeCreateAecmInstance()
41 | * Outputs:
42 | * NONE
43 | * Returns 0: OK
44 | * -1: error
45 | *
46 | */
47 | JNIEXPORT jint
48 | JNICALL Java_com_android_webrtc_audio_MobileAEC_nativeFreeAecmInstance(
49 | JNIEnv *env, jclass jclazz, jint aecmHandler) {
50 | void *aecmInst = (void *) aecmHandler;
51 | if (aecmInst == NULL)
52 | return -1;
53 | int ret = WebRtcAecm_Free(aecmInst);
54 | aecmInst = NULL;
55 | return ret;
56 | }
57 |
58 | /**
59 | * This wrapper wraps the WebRtcAecm_Init() function in WebRtc echo_control_mobile.c
60 | * Initializes an AECM instance.
61 | *
62 | * Inputs:
63 | * aecmHandler - Handler of AECM instance
64 | * sampFreq - Sampling frequency of data
65 | * Outputs:
66 | * NONE
67 | * Return: 0: OK
68 | * -1: error
69 | *
70 | */
71 | JNIEXPORT jint
72 | JNICALL Java_com_android_webrtc_audio_MobileAEC_nativeInitializeAecmInstance(
73 | JNIEnv *env, jclass jclazz, jint aecmHandler, jint sampFreq) {
74 | void *aecmInst = (void *) aecmHandler;
75 | if (aecmInst == NULL)
76 | return -1;
77 | return WebRtcAecm_Init(aecmInst, sampFreq);
78 | }
79 |
80 | /**
81 | * This wrapper wraps the WebRtcAecm_BufferFarend function in echo_control_mobile.c
82 | * Inserts an 80 or 160 sample block of data into the farend buffer.
83 | *
84 | * Inputs:
85 | * aecmHandler - Handler to the AECM instance
86 | * farend - In buffer containing one frame of farend signal for L band
87 | * nrOfSamples - Number of samples in farend buffer
88 | * Outputs:
89 | * NONE
90 | * Return: 0: OK
91 | * -1: error
92 | *
93 | */
94 | JNIEXPORT jint JNICALL Java_com_android_webrtc_audio_MobileAEC_nativeBufferFarend(
95 | JNIEnv *env, jclass jclazz, jint aecmHandler, jshortArray farend,
96 | jint nrOfSamples) {
97 | void *aecmInst = (void *) aecmHandler;
98 | if (aecmInst == NULL)
99 | return -1;
100 |
101 | int ret = -1;
102 | if (farend != NULL) {
103 | short *arrFarend = (*env)->GetShortArrayElements(env, farend, NULL);
104 | ret = WebRtcAecm_BufferFarend(aecmInst, arrFarend, nrOfSamples);
105 |
106 | //TODO(billhoo) should use JNI_ABORT instead of 0 in 4th param.
107 | //I think there is no need to copy this array back to Java layer.
108 | (*env)->ReleaseShortArrayElements(env, farend, arrFarend, 0);
109 | }
110 | return ret;
111 | }
112 |
113 | /**
114 | * This wrapper wraps the WebRtcAecm_Process in echo_control_mobile.c
115 | * Runs the AECM on an 80 or 160 sample blocks of data.
116 | *
117 | * Inputs:
118 | * aecmHandler - Handler to the AECM handler
119 | * nearendNoisy - In buffer containing one frame of reference nearend+echo signal.
120 | * If noise reduction is active, provide the noisy signal here.
121 | * nearendClean - In buffer containing one frame of nearend+echo signal.
122 | * If noise reduction is active, provide the clean signal here.
123 | * Otherwise pass a NULL pointer.
124 | * nrOfSamples - Number of samples in nearend buffer
125 | * msInSndCardBuf - Delay estimate for sound card and system buffers
126 | * Outputs:
127 | * out - Out buffer, one frame of processed nearend.
128 | * Return: 0: OK
129 | * -1: error
130 | *
131 | */
132 | JNIEXPORT jint JNICALL Java_com_android_webrtc_audio_MobileAEC_nativeAecmProcess(
133 | JNIEnv *env, jclass jclazz, jint aecmHandler,
134 | const jshortArray nearendNoisy, const jshortArray nearendClean,
135 | jshortArray out, jshort nrOfSamples, jshort msInSndCardBuf) {
136 |
137 | int16_t *arrNearendNoisy = NULL;
138 | int16_t *arrNearendClean = NULL;
139 | int16_t *arrOut = NULL;
140 |
141 | void *aecmInst = (void *) aecmHandler;
142 | if (aecmInst == NULL)
143 | return -1;
144 |
145 | int ret = -1;
146 |
147 | //nearendNoisy and out must not be NULL, otherwise process can not be run, return -1 for error.
148 | if (nearendNoisy == NULL || out == NULL)
149 | return ret;
150 |
151 | //get data from java side.
152 | arrNearendNoisy = (*env)->GetShortArrayElements(env, nearendNoisy, NULL);
153 | arrOut = (*env)->GetShortArrayElements(env, out, NULL);
154 |
155 | if (nearendClean != NULL)
156 | arrNearendClean = (*env)->GetShortArrayElements(env, nearendClean,
157 | NULL);
158 |
159 | ret = WebRtcAecm_Process(aecmInst, arrNearendNoisy, arrNearendClean, arrOut,
160 | nrOfSamples, msInSndCardBuf);
161 |
162 | //release and send the changes back to java side.
163 | (*env)->ReleaseShortArrayElements(env, nearendNoisy, arrNearendNoisy, 0);
164 | (*env)->ReleaseShortArrayElements(env, out, arrOut, 0);
165 |
166 | if (nearendClean != NULL)
167 | (*env)->ReleaseShortArrayElements(env, nearendClean, arrNearendClean,
168 | 0);
169 |
170 | return ret;
171 | }
172 |
173 | /**
174 | * This wrapper wraps the WebRtcAecm_set_config function in echo_control_mobile.c
175 | * Enables the user to set certain parameters on-the-fly.
176 | *
177 | * Inputs:
178 | * aecHandler - Handler to the AEC instance.
179 | * aecConfig - the new configuration of AEC instance to set.
180 | * Outputs:
181 | * NONE
182 | * Return: 0: OK
183 | * -1: error
184 | *
185 | */
186 | JNIEXPORT jint JNICALL Java_com_android_webrtc_audio_MobileAEC_nativeSetConfig(
187 | JNIEnv *env, jclass jclazz, jint aecmHandler, jobject aecmConfig) {
188 |
189 | void * aecmInst = (void *) aecmHandler;
190 | if (aecmInst == NULL)
191 | return -1;
192 |
193 | //get reference of AecmConfig class from java side.
194 | jclass JavaAecmConfig = (*env)->GetObjectClass(env, aecmConfig);
195 |
196 | //assertion that class not be NULL
197 | //TODO(billhoo) should use Exception handler to handle this situation instead of assertion.
198 | assert(JavaAecmConfig != NULL);
199 |
200 | //get configuration field IDs from java side.
201 | jfieldID mAecmModeID = (*env)->GetFieldID(env, JavaAecmConfig, "mAecmMode",
202 | "S");
203 | jfieldID mCngModeID = (*env)->GetFieldID(env, JavaAecmConfig, "mCngMode",
204 | "S");
205 |
206 | //if any ID is NULL, return -1 for error.
207 | if (mAecmModeID == NULL || mCngModeID == NULL)
208 | return -1;
209 |
210 | //get values of fields
211 | short echoMode = (*env)->GetShortField(env, aecmConfig, mAecmModeID);
212 | short cngMode = (*env)->GetShortField(env, aecmConfig, mCngModeID);
213 |
214 | //set new configuration to AECM instance.
215 | AecmConfig config;
216 | config.echoMode = echoMode;
217 | config.cngMode = cngMode;
218 |
219 | return WebRtcAecm_set_config(aecmInst, config);
220 | }
221 |
222 | /*
223 | * This function enables the user to set certain parameters on-the-fly
224 | *
225 | * Inputs Description
226 | * -------------------------------------------------------------------
227 | * void *aecmInst Pointer to the AECM instance
228 | *
229 | * Outputs Description
230 | * -------------------------------------------------------------------
231 | * AecmConfig *config Pointer to the config instance that
232 | * all properties will be written to
233 | * WebRtc_Word32 return 0: OK
234 | * -1: error
235 | */
236 | //TODO(billhoo) wrap this into JNI interface if necessary.
237 | int32_t WebRtcAecm_get_config(void *aecmInst, AecmConfig *config);
238 |
239 | /*
240 | * This function enables the user to set the echo path on-the-fly.
241 | *
242 | * Inputs Description
243 | * -------------------------------------------------------------------
244 | * void* aecmInst Pointer to the AECM instance
245 | * void* echo_path Pointer to the echo path to be set
246 | * size_t size_bytes Size in bytes of the echo path
247 | *
248 | * Outputs Description
249 | * -------------------------------------------------------------------
250 | * WebRtc_Word32 return 0: OK
251 | * -1: error
252 | */
253 | //TODO(billhoo) wrap this into JNI interface if necessary.
254 | int32_t WebRtcAecm_InitEchoPath(void* aecmInst, const void* echo_path,
255 | size_t size_bytes);
256 |
257 | /*
258 | * This function enables the user to get the currently used echo path
259 | * on-the-fly
260 | *
261 | * Inputs Description
262 | * -------------------------------------------------------------------
263 | * void* aecmInst Pointer to the AECM instance
264 | * void* echo_path Pointer to echo path
265 | * size_t size_bytes Size in bytes of the echo path
266 | *
267 | * Outputs Description
268 | * -------------------------------------------------------------------
269 | * WebRtc_Word32 return 0: OK
270 | * -1: error
271 | */
272 | //TODO(billhoo) wrap this into JNI interface if necessary.
273 | int32_t WebRtcAecm_GetEchoPath(void* aecmInst, void* echo_path,
274 | size_t size_bytes);
275 |
276 | /*
277 | * This function enables the user to get the echo path size in bytes
278 | *
279 | * Outputs Description
280 | * -------------------------------------------------------------------
281 | * size_t return : size in bytes
282 | */
283 | //TODO(billhoo) wrap this into JNI interface if necessary.
284 | size_t WebRtcAecm_echo_path_size_bytes();
285 |
286 | /*
287 | * Gets the last error code.
288 | *
289 | * Inputs Description
290 | * -------------------------------------------------------------------
291 | * void *aecmInst Pointer to the AECM instance
292 | *
293 | * Outputs Description
294 | * -------------------------------------------------------------------
295 | * WebRtc_Word32 return 11000-11100: error code
296 | */
297 | //TODO(billhoo) wrap this into JNI interface if necessary.
298 | int32_t WebRtcAecm_get_error_code(void *aecmInst);
299 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/aecm_core.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | // Performs echo control (suppression) with fft routines in fixed-point.
12 |
13 | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_AECM_CORE_H_
14 | #define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_AECM_CORE_H_
15 |
16 | #include "signal_processing_library.h"
17 | #include "aecm_defines.h"
18 | #include "ring_buffer.h"
19 | #include "typedefs.h"
20 |
21 | #ifdef _MSC_VER // visual c++
22 | #define ALIGN8_BEG __declspec(align(8))
23 | #define ALIGN8_END
24 | #else // gcc or icc
25 | #define ALIGN8_BEG
26 | #define ALIGN8_END __attribute__((aligned(8)))
27 | #endif
28 |
29 | typedef struct {
30 | int16_t real;
31 | int16_t imag;
32 | } complex16_t;
33 |
34 | typedef struct {
35 | int farBufWritePos;
36 | int farBufReadPos;
37 | int knownDelay;
38 | int lastKnownDelay;
39 | int firstVAD; // Parameter to control poorly initialized channels
40 |
41 | RingBuffer* farFrameBuf;
42 | RingBuffer* nearNoisyFrameBuf;
43 | RingBuffer* nearCleanFrameBuf;
44 | RingBuffer* outFrameBuf;
45 |
46 | int16_t farBuf[FAR_BUF_LEN];
47 |
48 | int16_t mult;
49 | uint32_t seed;
50 |
51 | // Delay estimation variables
52 | void* delay_estimator_farend;
53 | void* delay_estimator;
54 | uint16_t currentDelay;
55 | // Far end history variables
56 | // TODO(bjornv): Replace |far_history| with ring_buffer.
57 | uint16_t far_history[PART_LEN1 * MAX_DELAY];
58 | int far_history_pos;
59 | int far_q_domains[MAX_DELAY];
60 |
61 | int16_t nlpFlag;
62 | int16_t fixedDelay;
63 |
64 | uint32_t totCount;
65 |
66 | int16_t dfaCleanQDomain;
67 | int16_t dfaCleanQDomainOld;
68 | int16_t dfaNoisyQDomain;
69 | int16_t dfaNoisyQDomainOld;
70 |
71 | int16_t nearLogEnergy[MAX_BUF_LEN];
72 | int16_t farLogEnergy;
73 | int16_t echoAdaptLogEnergy[MAX_BUF_LEN];
74 | int16_t echoStoredLogEnergy[MAX_BUF_LEN];
75 |
76 | // The extra 16 or 32 bytes in the following buffers are for alignment based
77 | // Neon code.
78 | // It's designed this way since the current GCC compiler can't align a
79 | // buffer in 16 or 32 byte boundaries properly.
80 | int16_t channelStored_buf[PART_LEN1 + 8];
81 | int16_t channelAdapt16_buf[PART_LEN1 + 8];
82 | int32_t channelAdapt32_buf[PART_LEN1 + 8];
83 | int16_t xBuf_buf[PART_LEN2 + 16]; // farend
84 | int16_t dBufClean_buf[PART_LEN2 + 16]; // nearend
85 | int16_t dBufNoisy_buf[PART_LEN2 + 16]; // nearend
86 | int16_t outBuf_buf[PART_LEN + 8];
87 |
88 | // Pointers to the above buffers
89 | int16_t *channelStored;
90 | int16_t *channelAdapt16;
91 | int32_t *channelAdapt32;
92 | int16_t *xBuf;
93 | int16_t *dBufClean;
94 | int16_t *dBufNoisy;
95 | int16_t *outBuf;
96 |
97 | int32_t echoFilt[PART_LEN1];
98 | int16_t nearFilt[PART_LEN1];
99 | int32_t noiseEst[PART_LEN1];
100 | int noiseEstTooLowCtr[PART_LEN1];
101 | int noiseEstTooHighCtr[PART_LEN1];
102 | int16_t noiseEstCtr;
103 | int16_t cngMode;
104 |
105 | int32_t mseAdaptOld;
106 | int32_t mseStoredOld;
107 | int32_t mseThreshold;
108 |
109 | int16_t farEnergyMin;
110 | int16_t farEnergyMax;
111 | int16_t farEnergyMaxMin;
112 | int16_t farEnergyVAD;
113 | int16_t farEnergyMSE;
114 | int currentVADValue;
115 | int16_t vadUpdateCount;
116 |
117 | int16_t startupState;
118 | int16_t mseChannelCount;
119 | int16_t supGain;
120 | int16_t supGainOld;
121 |
122 | int16_t supGainErrParamA;
123 | int16_t supGainErrParamD;
124 | int16_t supGainErrParamDiffAB;
125 | int16_t supGainErrParamDiffBD;
126 |
127 | struct RealFFT* real_fft;
128 |
129 | #ifdef AEC_DEBUG
130 | FILE *farFile;
131 | FILE *nearFile;
132 | FILE *outFile;
133 | #endif
134 | } AecmCore_t;
135 |
136 | ////////////////////////////////////////////////////////////////////////////////
137 | // WebRtcAecm_CreateCore(...)
138 | //
139 | // Allocates the memory needed by the AECM. The memory needs to be
140 | // initialized separately using the WebRtcAecm_InitCore() function.
141 | //
142 | // Input:
143 | // - aecm : Instance that should be created
144 | //
145 | // Output:
146 | // - aecm : Created instance
147 | //
148 | // Return value : 0 - Ok
149 | // -1 - Error
150 | //
151 | int WebRtcAecm_CreateCore(AecmCore_t **aecm);
152 |
153 | ////////////////////////////////////////////////////////////////////////////////
154 | // WebRtcAecm_InitCore(...)
155 | //
156 | // This function initializes the AECM instant created with
157 | // WebRtcAecm_CreateCore(...)
158 | // Input:
159 | // - aecm : Pointer to the AECM instance
160 | // - samplingFreq : Sampling Frequency
161 | //
162 | // Output:
163 | // - aecm : Initialized instance
164 | //
165 | // Return value : 0 - Ok
166 | // -1 - Error
167 | //
168 | int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq);
169 |
170 | ////////////////////////////////////////////////////////////////////////////////
171 | // WebRtcAecm_FreeCore(...)
172 | //
173 | // This function releases the memory allocated by WebRtcAecm_CreateCore()
174 | // Input:
175 | // - aecm : Pointer to the AECM instance
176 | //
177 | // Return value : 0 - Ok
178 | // -1 - Error
179 | // 11001-11016: Error
180 | //
181 | int WebRtcAecm_FreeCore(AecmCore_t *aecm);
182 |
183 | int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag);
184 |
185 | ////////////////////////////////////////////////////////////////////////////////
186 | // WebRtcAecm_InitEchoPathCore(...)
187 | //
188 | // This function resets the echo channel adaptation with the specified channel.
189 | // Input:
190 | // - aecm : Pointer to the AECM instance
191 | // - echo_path : Pointer to the data that should initialize the echo
192 | // path
193 | //
194 | // Output:
195 | // - aecm : Initialized instance
196 | //
197 | void WebRtcAecm_InitEchoPathCore(AecmCore_t* aecm,
198 | const int16_t* echo_path);
199 |
200 | ////////////////////////////////////////////////////////////////////////////////
201 | // WebRtcAecm_ProcessFrame(...)
202 | //
203 | // This function processes frames and sends blocks to
204 | // WebRtcAecm_ProcessBlock(...)
205 | //
206 | // Inputs:
207 | // - aecm : Pointer to the AECM instance
208 | // - farend : In buffer containing one frame of echo signal
209 | // - nearendNoisy : In buffer containing one frame of nearend+echo signal
210 | // without NS
211 | // - nearendClean : In buffer containing one frame of nearend+echo signal
212 | // with NS
213 | //
214 | // Output:
215 | // - out : Out buffer, one frame of nearend signal :
216 | //
217 | //
218 | int WebRtcAecm_ProcessFrame(AecmCore_t * aecm, const int16_t * farend,
219 | const int16_t * nearendNoisy,
220 | const int16_t * nearendClean,
221 | int16_t * out);
222 |
223 | ////////////////////////////////////////////////////////////////////////////////
224 | // WebRtcAecm_ProcessBlock(...)
225 | //
226 | // This function is called for every block within one frame
227 | // This function is called by WebRtcAecm_ProcessFrame(...)
228 | //
229 | // Inputs:
230 | // - aecm : Pointer to the AECM instance
231 | // - farend : In buffer containing one block of echo signal
232 | // - nearendNoisy : In buffer containing one frame of nearend+echo signal
233 | // without NS
234 | // - nearendClean : In buffer containing one frame of nearend+echo signal
235 | // with NS
236 | //
237 | // Output:
238 | // - out : Out buffer, one block of nearend signal :
239 | //
240 | //
241 | int WebRtcAecm_ProcessBlock(AecmCore_t * aecm, const int16_t * farend,
242 | const int16_t * nearendNoisy,
243 | const int16_t * noisyClean,
244 | int16_t * out);
245 |
246 | ////////////////////////////////////////////////////////////////////////////////
247 | // WebRtcAecm_BufferFarFrame()
248 | //
249 | // Inserts a frame of data into farend buffer.
250 | //
251 | // Inputs:
252 | // - aecm : Pointer to the AECM instance
253 | // - farend : In buffer containing one frame of farend signal
254 | // - farLen : Length of frame
255 | //
256 | void WebRtcAecm_BufferFarFrame(AecmCore_t * const aecm,
257 | const int16_t * const farend,
258 | const int farLen);
259 |
260 | ////////////////////////////////////////////////////////////////////////////////
261 | // WebRtcAecm_FetchFarFrame()
262 | //
263 | // Read the farend buffer to account for known delay
264 | //
265 | // Inputs:
266 | // - aecm : Pointer to the AECM instance
267 | // - farend : In buffer containing one frame of farend signal
268 | // - farLen : Length of frame
269 | // - knownDelay : known delay
270 | //
271 | void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm,
272 | int16_t * const farend,
273 | const int farLen, const int knownDelay);
274 |
275 | ///////////////////////////////////////////////////////////////////////////////
276 | // Some function pointers, for internal functions shared by ARM NEON and
277 | // generic C code.
278 | //
279 | typedef void (*CalcLinearEnergies)(
280 | AecmCore_t* aecm,
281 | const uint16_t* far_spectrum,
282 | int32_t* echoEst,
283 | uint32_t* far_energy,
284 | uint32_t* echo_energy_adapt,
285 | uint32_t* echo_energy_stored);
286 | extern CalcLinearEnergies WebRtcAecm_CalcLinearEnergies;
287 |
288 | typedef void (*StoreAdaptiveChannel)(
289 | AecmCore_t* aecm,
290 | const uint16_t* far_spectrum,
291 | int32_t* echo_est);
292 | extern StoreAdaptiveChannel WebRtcAecm_StoreAdaptiveChannel;
293 |
294 | typedef void (*ResetAdaptiveChannel)(AecmCore_t* aecm);
295 | extern ResetAdaptiveChannel WebRtcAecm_ResetAdaptiveChannel;
296 |
297 | // For the above function pointers, functions for generic platforms are declared
298 | // and defined as static in file aecm_core.c, while those for ARM Neon platforms
299 | // are declared below and defined in file aecm_core_neon.s.
300 | #if (defined WEBRTC_DETECT_ARM_NEON) || defined (WEBRTC_ARCH_ARM_NEON)
301 | void WebRtcAecm_CalcLinearEnergiesNeon(AecmCore_t* aecm,
302 | const uint16_t* far_spectrum,
303 | int32_t* echo_est,
304 | uint32_t* far_energy,
305 | uint32_t* echo_energy_adapt,
306 | uint32_t* echo_energy_stored);
307 |
308 | void WebRtcAecm_StoreAdaptiveChannelNeon(AecmCore_t* aecm,
309 | const uint16_t* far_spectrum,
310 | int32_t* echo_est);
311 |
312 | void WebRtcAecm_ResetAdaptiveChannelNeon(AecmCore_t* aecm);
313 | #endif
314 |
315 | #endif
316 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/complex_fft.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 |
12 | /*
13 | * This file contains the function WebRtcSpl_ComplexFFT().
14 | * The description header can be found in signal_processing_library.h
15 | *
16 | */
17 |
18 | #include "complex_fft_tables.h"
19 | #include "signal_processing_library.h"
20 |
21 | #define CFFTSFT 14
22 | #define CFFTRND 1
23 | #define CFFTRND2 16384
24 |
25 | #define CIFFTSFT 14
26 | #define CIFFTRND 1
27 |
28 |
29 | int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode)
30 | {
31 | int i, j, l, k, istep, n, m;
32 | int16_t wr, wi;
33 | int32_t tr32, ti32, qr32, qi32;
34 |
35 | /* The 1024-value is a constant given from the size of kSinTable1024[],
36 | * and should not be changed depending on the input parameter 'stages'
37 | */
38 | n = 1 << stages;
39 | if (n > 1024)
40 | return -1;
41 |
42 | l = 1;
43 | k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
44 | depending on the input parameter 'stages' */
45 |
46 | if (mode == 0)
47 | {
48 | // mode==0: Low-complexity and Low-accuracy mode
49 | while (l < n)
50 | {
51 | istep = l << 1;
52 |
53 | for (m = 0; m < l; ++m)
54 | {
55 | j = m << k;
56 |
57 | /* The 256-value is a constant given as 1/4 of the size of
58 | * kSinTable1024[], and should not be changed depending on the input
59 | * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
60 | */
61 | wr = kSinTable1024[j + 256];
62 | wi = -kSinTable1024[j];
63 |
64 | for (i = m; i < n; i += istep)
65 | {
66 | j = i + l;
67 |
68 | tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
69 | - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);
70 |
71 | ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
72 | + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);
73 |
74 | qr32 = (int32_t)frfi[2 * i];
75 | qi32 = (int32_t)frfi[2 * i + 1];
76 | frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);
77 | frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);
78 | frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);
79 | frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);
80 | }
81 | }
82 |
83 | --k;
84 | l = istep;
85 |
86 | }
87 |
88 | } else
89 | {
90 | // mode==1: High-complexity and High-accuracy mode
91 | while (l < n)
92 | {
93 | istep = l << 1;
94 |
95 | for (m = 0; m < l; ++m)
96 | {
97 | j = m << k;
98 |
99 | /* The 256-value is a constant given as 1/4 of the size of
100 | * kSinTable1024[], and should not be changed depending on the input
101 | * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
102 | */
103 | wr = kSinTable1024[j + 256];
104 | wi = -kSinTable1024[j];
105 |
106 | #ifdef WEBRTC_ARCH_ARM_V7
107 | int32_t wri = 0;
108 | int32_t frfi_r = 0;
109 | __asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
110 | "r"((int32_t)wr), "r"((int32_t)wi));
111 | #endif
112 |
113 | for (i = m; i < n; i += istep)
114 | {
115 | j = i + l;
116 |
117 | #ifdef WEBRTC_ARCH_ARM_V7
118 | __asm __volatile(
119 | "pkhbt %[frfi_r], %[frfi_even], %[frfi_odd], lsl #16\n\t"
120 | "smlsd %[tr32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
121 | "smladx %[ti32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
122 | :[frfi_r]"+r"(frfi_r),
123 | [tr32]"=r"(tr32),
124 | [ti32]"=r"(ti32)
125 | :[frfi_even]"r"((int32_t)frfi[2*j]),
126 | [frfi_odd]"r"((int32_t)frfi[2*j +1]),
127 | [wri]"r"(wri),
128 | [cfftrnd]"r"(CFFTRND)
129 | );
130 |
131 | #else
132 | tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
133 | - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND;
134 |
135 | ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
136 | + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND;
137 | #endif
138 |
139 | tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT);
140 | ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT);
141 |
142 | qr32 = ((int32_t)frfi[2 * i]) << CFFTSFT;
143 | qi32 = ((int32_t)frfi[2 * i + 1]) << CFFTSFT;
144 |
145 | frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
146 | (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);
147 | frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
148 | (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);
149 | frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
150 | (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);
151 | frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
152 | (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);
153 | }
154 | }
155 |
156 | --k;
157 | l = istep;
158 | }
159 | }
160 | return 0;
161 | }
162 |
163 | int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode)
164 | {
165 | int i, j, l, k, istep, n, m, scale, shift;
166 | int16_t wr, wi;
167 | int32_t tr32, ti32, qr32, qi32;
168 | int32_t tmp32, round2;
169 |
170 | /* The 1024-value is a constant given from the size of kSinTable1024[],
171 | * and should not be changed depending on the input parameter 'stages'
172 | */
173 | n = 1 << stages;
174 | if (n > 1024)
175 | return -1;
176 |
177 | scale = 0;
178 |
179 | l = 1;
180 | k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
181 | depending on the input parameter 'stages' */
182 |
183 | while (l < n)
184 | {
185 | // variable scaling, depending upon data
186 | shift = 0;
187 | round2 = 8192;
188 |
189 | tmp32 = (int32_t)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
190 | if (tmp32 > 13573)
191 | {
192 | shift++;
193 | scale++;
194 | round2 <<= 1;
195 | }
196 | if (tmp32 > 27146)
197 | {
198 | shift++;
199 | scale++;
200 | round2 <<= 1;
201 | }
202 |
203 | istep = l << 1;
204 |
205 | if (mode == 0)
206 | {
207 | // mode==0: Low-complexity and Low-accuracy mode
208 | for (m = 0; m < l; ++m)
209 | {
210 | j = m << k;
211 |
212 | /* The 256-value is a constant given as 1/4 of the size of
213 | * kSinTable1024[], and should not be changed depending on the input
214 | * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
215 | */
216 | wr = kSinTable1024[j + 256];
217 | wi = kSinTable1024[j];
218 |
219 | for (i = m; i < n; i += istep)
220 | {
221 | j = i + l;
222 |
223 | tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)
224 | - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15);
225 |
226 | ti32 = WEBRTC_SPL_RSHIFT_W32(
227 | (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)
228 | + WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15);
229 |
230 | qr32 = (int32_t)frfi[2 * i];
231 | qi32 = (int32_t)frfi[2 * i + 1];
232 | frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift);
233 | frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift);
234 | frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift);
235 | frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift);
236 | }
237 | }
238 | } else
239 | {
240 | // mode==1: High-complexity and High-accuracy mode
241 |
242 | for (m = 0; m < l; ++m)
243 | {
244 | j = m << k;
245 |
246 | /* The 256-value is a constant given as 1/4 of the size of
247 | * kSinTable1024[], and should not be changed depending on the input
248 | * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
249 | */
250 | wr = kSinTable1024[j + 256];
251 | wi = kSinTable1024[j];
252 |
253 | #ifdef WEBRTC_ARCH_ARM_V7
254 | int32_t wri = 0;
255 | int32_t frfi_r = 0;
256 | __asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
257 | "r"((int32_t)wr), "r"((int32_t)wi));
258 | #endif
259 |
260 | for (i = m; i < n; i += istep)
261 | {
262 | j = i + l;
263 |
264 | #ifdef WEBRTC_ARCH_ARM_V7
265 | __asm __volatile(
266 | "pkhbt %[frfi_r], %[frfi_even], %[frfi_odd], lsl #16\n\t"
267 | "smlsd %[tr32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
268 | "smladx %[ti32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
269 | :[frfi_r]"+r"(frfi_r),
270 | [tr32]"=r"(tr32),
271 | [ti32]"=r"(ti32)
272 | :[frfi_even]"r"((int32_t)frfi[2*j]),
273 | [frfi_odd]"r"((int32_t)frfi[2*j +1]),
274 | [wri]"r"(wri),
275 | [cifftrnd]"r"(CIFFTRND)
276 | );
277 | #else
278 |
279 | tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
280 | - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CIFFTRND;
281 |
282 | ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
283 | + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND;
284 | #endif
285 | tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT);
286 | ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT);
287 |
288 | qr32 = ((int32_t)frfi[2 * i]) << CIFFTSFT;
289 | qi32 = ((int32_t)frfi[2 * i + 1]) << CIFFTSFT;
290 |
291 | frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2),
292 | shift+CIFFTSFT);
293 | frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
294 | (qi32 - ti32 + round2), shift + CIFFTSFT);
295 | frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2),
296 | shift + CIFFTSFT);
297 | frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
298 | (qi32 + ti32 + round2), shift + CIFFTSFT);
299 | }
300 | }
301 |
302 | }
303 | --k;
304 | l = istep;
305 | }
306 | return scale;
307 | }
308 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/delay_estimator_wrapper.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "delay_estimator_wrapper.h"
12 |
13 | #include
14 | #include
15 | #include
16 |
17 | #include "delay_estimator.h"
18 | #include "delay_estimator_internal.h"
19 | #include "compile_assert_c.h"
20 |
21 | // Only bit |kBandFirst| through bit |kBandLast| are processed and
22 | // |kBandFirst| - |kBandLast| must be < 32.
23 | enum { kBandFirst = 12 };
24 | enum { kBandLast = 43 };
25 |
26 | static __inline uint32_t SetBit(uint32_t in, int pos) {
27 | uint32_t mask = (1 << pos);
28 | uint32_t out = (in | mask);
29 |
30 | return out;
31 | }
32 |
33 | // Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
34 | // but for float.
35 | //
36 | // Inputs:
37 | // - new_value : New additional value.
38 | // - scale : Scale for smoothing (should be less than 1.0).
39 | //
40 | // Input/Output:
41 | // - mean_value : Pointer to the mean value for updating.
42 | //
43 | static void MeanEstimatorFloat(float new_value,
44 | float scale,
45 | float* mean_value) {
46 | assert(scale < 1.0f);
47 | *mean_value += (new_value - *mean_value) * scale;
48 | }
49 |
50 | // Computes the binary spectrum by comparing the input |spectrum| with a
51 | // |threshold_spectrum|. Float and fixed point versions.
52 | //
53 | // Inputs:
54 | // - spectrum : Spectrum of which the binary spectrum should be
55 | // calculated.
56 | // - threshold_spectrum : Threshold spectrum with which the input
57 | // spectrum is compared.
58 | // Return:
59 | // - out : Binary spectrum.
60 | //
61 | static uint32_t BinarySpectrumFix(uint16_t* spectrum,
62 | SpectrumType* threshold_spectrum,
63 | int q_domain,
64 | int* threshold_initialized) {
65 | int i = kBandFirst;
66 | uint32_t out = 0;
67 |
68 | assert(q_domain < 16);
69 |
70 | if (!(*threshold_initialized)) {
71 | // Set the |threshold_spectrum| to half the input |spectrum| as starting
72 | // value. This speeds up the convergence.
73 | for (i = kBandFirst; i <= kBandLast; i++) {
74 | if (spectrum[i] > 0) {
75 | // Convert input spectrum from Q(|q_domain|) to Q15.
76 | int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
77 | threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
78 | *threshold_initialized = 1;
79 | }
80 | }
81 | }
82 | for (i = kBandFirst; i <= kBandLast; i++) {
83 | // Convert input spectrum from Q(|q_domain|) to Q15.
84 | int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
85 | // Update the |threshold_spectrum|.
86 | WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
87 | // Convert |spectrum| at current frequency bin to a binary value.
88 | if (spectrum_q15 > threshold_spectrum[i].int32_) {
89 | out = SetBit(out, i - kBandFirst);
90 | }
91 | }
92 |
93 | return out;
94 | }
95 |
96 | static uint32_t BinarySpectrumFloat(float* spectrum,
97 | SpectrumType* threshold_spectrum,
98 | int* threshold_initialized) {
99 | int i = kBandFirst;
100 | uint32_t out = 0;
101 | const float kScale = 1 / 64.0;
102 |
103 | if (!(*threshold_initialized)) {
104 | // Set the |threshold_spectrum| to half the input |spectrum| as starting
105 | // value. This speeds up the convergence.
106 | for (i = kBandFirst; i <= kBandLast; i++) {
107 | if (spectrum[i] > 0.0f) {
108 | threshold_spectrum[i].float_ = (spectrum[i] / 2);
109 | *threshold_initialized = 1;
110 | }
111 | }
112 | }
113 |
114 | for (i = kBandFirst; i <= kBandLast; i++) {
115 | // Update the |threshold_spectrum|.
116 | MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
117 | // Convert |spectrum| at current frequency bin to a binary value.
118 | if (spectrum[i] > threshold_spectrum[i].float_) {
119 | out = SetBit(out, i - kBandFirst);
120 | }
121 | }
122 |
123 | return out;
124 | }
125 |
126 | void WebRtc_FreeDelayEstimatorFarend(void* handle) {
127 | DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
128 |
129 | if (handle == NULL) {
130 | return;
131 | }
132 |
133 | free(self->mean_far_spectrum);
134 | self->mean_far_spectrum = NULL;
135 |
136 | WebRtc_FreeBinaryDelayEstimatorFarend(self->binary_farend);
137 | self->binary_farend = NULL;
138 |
139 | free(self);
140 | }
141 |
142 | void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) {
143 | DelayEstimatorFarend* self = NULL;
144 |
145 | // Check if the sub band used in the delay estimation is small enough to fit
146 | // the binary spectra in a uint32_t.
147 | COMPILE_ASSERT(kBandLast - kBandFirst < 32);
148 |
149 | if (spectrum_size >= kBandLast) {
150 | self = malloc(sizeof(DelayEstimator));
151 | }
152 |
153 | if (self != NULL) {
154 | int memory_fail = 0;
155 |
156 | // Allocate memory for the binary far-end spectrum handling.
157 | self->binary_farend = WebRtc_CreateBinaryDelayEstimatorFarend(history_size);
158 | memory_fail |= (self->binary_farend == NULL);
159 |
160 | // Allocate memory for spectrum buffers.
161 | self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
162 | memory_fail |= (self->mean_far_spectrum == NULL);
163 |
164 | self->spectrum_size = spectrum_size;
165 |
166 | if (memory_fail) {
167 | WebRtc_FreeDelayEstimatorFarend(self);
168 | self = NULL;
169 | }
170 | }
171 |
172 | return self;
173 | }
174 |
175 | int WebRtc_InitDelayEstimatorFarend(void* handle) {
176 | DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
177 |
178 | if (self == NULL) {
179 | return -1;
180 | }
181 |
182 | // Initialize far-end part of binary delay estimator.
183 | WebRtc_InitBinaryDelayEstimatorFarend(self->binary_farend);
184 |
185 | // Set averaged far and near end spectra to zero.
186 | memset(self->mean_far_spectrum, 0,
187 | sizeof(SpectrumType) * self->spectrum_size);
188 | // Reset initialization indicators.
189 | self->far_spectrum_initialized = 0;
190 |
191 | return 0;
192 | }
193 |
194 | int WebRtc_AddFarSpectrumFix(void* handle, uint16_t* far_spectrum,
195 | int spectrum_size, int far_q) {
196 | DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
197 | uint32_t binary_spectrum = 0;
198 |
199 | if (self == NULL) {
200 | return -1;
201 | }
202 | if (far_spectrum == NULL) {
203 | // Empty far end spectrum.
204 | return -1;
205 | }
206 | if (spectrum_size != self->spectrum_size) {
207 | // Data sizes don't match.
208 | return -1;
209 | }
210 | if (far_q > 15) {
211 | // If |far_q| is larger than 15 we cannot guarantee no wrap around.
212 | return -1;
213 | }
214 |
215 | // Get binary spectrum.
216 | binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
217 | far_q, &(self->far_spectrum_initialized));
218 | WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
219 |
220 | return 0;
221 | }
222 |
223 | int WebRtc_AddFarSpectrumFloat(void* handle, float* far_spectrum,
224 | int spectrum_size) {
225 | DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
226 | uint32_t binary_spectrum = 0;
227 |
228 | if (self == NULL) {
229 | return -1;
230 | }
231 | if (far_spectrum == NULL) {
232 | // Empty far end spectrum.
233 | return -1;
234 | }
235 | if (spectrum_size != self->spectrum_size) {
236 | // Data sizes don't match.
237 | return -1;
238 | }
239 |
240 | // Get binary spectrum.
241 | binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
242 | &(self->far_spectrum_initialized));
243 | WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
244 |
245 | return 0;
246 | }
247 |
248 | void WebRtc_FreeDelayEstimator(void* handle) {
249 | DelayEstimator* self = (DelayEstimator*) handle;
250 |
251 | if (handle == NULL) {
252 | return;
253 | }
254 |
255 | free(self->mean_near_spectrum);
256 | self->mean_near_spectrum = NULL;
257 |
258 | WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
259 | self->binary_handle = NULL;
260 |
261 | free(self);
262 | }
263 |
264 | void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead) {
265 | DelayEstimator* self = NULL;
266 | DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
267 |
268 | if (farend_handle != NULL) {
269 | self = malloc(sizeof(DelayEstimator));
270 | }
271 |
272 | if (self != NULL) {
273 | int memory_fail = 0;
274 |
275 | // Allocate memory for the farend spectrum handling.
276 | self->binary_handle =
277 | WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, lookahead);
278 | memory_fail |= (self->binary_handle == NULL);
279 |
280 | // Allocate memory for spectrum buffers.
281 | self->mean_near_spectrum = malloc(farend->spectrum_size *
282 | sizeof(SpectrumType));
283 | memory_fail |= (self->mean_near_spectrum == NULL);
284 |
285 | self->spectrum_size = farend->spectrum_size;
286 |
287 | if (memory_fail) {
288 | WebRtc_FreeDelayEstimator(self);
289 | self = NULL;
290 | }
291 | }
292 |
293 | return self;
294 | }
295 |
296 | int WebRtc_InitDelayEstimator(void* handle) {
297 | DelayEstimator* self = (DelayEstimator*) handle;
298 |
299 | if (self == NULL) {
300 | return -1;
301 | }
302 |
303 | // Initialize binary delay estimator.
304 | WebRtc_InitBinaryDelayEstimator(self->binary_handle);
305 |
306 | // Set averaged far and near end spectra to zero.
307 | memset(self->mean_near_spectrum, 0,
308 | sizeof(SpectrumType) * self->spectrum_size);
309 | // Reset initialization indicators.
310 | self->near_spectrum_initialized = 0;
311 |
312 | return 0;
313 | }
314 |
315 | int WebRtc_DelayEstimatorProcessFix(void* handle,
316 | uint16_t* near_spectrum,
317 | int spectrum_size,
318 | int near_q) {
319 | DelayEstimator* self = (DelayEstimator*) handle;
320 | uint32_t binary_spectrum = 0;
321 |
322 | if (self == NULL) {
323 | return -1;
324 | }
325 | if (near_spectrum == NULL) {
326 | // Empty near end spectrum.
327 | return -1;
328 | }
329 | if (spectrum_size != self->spectrum_size) {
330 | // Data sizes don't match.
331 | return -1;
332 | }
333 | if (near_q > 15) {
334 | // If |near_q| is larger than 15 we cannot guarantee no wrap around.
335 | return -1;
336 | }
337 |
338 | // Get binary spectra.
339 | binary_spectrum = BinarySpectrumFix(near_spectrum,
340 | self->mean_near_spectrum,
341 | near_q,
342 | &(self->near_spectrum_initialized));
343 |
344 | return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
345 | }
346 |
347 | int WebRtc_DelayEstimatorProcessFloat(void* handle,
348 | float* near_spectrum,
349 | int spectrum_size) {
350 | DelayEstimator* self = (DelayEstimator*) handle;
351 | uint32_t binary_spectrum = 0;
352 |
353 | if (self == NULL) {
354 | return -1;
355 | }
356 | if (near_spectrum == NULL) {
357 | // Empty near end spectrum.
358 | return -1;
359 | }
360 | if (spectrum_size != self->spectrum_size) {
361 | // Data sizes don't match.
362 | return -1;
363 | }
364 |
365 | // Get binary spectrum.
366 | binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
367 | &(self->near_spectrum_initialized));
368 |
369 | return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
370 | }
371 |
372 | int WebRtc_last_delay(void* handle) {
373 | DelayEstimator* self = (DelayEstimator*) handle;
374 |
375 | if (self == NULL) {
376 | return -1;
377 | }
378 |
379 | return WebRtc_binary_last_delay(self->binary_handle);
380 | }
381 |
382 | int WebRtc_last_delay_quality(void* handle) {
383 | DelayEstimator* self = (DelayEstimator*) handle;
384 |
385 | if (self == NULL) {
386 | return -1;
387 | }
388 |
389 | return WebRtc_binary_last_delay_quality(self->binary_handle);
390 | }
391 |
--------------------------------------------------------------------------------
/eclipse-project/jni/aecm/delay_estimator.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "delay_estimator.h"
12 |
13 | #include
14 | #include
15 | #include
16 |
17 | // Number of right shifts for scaling is linearly depending on number of bits in
18 | // the far-end binary spectrum.
19 | static const int kShiftsAtZero = 13; // Right shifts at zero binary spectrum.
20 | static const int kShiftsLinearSlope = 3;
21 |
22 | static const int32_t kProbabilityOffset = 1024; // 2 in Q9.
23 | static const int32_t kProbabilityLowerLimit = 8704; // 17 in Q9.
24 | static const int32_t kProbabilityMinSpread = 2816; // 5.5 in Q9.
25 |
26 | // Counts and returns number of bits of a 32-bit word.
27 | static int BitCount(uint32_t u32) {
28 | uint32_t tmp = u32 - ((u32 >> 1) & 033333333333) -
29 | ((u32 >> 2) & 011111111111);
30 | tmp = ((tmp + (tmp >> 3)) & 030707070707);
31 | tmp = (tmp + (tmp >> 6));
32 | tmp = (tmp + (tmp >> 12) + (tmp >> 24)) & 077;
33 |
34 | return ((int) tmp);
35 | }
36 |
37 | // Compares the |binary_vector| with all rows of the |binary_matrix| and counts
38 | // per row the number of times they have the same value.
39 | //
40 | // Inputs:
41 | // - binary_vector : binary "vector" stored in a long
42 | // - binary_matrix : binary "matrix" stored as a vector of long
43 | // - matrix_size : size of binary "matrix"
44 | //
45 | // Output:
46 | // - bit_counts : "Vector" stored as a long, containing for each
47 | // row the number of times the matrix row and the
48 | // input vector have the same value
49 | //
50 | static void BitCountComparison(uint32_t binary_vector,
51 | const uint32_t* binary_matrix,
52 | int matrix_size,
53 | int32_t* bit_counts) {
54 | int n = 0;
55 |
56 | // Compare |binary_vector| with all rows of the |binary_matrix|
57 | for (; n < matrix_size; n++) {
58 | bit_counts[n] = (int32_t) BitCount(binary_vector ^ binary_matrix[n]);
59 | }
60 | }
61 |
62 | void WebRtc_FreeBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) {
63 |
64 | if (self == NULL) {
65 | return;
66 | }
67 |
68 | free(self->binary_far_history);
69 | self->binary_far_history = NULL;
70 |
71 | free(self->far_bit_counts);
72 | self->far_bit_counts = NULL;
73 |
74 | free(self);
75 | }
76 |
77 | BinaryDelayEstimatorFarend* WebRtc_CreateBinaryDelayEstimatorFarend(
78 | int history_size) {
79 | BinaryDelayEstimatorFarend* self = NULL;
80 |
81 | if (history_size > 1) {
82 | // Sanity conditions fulfilled.
83 | self = malloc(sizeof(BinaryDelayEstimatorFarend));
84 | }
85 | if (self != NULL) {
86 | int malloc_fail = 0;
87 |
88 | self->history_size = history_size;
89 |
90 | // Allocate memory for history buffers.
91 | self->binary_far_history = malloc(history_size * sizeof(uint32_t));
92 | malloc_fail |= (self->binary_far_history == NULL);
93 |
94 | self->far_bit_counts = malloc(history_size * sizeof(int));
95 | malloc_fail |= (self->far_bit_counts == NULL);
96 |
97 | if (malloc_fail) {
98 | WebRtc_FreeBinaryDelayEstimatorFarend(self);
99 | self = NULL;
100 | }
101 | }
102 |
103 | return self;
104 | }
105 |
106 | void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) {
107 | assert(self != NULL);
108 | memset(self->binary_far_history, 0, sizeof(uint32_t) * self->history_size);
109 | memset(self->far_bit_counts, 0, sizeof(int) * self->history_size);
110 | }
111 |
112 | void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle,
113 | uint32_t binary_far_spectrum) {
114 | assert(handle != NULL);
115 | // Shift binary spectrum history and insert current |binary_far_spectrum|.
116 | memmove(&(handle->binary_far_history[1]), &(handle->binary_far_history[0]),
117 | (handle->history_size - 1) * sizeof(uint32_t));
118 | handle->binary_far_history[0] = binary_far_spectrum;
119 |
120 | // Shift history of far-end binary spectrum bit counts and insert bit count
121 | // of current |binary_far_spectrum|.
122 | memmove(&(handle->far_bit_counts[1]), &(handle->far_bit_counts[0]),
123 | (handle->history_size - 1) * sizeof(int));
124 | handle->far_bit_counts[0] = BitCount(binary_far_spectrum);
125 | }
126 |
127 | void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self) {
128 |
129 | if (self == NULL) {
130 | return;
131 | }
132 |
133 | free(self->mean_bit_counts);
134 | self->mean_bit_counts = NULL;
135 |
136 | free(self->bit_counts);
137 | self->bit_counts = NULL;
138 |
139 | free(self->binary_near_history);
140 | self->binary_near_history = NULL;
141 |
142 | // BinaryDelayEstimator does not have ownership of |farend|, hence we do not
143 | // free the memory here. That should be handled separately by the user.
144 | self->farend = NULL;
145 |
146 | free(self);
147 | }
148 |
149 | BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
150 | BinaryDelayEstimatorFarend* farend, int lookahead) {
151 | BinaryDelayEstimator* self = NULL;
152 |
153 | if ((farend != NULL) && (lookahead >= 0)) {
154 | // Sanity conditions fulfilled.
155 | self = malloc(sizeof(BinaryDelayEstimator));
156 | }
157 |
158 | if (self != NULL) {
159 | int malloc_fail = 0;
160 |
161 | self->farend = farend;
162 | self->near_history_size = lookahead + 1;
163 |
164 | // Allocate memory for spectrum buffers.
165 | self->mean_bit_counts = malloc(farend->history_size * sizeof(int32_t));
166 | malloc_fail |= (self->mean_bit_counts == NULL);
167 |
168 | self->bit_counts = malloc(farend->history_size * sizeof(int32_t));
169 | malloc_fail |= (self->bit_counts == NULL);
170 |
171 | // Allocate memory for history buffers.
172 | self->binary_near_history = malloc((lookahead + 1) * sizeof(uint32_t));
173 | malloc_fail |= (self->binary_near_history == NULL);
174 |
175 | if (malloc_fail) {
176 | WebRtc_FreeBinaryDelayEstimator(self);
177 | self = NULL;
178 | }
179 | }
180 |
181 | return self;
182 | }
183 |
184 | void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) {
185 | int i = 0;
186 | assert(self != NULL);
187 |
188 | memset(self->bit_counts, 0, sizeof(int32_t) * self->farend->history_size);
189 | memset(self->binary_near_history, 0,
190 | sizeof(uint32_t) * self->near_history_size);
191 | for (i = 0; i < self->farend->history_size; ++i) {
192 | self->mean_bit_counts[i] = (20 << 9); // 20 in Q9.
193 | }
194 | self->minimum_probability = (32 << 9); // 32 in Q9.
195 | self->last_delay_probability = (32 << 9); // 32 in Q9.
196 |
197 | // Default return value if we're unable to estimate. -1 is used for errors.
198 | self->last_delay = -2;
199 | }
200 |
201 | int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self,
202 | uint32_t binary_near_spectrum) {
203 | int i = 0;
204 | int candidate_delay = -1;
205 |
206 | int32_t value_best_candidate = 32 << 9; // 32 in Q9, (max |mean_bit_counts|).
207 | int32_t value_worst_candidate = 0;
208 |
209 | assert(self != NULL);
210 | if (self->near_history_size > 1) {
211 | // If we apply lookahead, shift near-end binary spectrum history. Insert
212 | // current |binary_near_spectrum| and pull out the delayed one.
213 | memmove(&(self->binary_near_history[1]), &(self->binary_near_history[0]),
214 | (self->near_history_size - 1) * sizeof(uint32_t));
215 | self->binary_near_history[0] = binary_near_spectrum;
216 | binary_near_spectrum =
217 | self->binary_near_history[self->near_history_size - 1];
218 | }
219 |
220 | // Compare with delayed spectra and store the |bit_counts| for each delay.
221 | BitCountComparison(binary_near_spectrum, self->farend->binary_far_history,
222 | self->farend->history_size, self->bit_counts);
223 |
224 | // Update |mean_bit_counts|, which is the smoothed version of |bit_counts|.
225 | for (i = 0; i < self->farend->history_size; i++) {
226 | // |bit_counts| is constrained to [0, 32], meaning we can smooth with a
227 | // factor up to 2^26. We use Q9.
228 | int32_t bit_count = (self->bit_counts[i] << 9); // Q9.
229 |
230 | // Update |mean_bit_counts| only when far-end signal has something to
231 | // contribute. If |far_bit_counts| is zero the far-end signal is weak and
232 | // we likely have a poor echo condition, hence don't update.
233 | if (self->farend->far_bit_counts[i] > 0) {
234 | // Make number of right shifts piecewise linear w.r.t. |far_bit_counts|.
235 | int shifts = kShiftsAtZero;
236 | shifts -= (kShiftsLinearSlope * self->farend->far_bit_counts[i]) >> 4;
237 | WebRtc_MeanEstimatorFix(bit_count, shifts, &(self->mean_bit_counts[i]));
238 | }
239 | }
240 |
241 | // Find |candidate_delay|, |value_best_candidate| and |value_worst_candidate|
242 | // of |mean_bit_counts|.
243 | for (i = 0; i < self->farend->history_size; i++) {
244 | if (self->mean_bit_counts[i] < value_best_candidate) {
245 | value_best_candidate = self->mean_bit_counts[i];
246 | candidate_delay = i;
247 | }
248 | if (self->mean_bit_counts[i] > value_worst_candidate) {
249 | value_worst_candidate = self->mean_bit_counts[i];
250 | }
251 | }
252 |
253 | // The |value_best_candidate| is a good indicator on the probability of
254 | // |candidate_delay| being an accurate delay (a small |value_best_candidate|
255 | // means a good binary match). In the following sections we make a decision
256 | // whether to update |last_delay| or not.
257 | // 1) If the difference bit counts between the best and the worst delay
258 | // candidates is too small we consider the situation to be unreliable and
259 | // don't update |last_delay|.
260 | // 2) If the situation is reliable we update |last_delay| if the value of the
261 | // best candidate delay has a value less than
262 | // i) an adaptive threshold |minimum_probability|, or
263 | // ii) this corresponding value |last_delay_probability|, but updated at
264 | // this time instant.
265 |
266 | // Update |minimum_probability|.
267 | if ((self->minimum_probability > kProbabilityLowerLimit) &&
268 | (value_worst_candidate - value_best_candidate > kProbabilityMinSpread)) {
269 | // The "hard" threshold can't be lower than 17 (in Q9).
270 | // The valley in the curve also has to be distinct, i.e., the
271 | // difference between |value_worst_candidate| and |value_best_candidate| has
272 | // to be large enough.
273 | int32_t threshold = value_best_candidate + kProbabilityOffset;
274 | if (threshold < kProbabilityLowerLimit) {
275 | threshold = kProbabilityLowerLimit;
276 | }
277 | if (self->minimum_probability > threshold) {
278 | self->minimum_probability = threshold;
279 | }
280 | }
281 | // Update |last_delay_probability|.
282 | // We use a Markov type model, i.e., a slowly increasing level over time.
283 | self->last_delay_probability++;
284 | if (value_worst_candidate > value_best_candidate + kProbabilityOffset) {
285 | // Reliable delay value for usage.
286 | if (value_best_candidate < self->minimum_probability) {
287 | self->last_delay = candidate_delay;
288 | }
289 | if (value_best_candidate < self->last_delay_probability) {
290 | self->last_delay = candidate_delay;
291 | // Reset |last_delay_probability|.
292 | self->last_delay_probability = value_best_candidate;
293 | }
294 | }
295 |
296 | return self->last_delay;
297 | }
298 |
299 | int WebRtc_binary_last_delay(BinaryDelayEstimator* self) {
300 | assert(self != NULL);
301 | return self->last_delay;
302 | }
303 |
304 | int WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self) {
305 | int delay_quality = 0;
306 | assert(self != NULL);
307 | // |last_delay_probability| is the opposite of quality and states how deep the
308 | // minimum of the cost function is. The value states how many non-matching
309 | // bits we have between the binary spectra for the corresponding delay
310 | // estimate. The range is thus from 0 to 32, since we use 32 bits in the
311 | // binary spectra.
312 |
313 | // Return the |delay_quality| = 1 - |last_delay_probability| / 32 (in Q14).
314 | delay_quality = (32 << 9) - self->last_delay_probability;
315 | if (delay_quality < 0) {
316 | delay_quality = 0;
317 | }
318 | return delay_quality;
319 | }
320 |
321 | void WebRtc_MeanEstimatorFix(int32_t new_value,
322 | int factor,
323 | int32_t* mean_value) {
324 | int32_t diff = new_value - *mean_value;
325 |
326 | // mean_new = mean_value + ((new_value - mean_value) >> factor);
327 | if (diff < 0) {
328 | diff = -((-diff) >> factor);
329 | } else {
330 | diff = (diff >> factor);
331 | }
332 | *mean_value += diff;
333 | }
334 |
--------------------------------------------------------------------------------