1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-12-03 10:07:45 +01:00
libtgvoip/webrtc_dsp/common_audio/signal_processing/resample_fractional.c
Grishka 5caaaafa42 Updated WebRTC APM
I'm now using the entire audio processing module from WebRTC as opposed to individual DSP algorithms pulled from there before. Seems to work better this way.
2018-11-23 04:02:53 +03:00

240 lines
7.7 KiB
C

/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains the resampling functions between 48, 44, 32 and 24 kHz.
* The description headers can be found in signal_processing_library.h
*
*/
#include "common_audio/signal_processing/include/signal_processing_library.h"
// interpolation coefficients
static const int16_t kCoefficients48To32[2][8] = {
{778, -2050, 1087, 23285, 12903, -3783, 441, 222},
{222, 441, -3783, 12903, 23285, 1087, -2050, 778}
};
static const int16_t kCoefficients32To24[3][8] = {
{767, -2362, 2434, 24406, 10620, -3838, 721, 90},
{386, -381, -2646, 19062, 19062, -2646, -381, 386},
{90, 721, -3838, 10620, 24406, 2434, -2362, 767}
};
static const int16_t kCoefficients44To32[4][9] = {
{117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138},
{-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91},
{50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53},
{-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126}
};
// Resampling ratio: 2/3
// input: int32_t (normalized, not saturated) :: size 3 * K
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 2 * K
// K: number of blocks
void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (3 input samples -> 2 output samples);
// process in sub blocks of size 3 samples.
int32_t tmp;
size_t m;
for (m = 0; m < K; m++)
{
tmp = 1 << 14;
tmp += kCoefficients48To32[0][0] * In[0];
tmp += kCoefficients48To32[0][1] * In[1];
tmp += kCoefficients48To32[0][2] * In[2];
tmp += kCoefficients48To32[0][3] * In[3];
tmp += kCoefficients48To32[0][4] * In[4];
tmp += kCoefficients48To32[0][5] * In[5];
tmp += kCoefficients48To32[0][6] * In[6];
tmp += kCoefficients48To32[0][7] * In[7];
Out[0] = tmp;
tmp = 1 << 14;
tmp += kCoefficients48To32[1][0] * In[1];
tmp += kCoefficients48To32[1][1] * In[2];
tmp += kCoefficients48To32[1][2] * In[3];
tmp += kCoefficients48To32[1][3] * In[4];
tmp += kCoefficients48To32[1][4] * In[5];
tmp += kCoefficients48To32[1][5] * In[6];
tmp += kCoefficients48To32[1][6] * In[7];
tmp += kCoefficients48To32[1][7] * In[8];
Out[1] = tmp;
// update pointers
In += 3;
Out += 2;
}
}
// Resampling ratio: 3/4
// input: int32_t (normalized, not saturated) :: size 4 * K
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 3 * K
// K: number of blocks
void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (4 input samples -> 3 output samples);
// process in sub blocks of size 4 samples.
size_t m;
int32_t tmp;
for (m = 0; m < K; m++)
{
tmp = 1 << 14;
tmp += kCoefficients32To24[0][0] * In[0];
tmp += kCoefficients32To24[0][1] * In[1];
tmp += kCoefficients32To24[0][2] * In[2];
tmp += kCoefficients32To24[0][3] * In[3];
tmp += kCoefficients32To24[0][4] * In[4];
tmp += kCoefficients32To24[0][5] * In[5];
tmp += kCoefficients32To24[0][6] * In[6];
tmp += kCoefficients32To24[0][7] * In[7];
Out[0] = tmp;
tmp = 1 << 14;
tmp += kCoefficients32To24[1][0] * In[1];
tmp += kCoefficients32To24[1][1] * In[2];
tmp += kCoefficients32To24[1][2] * In[3];
tmp += kCoefficients32To24[1][3] * In[4];
tmp += kCoefficients32To24[1][4] * In[5];
tmp += kCoefficients32To24[1][5] * In[6];
tmp += kCoefficients32To24[1][6] * In[7];
tmp += kCoefficients32To24[1][7] * In[8];
Out[1] = tmp;
tmp = 1 << 14;
tmp += kCoefficients32To24[2][0] * In[2];
tmp += kCoefficients32To24[2][1] * In[3];
tmp += kCoefficients32To24[2][2] * In[4];
tmp += kCoefficients32To24[2][3] * In[5];
tmp += kCoefficients32To24[2][4] * In[6];
tmp += kCoefficients32To24[2][5] * In[7];
tmp += kCoefficients32To24[2][6] * In[8];
tmp += kCoefficients32To24[2][7] * In[9];
Out[2] = tmp;
// update pointers
In += 4;
Out += 3;
}
}
//
// fractional resampling filters
// Fout = 11/16 * Fin
// Fout = 8/11 * Fin
//
// compute two inner-products and store them to output array
static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2,
const int16_t *coef_ptr, int32_t *out1,
int32_t *out2)
{
int32_t tmp1 = 16384;
int32_t tmp2 = 16384;
int16_t coef;
coef = coef_ptr[0];
tmp1 += coef * in1[0];
tmp2 += coef * in2[-0];
coef = coef_ptr[1];
tmp1 += coef * in1[1];
tmp2 += coef * in2[-1];
coef = coef_ptr[2];
tmp1 += coef * in1[2];
tmp2 += coef * in2[-2];
coef = coef_ptr[3];
tmp1 += coef * in1[3];
tmp2 += coef * in2[-3];
coef = coef_ptr[4];
tmp1 += coef * in1[4];
tmp2 += coef * in2[-4];
coef = coef_ptr[5];
tmp1 += coef * in1[5];
tmp2 += coef * in2[-5];
coef = coef_ptr[6];
tmp1 += coef * in1[6];
tmp2 += coef * in2[-6];
coef = coef_ptr[7];
tmp1 += coef * in1[7];
tmp2 += coef * in2[-7];
coef = coef_ptr[8];
*out1 = tmp1 + coef * in1[8];
*out2 = tmp2 + coef * in2[-8];
}
// Resampling ratio: 8/11
// input: int32_t (normalized, not saturated) :: size 11 * K
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 8 * K
// K: number of blocks
void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (11 input samples -> 8 output samples);
// process in sub blocks of size 11 samples.
int32_t tmp;
size_t m;
for (m = 0; m < K; m++)
{
tmp = 1 << 14;
// first output sample
Out[0] = ((int32_t)In[3] << 15) + tmp;
// sum and accumulate filter coefficients and input samples
tmp += kCoefficients44To32[3][0] * In[5];
tmp += kCoefficients44To32[3][1] * In[6];
tmp += kCoefficients44To32[3][2] * In[7];
tmp += kCoefficients44To32[3][3] * In[8];
tmp += kCoefficients44To32[3][4] * In[9];
tmp += kCoefficients44To32[3][5] * In[10];
tmp += kCoefficients44To32[3][6] * In[11];
tmp += kCoefficients44To32[3][7] * In[12];
tmp += kCoefficients44To32[3][8] * In[13];
Out[4] = tmp;
// sum and accumulate filter coefficients and input samples
WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);
// update pointers
In += 11;
Out += 8;
}
}