208 lines
5.1 KiB
C
208 lines
5.1 KiB
C
/**
|
|
* Copyright (2017) Baidu Inc. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
// Author: Su Hao (suhao@baidu.com)
|
|
//
|
|
// Description: Encode & decode the int8 into base16/32/64.
|
|
|
|
#include "lightduer_math.h"
|
|
#include "lightduer_log.h"
|
|
|
|
DUER_INT_IMPL const duer_coef_t PI = DUER_QCONST(3.141592654);
|
|
DUER_INT_IMPL const duer_coef_t PI_DOUBLE = DUER_QCONST(3.141592654 * 2);
|
|
DUER_INT_IMPL const duer_coef_t PI_HALF = DUER_QCONST(3.141592654 / 2);
|
|
|
|
#define DUER_PERCISION (12)
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_coef_sin(duer_coef_t x)
|
|
{
|
|
duer_coef_t n = x;
|
|
duer_coef_t sum = 0;
|
|
|
|
int i = 1;
|
|
|
|
// Eliminate the (2 * k * PI) as below:
|
|
// sin(x) = sin(2 * k * PI + x) {k = 0, 1, 2...}
|
|
n = (duer_coef_t)((int)(x / PI_DOUBLE));
|
|
n = x - n * PI_DOUBLE;
|
|
x = n;
|
|
|
|
do {
|
|
sum += n;
|
|
i++;
|
|
|
|
n = DUER_COEF_MUL(n, x);
|
|
n = DUER_COEF_MUL(n, x);
|
|
n *= -1;
|
|
n /= 2 * i - 1;
|
|
n /= 2 * i - 2;
|
|
} while (i < DUER_PERCISION);
|
|
|
|
return DUER_SAT(sum);
|
|
}
|
|
|
|
duer_status_t duer_conv(duer_coef_t *y, duer_size_t O, int ystart,
|
|
const duer_coef_t *x, duer_size_t N, int xstart,
|
|
const duer_coef_t *h, duer_size_t M)
|
|
{
|
|
int n, i;
|
|
|
|
DUER_LOGV("===> O: %d, N: %d, xstart: %d, M: %d", O, N, xstart, M);
|
|
for (n = ystart; n < O + ystart; n++) {
|
|
i = (n < M) ? 0 : (n - M + 1);
|
|
i = i < xstart ? xstart : i;
|
|
DUER_LOGV("\t+ n: %d, i: %d", n, i);
|
|
for (; i < n + 1 && i < N + xstart; i++) {
|
|
duer_coef_t temp = DUER_COEF_MUL(x[i - xstart], h[n - i]);
|
|
DUER_LOGV("\t| x[%d] * h[%d] = %d * %d = %d; ", i, n - i, x[i - xstart], h[n - i], temp);
|
|
y[n - ystart] += temp;
|
|
}
|
|
}
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_window_cos(int n, int N, const duer_coef_t a[], duer_size_t order)
|
|
{
|
|
duer_coef_t base = 0;
|
|
duer_size_t i = 0;
|
|
duer_coef_t rs = 0;
|
|
|
|
if (a == NULL || order == 0 || N == 1) {
|
|
return rs;
|
|
}
|
|
|
|
base = PI_DOUBLE * n / (N - 1);
|
|
|
|
rs = a[0];
|
|
i = 1;
|
|
|
|
while (i < order) {
|
|
rs += DUER_COEF_MUL(DUER_SIN(PI_HALF - i * base), a[i]);
|
|
i++;
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_window_hamming(int index, int length)
|
|
{
|
|
static const duer_coef_t coefs[] = {
|
|
DUER_QCONST(0.54),
|
|
DUER_QCONST(-0.46)
|
|
};
|
|
|
|
return duer_window_cos(index, length, coefs, 2);
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_window_hanning(int index, int length)
|
|
{
|
|
static const duer_coef_t coefs[] = {
|
|
DUER_QCONST(0.5),
|
|
DUER_QCONST(-0.5)
|
|
};
|
|
|
|
return duer_window_cos(index, length, coefs, 2);
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_window_blackman(int index, int length)
|
|
{
|
|
static const duer_coef_t coefs[] = {
|
|
DUER_QCONST(0.62),
|
|
DUER_QCONST(-0.48),
|
|
DUER_QCONST(0.38)
|
|
};
|
|
|
|
return duer_window_cos(index, length, coefs, 3);
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_window_blackman_harris(int index, int length)
|
|
{
|
|
static const duer_coef_t coefs[] = {
|
|
DUER_QCONST(0.35875),
|
|
DUER_QCONST(-0.48829),
|
|
DUER_QCONST(0.14128),
|
|
DUER_QCONST(-0.01168)
|
|
};
|
|
|
|
return duer_window_cos(index, length, coefs, 4);
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_window_blackman_nuttall(int index, int length)
|
|
{
|
|
static const duer_coef_t coefs[] = {
|
|
DUER_QCONST(0.3635819),
|
|
DUER_QCONST(-0.4891775),
|
|
DUER_QCONST(0.1365995),
|
|
DUER_QCONST(-0.0106411)
|
|
};
|
|
|
|
return duer_window_cos(index, length, coefs, 4);
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_sample_generate(int index, int freq, duer_size_t length, int fs)
|
|
{
|
|
duer_coef_t coef = DUER_QCONST(1.0f * freq * index / fs);
|
|
return DUER_SIN(DUER_COEF_MUL(PI_DOUBLE, coef));
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t duer_short2coef(short val)
|
|
{
|
|
duer_coef_t rs = 0;
|
|
|
|
#if !defined(DUER_FIXED_POINT) || (DUER_FIXED_POINT == 0)
|
|
rs = DUER_FCONST_BITS(val, 16);
|
|
#else
|
|
rs = val;
|
|
#endif
|
|
|
|
return rs;
|
|
}
|
|
|
|
DUER_INT_IMPL short duer_coef2short(duer_coef_t val)
|
|
{
|
|
short rs = 0;
|
|
|
|
#if !defined(DUER_FIXED_POINT) || (DUER_FIXED_POINT == 0)
|
|
rs = DUER_QCONST_BITS(val, 16);
|
|
#else
|
|
rs = val;
|
|
#endif
|
|
|
|
return rs;
|
|
}
|
|
|
|
DUER_INT_IMPL duer_coef_t *duer_short2coef_array(duer_coef_t dst[], const short src[], duer_size_t length)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < length; i++) {
|
|
dst[i] = duer_short2coef(src[i]);
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
DUER_INT_IMPL short *duer_coef2short_array(short dst[], const duer_coef_t src[], duer_size_t length)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < length; i++) {
|
|
dst[i] = duer_coef2short(src[i]);
|
|
}
|
|
|
|
return dst;
|
|
}
|