KT24-1110_65E-HA-651B/apps/common/audio/sine_make.c

325 lines
13 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
/*****************************************************************
>file name : apps/common/sine_make.c
>author : lichao
>create time : Sun 05 May 2019 08:37:35 PM CST
*****************************************************************/
#include "system/includes.h"
#include "sine_make.h"
#define SINE_USE_MALLOC 1
struct audio_sin_maker {
u8 open;
u8 id;
u8 sin_num;
u8 channel;
u8 repeat;
u8 next_param;
u16 fade_points;
/*int sample_rate;*/
int volume;
int points;
int sin_index;
int win_sin_index;
const struct sin_param *sin;
};
#ifndef SINE_USE_MALLOC
static struct audio_sin_maker sin_maker_handle;
#endif
void *sin_tone_open(const struct sin_param *param, int num, u8 channel, u8 repeat)
{
if (!param || !num) {
return NULL;
}
#ifdef SINE_USE_MALLOC
struct audio_sin_maker *sin = zalloc(sizeof(struct audio_sin_maker));
#else
struct audio_sin_maker *sin = &sin_maker_handle;
#endif
if (!sin) {
return NULL;
}
if (sin->open) {
return NULL;
}
sin->sin = param;
sin->sin_num = num;
sin->open = 1;
sin->points = param[0].points;
sin->id = 0;
sin->channel = channel;
sin->repeat = repeat;
#if (defined CONFIG_CPU_BR18 || \
CONFIG_CPU_BR21)
/*这里如果加多fade points会导致结束的时候有噪声,不是在淡出尾部*/
sin->fade_points = 0;
#else
sin->fade_points = 480;
#endif
sin->next_param = 1;
return (void *)sin;
}
#if !defined(SINE_MAKE_IN_MASK)
const int sf_sin_tab1[513] = {
0x00000000, 0x0000c910, 0x0001921f, 0x00025b2d, 0x0003243a, 0x0003ed45, 0x0004b64e, 0x00057f53,
0x00064855, 0x00071154, 0x0007da4e, 0x0008a343, 0x00096c33, 0x000a351d, 0x000afe00, 0x000bc6dd,
0x000c8fb3, 0x000d5881, 0x000e2147, 0x000eea03, 0x000fb2b7, 0x00107b61, 0x00114401, 0x00120c96,
0x0012d521, 0x00139d9f, 0x00146611, 0x00152e77, 0x0015f6d0, 0x0016bf1b, 0x00178758, 0x00184f87,
0x001917a7, 0x0019dfb7, 0x001aa7b7, 0x001b6fa7, 0x001c3786, 0x001cff53, 0x001dc70f, 0x001e8eb8,
0x001f564e, 0x00201dd1, 0x0020e541, 0x0021ac9b, 0x002273e2, 0x00233b13, 0x0024022e, 0x0024c933,
0x00259021, 0x002656f8, 0x00271db7, 0x0027e45f, 0x0028aaed, 0x00297163, 0x002a37bf, 0x002afe01,
0x002bc429, 0x002c8a35, 0x002d5026, 0x002e15fb, 0x002edbb4, 0x002fa14f, 0x003066ce, 0x00312c2e,
0x0031f170, 0x0032b694, 0x00337b98, 0x0034407c, 0x00350540, 0x0035c9e4, 0x00368e66, 0x003752c6,
0x00381705, 0x0038db21, 0x00399f19, 0x003a62ef, 0x003b26a0, 0x003bea2c, 0x003cad94, 0x003d70d7,
0x003e33f3, 0x003ef6e9, 0x003fb9b8, 0x00407c60, 0x00413ee0, 0x00420138, 0x0042c367, 0x0043856d,
0x0044474a, 0x004508fc, 0x0045ca83, 0x00468be0, 0x00474d11, 0x00480e16, 0x0048ceef, 0x00498f9a,
0x004a5019, 0x004b1069, 0x004bd08b, 0x004c907f, 0x004d5043, 0x004e0fd8, 0x004ecf3c, 0x004f8e70,
0x00504d72, 0x00510c43, 0x0051cae3, 0x0052894f, 0x00534789, 0x0054058f, 0x0054c362, 0x00558100,
0x00563e6a, 0x0056fb9e, 0x0057b89d, 0x00587565, 0x005931f7, 0x0059ee52, 0x005aaa76, 0x005b6662,
0x005c2215, 0x005cdd8f, 0x005d98d0, 0x005e53d8, 0x005f0ea5, 0x005fc937, 0x0060838f, 0x00613dab,
0x0061f78b, 0x0062b12e, 0x00636a95, 0x006423be, 0x0064dcaa, 0x00659557, 0x00664dc6, 0x006705f5,
0x0067bde5, 0x00687595, 0x00692d05, 0x0069e433, 0x006a9b21, 0x006b51cc, 0x006c0836, 0x006cbe5c,
0x006d7440, 0x006e29e0, 0x006edf3d, 0x006f9454, 0x00704927, 0x0070fdb5, 0x0071b1fd, 0x007265ff,
0x007319ba, 0x0073cd2f, 0x0074805c, 0x00753341, 0x0075e5dd, 0x00769831, 0x00774a3c, 0x0077fbfe,
0x0078ad75, 0x00795ea2, 0x007a0f84, 0x007ac01a, 0x007b7065, 0x007c2064, 0x007cd016, 0x007d7f7c,
0x007e2e93, 0x007edd5d, 0x007f8bd9, 0x00803a06, 0x0080e7e4, 0x00819573, 0x008242b1, 0x0082ef9f,
0x00839c3d, 0x00844889, 0x0084f484, 0x0085a02c, 0x00864b82, 0x0086f686, 0x0087a136, 0x00884b92,
0x0088f59b, 0x00899f4e, 0x008a48ad, 0x008af1b7, 0x008b9a6b, 0x008c42c9, 0x008cead0, 0x008d9281,
0x008e39da, 0x008ee0db, 0x008f8784, 0x00902dd5, 0x0090d3cd, 0x0091796b, 0x00921eb0, 0x0092c39a,
0x0093682a, 0x00940c5f, 0x0094b039, 0x009553b7, 0x0095f6d9, 0x0096999f, 0x00973c07, 0x0097de12,
0x00987fc0, 0x0099210f, 0x0099c200, 0x009a6293, 0x009b02c6, 0x009ba299, 0x009c420c, 0x009ce11f,
0x009d7fd1, 0x009e1e22, 0x009ebc12, 0x009f599f, 0x009ff6cb, 0x00a09393, 0x00a12ff9, 0x00a1cbfb,
0x00a26799, 0x00a302d3, 0x00a39da9, 0x00a4381a, 0x00a4d225, 0x00a56bcb, 0x00a6050a, 0x00a69de3,
0x00a73656, 0x00a7ce61, 0x00a86605, 0x00a8fd41, 0x00a99415, 0x00aa2a80, 0x00aac082, 0x00ab561b,
0x00abeb4a, 0x00ac800f, 0x00ad1469, 0x00ada859, 0x00ae3bde, 0x00aecef7, 0x00af61a5, 0x00aff3e6,
0x00b085bb, 0x00b11722, 0x00b1a81d, 0x00b238aa, 0x00b2c8c9, 0x00b3587a, 0x00b3e7bc, 0x00b4768f,
0x00b504f3, 0x00b592e7, 0x00b6206c, 0x00b6ad7f, 0x00b73a23, 0x00b7c655, 0x00b85216, 0x00b8dd65,
0x00b96842, 0x00b9f2ac, 0x00ba7ca4, 0x00bb0629, 0x00bb8f3b, 0x00bc17d9, 0x00bca003, 0x00bd27b8,
0x00bdaef9, 0x00be35c5, 0x00bebc1b, 0x00bf41fc, 0x00bfc767, 0x00c04c5c, 0x00c0d0da, 0x00c154e1,
0x00c1d870, 0x00c25b89, 0x00c2de29, 0x00c36051, 0x00c3e200, 0x00c46337, 0x00c4e3f5, 0x00c56439,
0x00c5e403, 0x00c66354, 0x00c6e22a, 0x00c76085, 0x00c7de65, 0x00c85bca, 0x00c8d8b3, 0x00c95521,
0x00c9d112, 0x00ca4c87, 0x00cac77f, 0x00cb41fa, 0x00cbbbf8, 0x00cc3578, 0x00ccae79, 0x00cd26fd,
0x00cd9f02, 0x00ce1689, 0x00ce8d90, 0x00cf0417, 0x00cf7a1f, 0x00cfefa8, 0x00d064af, 0x00d0d937,
0x00d14d3d, 0x00d1c0c2, 0x00d233c6, 0x00d2a649, 0x00d31849, 0x00d389c7, 0x00d3fac3, 0x00d46b3b,
0x00d4db31, 0x00d54aa4, 0x00d5b993, 0x00d627fe, 0x00d695e5, 0x00d70348, 0x00d77026, 0x00d7dc7f,
0x00d84853, 0x00d8b3a1, 0x00d91e6a, 0x00d988ad, 0x00d9f26a, 0x00da5ba0, 0x00dac450, 0x00db2c79,
0x00db941a, 0x00dbfb34, 0x00dc61c7, 0x00dcc7d1, 0x00dd2d53, 0x00dd924d, 0x00ddf6be, 0x00de5aa6,
0x00debe05, 0x00df20db, 0x00df8327, 0x00dfe4e9, 0x00e04621, 0x00e0a6cf, 0x00e106f2, 0x00e1668a,
0x00e1c598, 0x00e2241a, 0x00e28210, 0x00e2df7b, 0x00e33c5a, 0x00e398ac, 0x00e3f473, 0x00e44fac,
0x00e4aa59, 0x00e50479, 0x00e55e0b, 0x00e5b710, 0x00e60f88, 0x00e66771, 0x00e6becc, 0x00e71599,
0x00e76bd8, 0x00e7c187, 0x00e816a8, 0x00e86b39, 0x00e8bf3c, 0x00e912ae, 0x00e96591, 0x00e9b7e4,
0x00ea09a7, 0x00ea5ad9, 0x00eaab7b, 0x00eafb8c, 0x00eb4b0c, 0x00eb99fb, 0x00ebe858, 0x00ec3624,
0x00ec835e, 0x00ecd007, 0x00ed1c1d, 0x00ed67a1, 0x00edb293, 0x00edfcf2, 0x00ee46be, 0x00ee8ff8,
0x00eed89e, 0x00ef20b0, 0x00ef6830, 0x00efaf1b, 0x00eff573, 0x00f03b37, 0x00f08066, 0x00f0c501,
0x00f10908, 0x00f14c7a, 0x00f18f57, 0x00f1d19f, 0x00f21352, 0x00f25470, 0x00f294f8, 0x00f2d4eb,
0x00f31447, 0x00f3530e, 0x00f3913f, 0x00f3ced9, 0x00f40bdd, 0x00f4484b, 0x00f48422, 0x00f4bf62,
0x00f4fa0b, 0x00f5341d, 0x00f56d97, 0x00f5a67b, 0x00f5dec6, 0x00f6167a, 0x00f64d97, 0x00f6841b,
0x00f6ba07, 0x00f6ef5b, 0x00f72417, 0x00f7583a, 0x00f78bc5, 0x00f7beb7, 0x00f7f110, 0x00f822d1,
0x00f853f8, 0x00f88486, 0x00f8b47b, 0x00f8e3d6, 0x00f91298, 0x00f940c0, 0x00f96e4e, 0x00f99b43,
0x00f9c79d, 0x00f9f35e, 0x00fa1e84, 0x00fa4910, 0x00fa7302, 0x00fa9c59, 0x00fac516, 0x00faed37,
0x00fb14be, 0x00fb3bab, 0x00fb61fc, 0x00fb87b2, 0x00fbaccd, 0x00fbd14d, 0x00fbf531, 0x00fc187a,
0x00fc3b28, 0x00fc5d3a, 0x00fc7eb0, 0x00fc9f8a, 0x00fcbfc9, 0x00fcdf6c, 0x00fcfe73, 0x00fd1cdd,
0x00fd3aac, 0x00fd57de, 0x00fd7474, 0x00fd906e, 0x00fdabcc, 0x00fdc68c, 0x00fde0b1, 0x00fdfa38,
0x00fe1324, 0x00fe2b72, 0x00fe4323, 0x00fe5a38, 0x00fe70b0, 0x00fe868b, 0x00fe9bc9, 0x00feb069,
0x00fec46d, 0x00fed7d4, 0x00feea9d, 0x00fefcc9, 0x00ff0e58, 0x00ff1f49, 0x00ff2f9d, 0x00ff3f54,
0x00ff4e6d, 0x00ff5ce9, 0x00ff6ac7, 0x00ff7808, 0x00ff84ab, 0x00ff90b1, 0x00ff9c18, 0x00ffa6e3,
0x00ffb10f, 0x00ffba9e, 0x00ffc38f, 0x00ffcbe2, 0x00ffd397, 0x00ffdaaf, 0x00ffe129, 0x00ffe705,
0x00ffec43, 0x00fff0e3, 0x00fff4e6, 0x00fff84a, 0x00fffb11, 0x00fffd39, 0x00fffec4, 0x00ffffb1,
0x00ffffff,
};
#else
extern const int sf_sin_tab1[513] ;
#endif
#define SINE_INT_ZOOM 16384
#define SINE_INT_ZBIT 14
#define __int64 long long
/*软件索引实现sin生成*/
static int get_sine_value(int mx_idx)
{
int ret = 0;
int idx = 0;
int tm_idx = mx_idx & 0x1FFFFFF; //2^25
int phase = tm_idx & 0x3FFF;
int tp_idx0 = tm_idx >> 14;
int tp_idx1 = tp_idx0 + 1;
int sign = 1, dt0, dt1;
if (tp_idx0 > 1024) {
sign = -1;
tp_idx0 = 2048 - tp_idx0;
}
if (tp_idx0 < 513) {
dt0 = sf_sin_tab1[tp_idx0];
} else {
dt0 = sf_sin_tab1[1024 - tp_idx0];
}
if (tp_idx1 > 1024) {
sign = -1;
tp_idx1 = 2048 - tp_idx1;
}
if (tp_idx1 < 513) {
dt1 = sf_sin_tab1[tp_idx1];
} else {
dt1 = sf_sin_tab1[1024 - tp_idx1];
}
ret = ((__int64)dt0 * (SINE_INT_ZOOM - phase) + (__int64)dt1 * phase) >> SINE_INT_ZBIT;
ret *= sign;
return ret;
}
static void hw_sin_value(int a, int *sin_res, u8 precision)
{
u64 s64 = a;
*sin_res = __asm_sine(s64, precision);
}
int sin_tone_make(void *_maker, void *data, int len)
{
struct audio_sin_maker *maker = (struct audio_sin_maker *)_maker;
s16 *pcm = (s16 *)data;
int sin_value = 0;
int win_sin_value = 0;
int add_idx = 0, sub_vol = 0, win_add_idx = 0;
int offset = 0;
u8 id = maker->id;
u8 sin_num = maker->sin_num;
u8 repeat = maker->repeat;
u8 channel = maker->channel;
int sin_index;
int win_sin_index;
int volume;
u32 reamin_points = len / 2 / channel;
do {
if (maker->next_param) {
maker->volume = SINE_TOTAL_VOLUME;
maker->sin_index = 0;
maker->win_sin_index = 0;
maker->next_param = 0;
}
u8 win = maker->sin[id].win;
add_idx = ((u64)(1 << 25) * maker->sin[id].freq / DEFAULT_SINE_SAMPLE_RATE) >> 9;
if (win) {
win_add_idx = ((u64)(1 << 25) * maker->sin[id].decay / DEFAULT_SINE_SAMPLE_RATE) >> 9;
/*sub_vol = 0;*/
} else {
sub_vol = maker->sin[id].decay;
}
sin_index = maker->sin_index;
win_sin_index = maker->win_sin_index;
volume = maker->volume;
u32 points = 0;
if (maker->fade_points) {
points = maker->fade_points > reamin_points ? reamin_points : maker->fade_points;
sub_vol = 0;
maker->fade_points -= points;
} else {
points = maker->points > reamin_points ? reamin_points : maker->points;
maker->points -= points;
}
reamin_points -= points;
while (points--) {
/*hw_sin_value(sin_index, &sin_value, 0);*/
sin_value = __asm_sine((s64)sin_index, 2);
if (win) {
/*hw_sin_value(win_sin_index, &win_sin_value, 0);*/
win_sin_value = __asm_sine((s64)win_sin_index, 2);
#ifdef CONFIG_CPU_BR36
sin_value = ((s64)sin_value * (s64)win_sin_value) >> 44;
#else
sin_value = ((s64)sin_value * (s64)win_sin_value) >> 34;
#endif
win_sin_index += win_add_idx;
win_sin_index &= 0x1ffffff;
} else {
#ifdef CONFIG_CPU_BR36
sin_value = ((s64)volume * sin_value) >> 39;
#else
sin_value = ((s64)volume * sin_value) >> 34;
#endif
}
sin_index += add_idx;
sin_index &= 0x1ffffff;
volume -= sub_vol;
if (volume < 0) {
volume = 0;
}
*pcm++ = sin_value;
if (channel == 2) {
*pcm++ = sin_value;
} else if (channel == 4) {
*pcm++ = sin_value;
*pcm++ = sin_value;
*pcm++ = sin_value;
}
}
maker->volume = volume;
maker->sin_index = sin_index;
maker->win_sin_index = win_sin_index;
if (!maker->points) {
if (++id >= sin_num) {
if (!repeat) {
break;
}
id = 0;
}
maker->points = maker->sin[id].points;
maker->id = id;
maker->next_param = 1;
}
if (!reamin_points) {
break;
}
} while (1);
return len - (reamin_points * 2 * channel);
}
int sin_tone_points(void *_maker)
{
struct audio_sin_maker *maker = (struct audio_sin_maker *)_maker;
int points = 0;
u8 i = 0;
for (i = 0; i < maker->sin_num; i++) {
points += maker->sin[i].points;
}
return points;
}
void sin_tone_close(void *_maker)
{
struct audio_sin_maker *maker = (struct audio_sin_maker *)_maker;
#ifdef SINE_USE_MALLOC
if (maker) {
free(maker);
}
#else
if (sin_maker_handle.open) {
sin_maker_handle.open = 0;
}
#endif
}