-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathala_utility.c
100 lines (86 loc) · 2.41 KB
/
ala_utility.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "ala_utility.h"
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <float.h>
#include <assert.h>
/* NLZ計算のためのテーブル */
#define UNUSED 99
static const uint32_t nlz10_table[64] = {
32, 20, 19, UNUSED, UNUSED, 18, UNUSED, 7,
10, 17, UNUSED, UNUSED, 14, UNUSED, 6, UNUSED,
UNUSED, 9, UNUSED, 16, UNUSED, UNUSED, 1, 26,
UNUSED, 13, UNUSED, UNUSED, 24, 5, UNUSED, UNUSED,
UNUSED, 21, UNUSED, 8, 11, UNUSED, 15, UNUSED,
UNUSED, UNUSED, UNUSED, 2, 27, 0, 25, UNUSED,
22, UNUSED, 12, UNUSED, UNUSED, 3, 28, UNUSED,
23, UNUSED, 4, 29, UNUSED, UNUSED, 30, 31
};
#undef UNUSED
/* 窓の適用 */
void ALAUtility_ApplyWindow(const double* window, double* data, uint32_t num_samples)
{
uint32_t smpl;
assert(window != NULL && data != NULL);
for (smpl = 0; smpl < num_samples; smpl++) {
data[smpl] *= window[smpl];
}
}
/* サイン窓を作成 */
void ALAUtility_MakeSinWindow(double* window, uint32_t window_size)
{
uint32_t smpl;
double x;
assert(window != NULL);
/* 0除算対策 */
if (window_size == 1) {
window[0] = 1.0f;
return;
}
for (smpl = 0; smpl < window_size; smpl++) {
x = (double)smpl / (window_size - 1);
window[smpl] = sin(ALA_PI * x);
}
}
/* NLZ(最上位ビットから1に当たるまでのビット数)を計算する黒魔術 */
/* ハッカーのたのしみ参照 */
static uint32_t nlz10(uint32_t x)
{
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x & ~(x >> 16);
x = (x << 9) - x;
x = (x << 11) - x;
x = (x << 14) - x;
return nlz10_table[x >> 26];
}
/* ceil(log2(val)) を計算する */
uint32_t ALAUtility_Log2Ceil(uint32_t val)
{
assert(val != 0);
return 32U - nlz10(val - 1);
}
/* floor(log2(val)) を計算する */
uint32_t ALAUtility_Log2Floor(uint32_t val)
{
return 31U - nlz10(val);
}
/* 2の冪乗数に切り上げる ハッカーのたのしみ参照 */
uint32_t ALAUtility_RoundUp2Powered(uint32_t val)
{
val--;
val |= val >> 1;
val |= val >> 2;
val |= val >> 4;
val |= val >> 8;
val |= val >> 16;
return val + 1;
}
/* round関数(C89で定義されてないため自己定義) */
double ALAUtility_Round(double d)
{
return (d >= 0.0f) ? floor(d + 0.5f) : -floor(-d + 0.5f);
}